| // Copyright (c) 2017 The Chromium Authors. All rights reserved. |
| // 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_RTC_EVENT_LOG_MANAGER_COMMON_H_ |
| #define CONTENT_BROWSER_WEBRTC_WEBRTC_RTC_EVENT_LOG_MANAGER_COMMON_H_ |
| |
| #include <map> |
| #include <string> |
| #include <tuple> |
| |
| #include "base/files/file.h" |
| #include "base/files/file_path.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "content/common/content_export.h" |
| |
| // This file is intended for: |
| // 1. Code shared between WebRtcEventLogManager, WebRtcLocalEventLogManager |
| // and WebRtcRemoteEventLogManager. |
| // 2. Code specific to either of the above classes, but which also needs |
| // to be seen by unit tests (such as constants). |
| |
| namespace content { |
| |
| CONTENT_EXPORT extern const size_t kWebRtcEventLogManagerUnlimitedFileSize; |
| |
| CONTENT_EXPORT extern const size_t kDefaultMaxLocalLogFileSizeBytes; |
| CONTENT_EXPORT extern const size_t kMaxNumberLocalWebRtcEventLogFiles; |
| |
| // Limit over the number of concurrently active (currently being written to |
| // disk) remote-bound log files. This limits IO operations, and so it is |
| // applied globally (all browser contexts are limited together). |
| CONTENT_EXPORT extern const size_t kMaxActiveRemoteBoundWebRtcEventLogs; |
| |
| // Limit over the number of pending logs (logs stored on disk and awaiting to |
| // be uploaded to a remote server). This limit avoids excessive storage. If a |
| // user chooses to have multiple profiles (and hence browser contexts) on a |
| // system, it is assumed that the user has enough storage to accommodate |
| // the increased storage consumption that comes with it. Therefore, this |
| // limit is applied per browser context. |
| CONTENT_EXPORT extern const size_t kMaxPendingRemoteBoundWebRtcEventLogs; |
| |
| // The file extension to be associated with remote-bound logs while they are |
| // kept on local disk. |
| CONTENT_EXPORT extern const base::FilePath::CharType kRemoteBoundLogExtension[]; |
| |
| // Version of the remote-bound log. Refers to the version of the event logs' |
| // encoding, method for separation of metadata from the WebRTC event log, etc. |
| CONTENT_EXPORT extern const uint8_t kRemoteBoundWebRtcEventLogFileVersion; |
| |
| // Remote-bound log headers are composed of: |
| // * One byte for the version (for the encoding, metadata format, etc.) |
| // * Three bytes encoding the length of the metadata, in bytes. |
| // The metadata, which immediately follows the header, is not counted as part |
| // of the header size. |
| CONTENT_EXPORT extern const size_t kRemoteBoundLogFileHeaderSizeBytes; |
| |
| // Remote-bound event logs will not be uploaded if the time since their last |
| // modification (meaning the time when they were completed) exceeds this value. |
| // Such expired files will be purged from disk when examined. |
| CONTENT_EXPORT extern const base::TimeDelta |
| kRemoteBoundWebRtcEventLogsMaxRetention; |
| |
| // For a given Chrome session, this is a unique key for PeerConnections. |
| // It's not, however, unique between sessions (after Chrome is restarted). |
| struct WebRtcEventLogPeerConnectionKey { |
| using BrowserContextId = uintptr_t; |
| |
| constexpr WebRtcEventLogPeerConnectionKey(int render_process_id, |
| int lid, |
| BrowserContextId browser_context_id) |
| : render_process_id(render_process_id), |
| lid(lid), |
| browser_context_id(browser_context_id) {} |
| |
| bool operator==(const WebRtcEventLogPeerConnectionKey& other) const { |
| // Each RPH is associated with exactly one BrowserContext. |
| DCHECK(render_process_id != other.render_process_id || |
| browser_context_id == other.browser_context_id); |
| |
| const bool equal = std::tie(render_process_id, lid) == |
| std::tie(other.render_process_id, other.lid); |
| return equal; |
| } |
| |
| bool operator<(const WebRtcEventLogPeerConnectionKey& other) const { |
| // Each RPH is associated with exactly one BrowserContext. |
| DCHECK(render_process_id != other.render_process_id || |
| browser_context_id == other.browser_context_id); |
| |
| return std::tie(render_process_id, lid) < |
| std::tie(other.render_process_id, other.lid); |
| } |
| |
| // These two fields are the actual key; any peer connection is uniquely |
| // identifiable by the renderer process in which it lives, and its ID within |
| // that process. |
| int render_process_id; |
| int lid; // Renderer-local PeerConnection ID. |
| |
| // The BrowserContext is not actually part of the key, but each PeerConnection |
| // is associated with a BrowserContext, and that BrowserContext is almost |
| // always necessary, so it makes sense to remember it along with the key. |
| BrowserContextId browser_context_id; |
| }; |
| |
| // An observer for notifications of local log files being started/stopped, and |
| // the paths which will be used for these logs. |
| class WebRtcLocalEventLogsObserver { |
| public: |
| virtual void OnLocalLogStarted(WebRtcEventLogPeerConnectionKey key, |
| const base::FilePath& file_path) = 0; |
| virtual void OnLocalLogStopped(WebRtcEventLogPeerConnectionKey key) = 0; |
| |
| protected: |
| virtual ~WebRtcLocalEventLogsObserver() = default; |
| }; |
| |
| // An observer for notifications of remote-bound log files being |
| // started/stopped. The start event would likely only interest unit tests |
| // (because it exposes the randomized filename to them). The stop event is of |
| // general interest, because it would often mean that WebRTC can stop sending |
| // us event logs for this peer connection. |
| // Some cases where OnRemoteLogStopped would be called include: |
| // 1. The PeerConnection has become inactive. |
| // 2. The file's maximum size has been reached. |
| // 3. Any type of error while writing to the file. |
| class WebRtcRemoteEventLogsObserver { |
| public: |
| virtual void OnRemoteLogStarted(WebRtcEventLogPeerConnectionKey key, |
| const base::FilePath& file_path) = 0; |
| virtual void OnRemoteLogStopped(WebRtcEventLogPeerConnectionKey key) = 0; |
| |
| protected: |
| virtual ~WebRtcRemoteEventLogsObserver() = default; |
| }; |
| |
| struct LogFile { |
| LogFile(const base::FilePath& path, |
| base::File file, |
| size_t max_file_size_bytes, |
| size_t file_size_bytes = 0) |
| : path(path), |
| file(std::move(file)), |
| max_file_size_bytes(max_file_size_bytes), |
| file_size_bytes(file_size_bytes) {} |
| const base::FilePath path; |
| base::File file; |
| const size_t max_file_size_bytes; |
| size_t file_size_bytes; |
| }; |
| |
| // WebRtcLocalEventLogManager and WebRtcRemoteEventLogManager share some logic |
| // when it comes to handling of files on disk. |
| class LogFileWriter { |
| protected: |
| using PeerConnectionKey = WebRtcEventLogPeerConnectionKey; |
| using BrowserContextId = PeerConnectionKey::BrowserContextId; |
| using LogFilesMap = std::map<PeerConnectionKey, LogFile>; |
| |
| virtual ~LogFileWriter() = default; |
| |
| // Given a peer connection and its associated log file, and given a log |
| // fragment that should be written to the log file, attempt to write to |
| // the log file (return value indicates success/failure). |
| // If an error occurs, or if the file reaches its capacity, CloseLogFile() |
| // will be called, closing the file. |
| bool WriteToLogFile(LogFilesMap::iterator it, const std::string& message); |
| |
| // Called when WriteToLogFile() either encounters an error, or if the file's |
| // intended capacity is reached. It indicates to the inheriting class that |
| // the file should also be purged from its set of active log files. |
| // The function should return an iterator to the next element in the set |
| // of active logs. This makes the function more useful, allowing it to be |
| // used when iterating and closing several log files. |
| virtual LogFilesMap::iterator CloseLogFile(LogFilesMap::iterator it) = 0; |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_WEBRTC_WEBRTC_RTC_EVENT_LOG_MANAGER_COMMON_H_ |