Commit ab4cc6d7 authored by Xiangjun Zhang's avatar Xiangjun Zhang Committed by Commit Bot

Mirroring service: Add SessionMonitor.

This CL adds the SessionMonitor that collects WiFi status reported by
receiver, extra tags, and Cast Streaming raw events/stats for an active
mirroring session. The data is assembled and re-packaged as requested
to be included in user feedback report uploads.

Bug: 734672
Change-Id: If3644cb345c3cbe8c1cfbd5474432667f426944a
Reviewed-on: https://chromium-review.googlesource.com/1055789Reviewed-by: default avatarHelen Li <xunjieli@chromium.org>
Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Commit-Queue: Xiangjun Zhang <xjz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#560662}
parent fe5a2b3a
...@@ -35,6 +35,8 @@ source_set("service") { ...@@ -35,6 +35,8 @@ source_set("service") {
"rtp_stream.h", "rtp_stream.h",
"session.cc", "session.cc",
"session.h", "session.h",
"session_monitor.cc",
"session_monitor.h",
"udp_socket_client.cc", "udp_socket_client.cc",
"udp_socket_client.h", "udp_socket_client.h",
"value_util.cc", "value_util.cc",
...@@ -51,6 +53,7 @@ source_set("service") { ...@@ -51,6 +53,7 @@ source_set("service") {
deps = [ deps = [
":interface", ":interface",
"//components/version_info",
"//crypto", "//crypto",
"//media", "//media",
"//media/capture:capture_base", "//media/capture:capture_base",
...@@ -62,6 +65,7 @@ source_set("service") { ...@@ -62,6 +65,7 @@ source_set("service") {
"//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings",
"//mojo/public/cpp/system", "//mojo/public/cpp/system",
"//net", "//net",
"//services/network/public/cpp",
"//services/network/public/mojom", "//services/network/public/mojom",
"//ui/gfx", "//ui/gfx",
] ]
...@@ -77,6 +81,7 @@ source_set("unittests") { ...@@ -77,6 +81,7 @@ source_set("unittests") {
"message_dispatcher_unittest.cc", "message_dispatcher_unittest.cc",
"receiver_response_unittest.cc", "receiver_response_unittest.cc",
"rtp_stream_unittest.cc", "rtp_stream_unittest.cc",
"session_monitor_unittest.cc",
"session_unittest.cc", "session_unittest.cc",
"udp_socket_client_unittest.cc", "udp_socket_client_unittest.cc",
"video_capture_client_unittest.cc", "video_capture_client_unittest.cc",
...@@ -98,6 +103,7 @@ source_set("unittests") { ...@@ -98,6 +103,7 @@ source_set("unittests") {
"//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings",
"//net", "//net",
"//services/network:test_support", "//services/network:test_support",
"//services/network/public/cpp",
"//services/network/public/mojom", "//services/network/public/mojom",
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
......
include_rules = [ include_rules = [
"-components",
"+components/mirroring/service",
"+components/version_info",
"+crypto", "+crypto",
"+net", "+net",
"+services/network/public/mojom", "+services/network/public",
"+services/network/test", "+services/network/test",
] ]
...@@ -118,4 +118,31 @@ media::VideoCaptureParams MirrorSettings::GetVideoCaptureParams() { ...@@ -118,4 +118,31 @@ media::VideoCaptureParams MirrorSettings::GetVideoCaptureParams() {
return params; return params;
} }
base::Value MirrorSettings::ToDictionaryValue() {
base::Value settings(base::Value::Type::DICTIONARY);
settings.SetKey("maxWidth", base::Value(max_width_));
settings.SetKey("maxHeight", base::Value(max_height_));
settings.SetKey("minWidth", base::Value(min_width_));
settings.SetKey("minHeight", base::Value(min_height_));
settings.SetKey("senderSideLetterboxing", base::Value(true));
settings.SetKey("minFrameRate", base::Value(0));
settings.SetKey("maxFrameRate", base::Value(kMaxFrameRate));
settings.SetKey("minVideoBitrate", base::Value(kMinVideoBitrate));
settings.SetKey("maxVideoBitrate", base::Value(kMaxVideoBitrate));
settings.SetKey("audioBitrate", base::Value(kAudioBitrate));
settings.SetKey(
"maxLatencyMillis",
base::Value(static_cast<int32_t>(kMaxPlayoutDelay.InMilliseconds())));
settings.SetKey(
"minLatencyMillis",
base::Value(static_cast<int32_t>(kMinPlayoutDelay.InMilliseconds())));
settings.SetKey("animatedLatencyMillis",
base::Value(static_cast<int32_t>(
kAnimatedPlayoutDelay.InMilliseconds())));
settings.SetKey("dscpEnabled", base::Value(false));
settings.SetKey("enableLogging", base::Value(true));
settings.SetKey("useTdls", base::Value(false));
return settings;
}
} // namespace mirroring } // namespace mirroring
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define COMPONENTS_MIRRORING_SERVICE_MIRROR_SETTINGS_H_ #define COMPONENTS_MIRRORING_SERVICE_MIRROR_SETTINGS_H_
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h"
#include "media/capture/video_capture_types.h" #include "media/capture/video_capture_types.h"
#include "media/cast/cast_config.h" #include "media/cast/cast_config.h"
...@@ -39,6 +40,9 @@ class MirrorSettings { ...@@ -39,6 +40,9 @@ class MirrorSettings {
int max_width() const { return max_width_; } int max_width() const { return max_width_; }
int max_height() const { return max_height_; } int max_height() const { return max_height_; }
// Returns a dictionary value of the current settings.
base::Value ToDictionaryValue();
private: private:
const int min_width_; const int min_width_;
const int min_height_; const int min_height_;
......
...@@ -58,6 +58,13 @@ constexpr int kAudioSsrcMax = 5e5; ...@@ -58,6 +58,13 @@ constexpr int kAudioSsrcMax = 5e5;
constexpr int kVideoSsrcMin = 5e5 + 1; constexpr int kVideoSsrcMin = 5e5 + 1;
constexpr int kVideoSsrcMax = 10e5; constexpr int kVideoSsrcMax = 10e5;
// Maximum number of bytes of file data allowed in a single Crash report. As of
// this writing, the total report upload size is capped at 20 MB.
//
// 2 KB of "overhead bytes" are subtracted to account for all of the non-file
// data in a report upload, including HTTP headers/requests and form data.
constexpr int kMaxCrashReportBytes = (20 * 1024 - 2) * 1024;
class TransportClient final : public media::cast::CastTransport::Client { class TransportClient final : public media::cast::CastTransport::Client {
public: public:
explicit TransportClient(Session* session) : session_(session) {} explicit TransportClient(Session* session) : session_(session) {}
...@@ -225,6 +232,28 @@ Session::Session(int32_t session_id, ...@@ -225,6 +232,28 @@ Session::Session(int32_t session_id,
DCHECK(resource_provider_); DCHECK(resource_provider_);
mirror_settings_.SetResolutionContraints(max_resolution.width(), mirror_settings_.SetResolutionContraints(max_resolution.width(),
max_resolution.height()); max_resolution.height());
resource_provider_->GetNetworkContext(mojo::MakeRequest(&network_context_));
auto wifi_status_monitor =
std::make_unique<WifiStatusMonitor>(session_id_, &message_dispatcher_);
network::mojom::URLLoaderFactoryPtr url_loader_factory;
network_context_->CreateURLLoaderFactory(
mojo::MakeRequest(&url_loader_factory), 0 /* process_id */);
// Generate session level tags.
base::Value session_tags(base::Value::Type::DICTIONARY);
session_tags.SetKey("mirrorSettings", mirror_settings_.ToDictionaryValue());
session_tags.SetKey("shouldCaptureAudio",
base::Value(sink_info_.capability != VIDEO_ONLY));
session_tags.SetKey("shouldCaptureVideo",
base::Value(sink_info_.capability != AUDIO_ONLY));
session_tags.SetKey("receiverProductName",
base::Value(sink_info_.model_name));
session_monitor_.emplace(
kMaxCrashReportBytes, sink_info_.ip_address, std::move(session_tags),
std::move(url_loader_factory), std::move(wifi_status_monitor));
CreateAndSendOffer(); CreateAndSendOffer();
} }
...@@ -233,7 +262,8 @@ Session::~Session() { ...@@ -233,7 +262,8 @@ Session::~Session() {
} }
void Session::ReportError(SessionError error) { void Session::ReportError(SessionError error) {
DVLOG(1) << __func__ << ": error=" << error; if (session_monitor_.has_value())
session_monitor_->OnStreamingError(error);
if (observer_) if (observer_)
observer_->OnError(error); observer_->OnError(error);
StopSession(); StopSession();
...@@ -244,6 +274,8 @@ void Session::StopSession() { ...@@ -244,6 +274,8 @@ void Session::StopSession() {
if (!resource_provider_) if (!resource_provider_)
return; return;
session_monitor_->StopStreamingSession();
session_monitor_.reset();
weak_factory_.InvalidateWeakPtrs(); weak_factory_.InvalidateWeakPtrs();
audio_encode_thread_ = nullptr; audio_encode_thread_ = nullptr;
video_encode_thread_ = nullptr; video_encode_thread_ = nullptr;
...@@ -260,7 +292,6 @@ void Session::StopSession() { ...@@ -260,7 +292,6 @@ void Session::StopSession() {
} }
void Session::OnError(const std::string& message) { void Session::OnError(const std::string& message) {
VLOG(1) << message;
ReportError(SessionError::RTP_STREAM_ERROR); ReportError(SessionError::RTP_STREAM_ERROR);
} }
...@@ -283,7 +314,6 @@ void Session::OnEncoderStatusChange(OperationalStatus status) { ...@@ -283,7 +314,6 @@ void Session::OnEncoderStatusChange(OperationalStatus status) {
case OperationalStatus::STATUS_UNSUPPORTED_CODEC: case OperationalStatus::STATUS_UNSUPPORTED_CODEC:
case OperationalStatus::STATUS_CODEC_INIT_FAILED: case OperationalStatus::STATUS_CODEC_INIT_FAILED:
case OperationalStatus::STATUS_CODEC_RUNTIME_ERROR: case OperationalStatus::STATUS_CODEC_RUNTIME_ERROR:
DVLOG(1) << "OperationalStatus error.";
ReportError(SessionError::ENCODING_ERROR); ReportError(SessionError::ENCODING_ERROR);
break; break;
} }
...@@ -335,13 +365,7 @@ void Session::OnTransportStatusChanged(CastTransportStatus status) { ...@@ -335,13 +365,7 @@ void Session::OnTransportStatusChanged(CastTransportStatus status) {
case CastTransportStatus::TRANSPORT_STREAM_INITIALIZED: case CastTransportStatus::TRANSPORT_STREAM_INITIALIZED:
return; // Not errors, do nothing. return; // Not errors, do nothing.
case CastTransportStatus::TRANSPORT_INVALID_CRYPTO_CONFIG: case CastTransportStatus::TRANSPORT_INVALID_CRYPTO_CONFIG:
DVLOG(1) << "Warning: unexpected status: "
<< "TRANSPORT_INVALID_CRYPTO_CONFIG";
ReportError(SessionError::CAST_TRANSPORT_ERROR);
break;
case CastTransportStatus::TRANSPORT_SOCKET_ERROR: case CastTransportStatus::TRANSPORT_SOCKET_ERROR:
DVLOG(1) << "Warning: unexpected status: "
<< "TRANSPORT_SOCKET_ERROR";
ReportError(SessionError::CAST_TRANSPORT_ERROR); ReportError(SessionError::CAST_TRANSPORT_ERROR);
break; break;
} }
...@@ -360,7 +384,6 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -360,7 +384,6 @@ void Session::OnAnswer(const std::string& cast_mode,
const std::vector<FrameSenderConfig>& video_configs, const std::vector<FrameSenderConfig>& video_configs,
const ReceiverResponse& response) { const ReceiverResponse& response) {
if (!response.answer || response.type == ResponseType::UNKNOWN) { if (!response.answer || response.type == ResponseType::UNKNOWN) {
VLOG(1) << "Received a null ANSWER response.";
ReportError(ANSWER_TIME_OUT); ReportError(ANSWER_TIME_OUT);
return; return;
} }
...@@ -368,23 +391,17 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -368,23 +391,17 @@ void Session::OnAnswer(const std::string& cast_mode,
DCHECK_EQ(ResponseType::ANSWER, response.type); DCHECK_EQ(ResponseType::ANSWER, response.type);
if (response.result != "ok") { if (response.result != "ok") {
VLOG(1) << "Received an error ANSWER response.";
ReportError(ANSWER_NOT_OK); ReportError(ANSWER_NOT_OK);
return; return;
} }
const Answer& answer = *response.answer; const Answer& answer = *response.answer;
if (answer.cast_mode != cast_mode) { if (answer.cast_mode != cast_mode) {
VLOG(1) << "Unexpected cast mode=" << answer.cast_mode
<< " while expected mode=" << cast_mode;
ReportError(ANSWER_MISMATCHED_CAST_MODE); ReportError(ANSWER_MISMATCHED_CAST_MODE);
return; return;
} }
if (answer.send_indexes.size() != answer.ssrcs.size()) { if (answer.send_indexes.size() != answer.ssrcs.size()) {
VLOG(1) << "sendIndexes.length != ssrcs.length in ANSWER"
<< " sendIndexes.length=" << answer.send_indexes.size()
<< " ssrcs.length=" << answer.ssrcs.size();
ReportError(ANSWER_MISMATCHED_SSRC_LENGTH); ReportError(ANSWER_MISMATCHED_SSRC_LENGTH);
return; return;
} }
...@@ -399,15 +416,12 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -399,15 +416,12 @@ void Session::OnAnswer(const std::string& cast_mode,
for (size_t i = 0; i < answer.send_indexes.size(); ++i) { for (size_t i = 0; i < answer.send_indexes.size(); ++i) {
if (answer.send_indexes[i] < 0 || if (answer.send_indexes[i] < 0 ||
answer.send_indexes[i] >= video_idx_bound) { answer.send_indexes[i] >= video_idx_bound) {
VLOG(1) << "Invalid indexes selected in ANSWER: Select index="
<< answer.send_indexes[i] << " allowed index<" << video_idx_bound;
ReportError(ANSWER_SELECT_INVALID_INDEX); ReportError(ANSWER_SELECT_INVALID_INDEX);
return; return;
} }
if (answer.send_indexes[i] < video_start_idx) { if (answer.send_indexes[i] < video_start_idx) {
// Audio // Audio
if (has_audio) { if (has_audio) {
VLOG(1) << "Receiver selected audio RTP stream twice in ANSWER";
ReportError(ANSWER_SELECT_MULTIPLE_AUDIO); ReportError(ANSWER_SELECT_MULTIPLE_AUDIO);
return; return;
} }
...@@ -417,7 +431,6 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -417,7 +431,6 @@ void Session::OnAnswer(const std::string& cast_mode,
} else { } else {
// Video // Video
if (has_video) { if (has_video) {
VLOG(1) << "Receiver selected video RTP stream twice in ANSWER";
ReportError(ANSWER_SELECT_MULTIPLE_VIDEO); ReportError(ANSWER_SELECT_MULTIPLE_VIDEO);
return; return;
} }
...@@ -429,7 +442,6 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -429,7 +442,6 @@ void Session::OnAnswer(const std::string& cast_mode,
} }
} }
if (!has_audio && !has_video) { if (!has_audio && !has_video) {
VLOG(1) << "Incorrect ANSWER message: No audio or Video.";
ReportError(ANSWER_NO_AUDIO_OR_VIDEO); ReportError(ANSWER_NO_AUDIO_OR_VIDEO);
return; return;
} }
...@@ -455,11 +467,9 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -455,11 +467,9 @@ void Session::OnAnswer(const std::string& cast_mode,
base::DefaultTickClock::GetInstance(), base::DefaultTickClock::GetInstance(),
base::ThreadTaskRunnerHandle::Get(), audio_encode_thread_, base::ThreadTaskRunnerHandle::Get(), audio_encode_thread_,
video_encode_thread_); video_encode_thread_);
network::mojom::NetworkContextPtr network_context;
resource_provider_->GetNetworkContext(mojo::MakeRequest(&network_context));
auto udp_client = std::make_unique<UdpSocketClient>( auto udp_client = std::make_unique<UdpSocketClient>(
net::IPEndPoint(sink_info_.ip_address, answer.udp_port), net::IPEndPoint(sink_info_.ip_address, answer.udp_port),
std::move(network_context), network_context_.get(),
base::BindOnce(&Session::ReportError, weak_factory_.GetWeakPtr(), base::BindOnce(&Session::ReportError, weak_factory_.GetWeakPtr(),
SessionError::CAST_TRANSPORT_ERROR)); SessionError::CAST_TRANSPORT_ERROR));
cast_transport_ = media::cast::CastTransport::Create( cast_transport_ = media::cast::CastTransport::Create(
...@@ -504,6 +514,13 @@ void Session::OnAnswer(const std::string& cast_mode, ...@@ -504,6 +514,13 @@ void Session::OnAnswer(const std::string& cast_mode,
SessionError::VIDEO_CAPTURE_ERROR)); SessionError::VIDEO_CAPTURE_ERROR));
} }
const SessionMonitor::SessionType session_type =
(has_audio && has_video)
? SessionMonitor::AUDIO_AND_VIDEO
: has_audio ? SessionMonitor::AUDIO_ONLY : SessionMonitor::VIDEO_ONLY;
session_monitor_->StartStreamingSession(cast_environment_, session_type,
false /* is_remoting */);
if (observer_) if (observer_)
observer_->DidStart(); observer_->DidStart();
} }
......
...@@ -6,11 +6,14 @@ ...@@ -6,11 +6,14 @@
#define COMPONENTS_MIRRORING_SERVICE_SESSION_H_ #define COMPONENTS_MIRRORING_SERVICE_SESSION_H_
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "components/mirroring/service/interface.h" #include "components/mirroring/service/interface.h"
#include "components/mirroring/service/message_dispatcher.h" #include "components/mirroring/service/message_dispatcher.h"
#include "components/mirroring/service/mirror_settings.h" #include "components/mirroring/service/mirror_settings.h"
#include "components/mirroring/service/rtp_stream.h" #include "components/mirroring/service/rtp_stream.h"
#include "components/mirroring/service/session_monitor.h"
#include "components/mirroring/service/wifi_status_monitor.h"
#include "media/cast/cast_environment.h" #include "media/cast/cast_environment.h"
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
...@@ -26,6 +29,7 @@ namespace mirroring { ...@@ -26,6 +29,7 @@ namespace mirroring {
struct ReceiverResponse; struct ReceiverResponse;
class VideoCaptureClient; class VideoCaptureClient;
class SessionMonitor;
// Controls a mirroring session, including audio/video capturing and Cast // Controls a mirroring session, including audio/video capturing and Cast
// Streaming. When constructed, it does OFFER/ANSWER exchange with the mirroring // Streaming. When constructed, it does OFFER/ANSWER exchange with the mirroring
...@@ -102,6 +106,10 @@ class Session final : public RtpStreamClient { ...@@ -102,6 +106,10 @@ class Session final : public RtpStreamClient {
MessageDispatcher message_dispatcher_; MessageDispatcher message_dispatcher_;
network::mojom::NetworkContextPtr network_context_;
base::Optional<SessionMonitor> session_monitor_;
// Created after OFFER/ANSWER exchange succeeds. // Created after OFFER/ANSWER exchange succeeds.
std::unique_ptr<AudioRtpStream> audio_stream_; std::unique_ptr<AudioRtpStream> audio_stream_;
std::unique_ptr<VideoRtpStream> video_stream_; std::unique_ptr<VideoRtpStream> video_stream_;
......
This diff is collapsed.
// Copyright 2018 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 COMPONENTS_MIRRORING_SERVICE_SESSION_MONITOR_H_
#define COMPONENTS_MIRRORING_SERVICE_SESSION_MONITOR_H_
#include "components/mirroring/service/interface.h"
#include <memory>
#include <string>
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "components/mirroring/service/interface.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace media {
namespace cast {
class CastEnvironment;
class RawEventSubscriberBundle;
} // namespace cast
} // namespace media
namespace mirroring {
class WifiStatusMonitor;
// Monitors a single mirroring session's multiple Cast Streaming "subsessions",
// collecting and managing the following information:
//
// 1. WiFi signal strength, SNR, etc. on the connection between sender and
// receiver.
// 2. Extra "tags": Information about both the sender and receiver, such as
// software versions, mirroring settings, and network configuration.
// 3. Snapshots of Cast Streaming event logs (frame- and packet-level events
// that will allow an analysis of the data flows and a diagnosing of any
// issues occurring in-the-wild). Start/StopStreamingSession() are called
// to notify this monitor whenever each (of multiple) Cast Streaming
// sessions starts and ends.
//
// Either during or at the end of a session, AssembleBundlesAndClear() is called
// to re-package all of the information across multiple snapshots together into
// one bundle, whose blobs can then be included in user feedback report uploads.
//
// To avoid unbounded memory use, older data is discarded automatically if too
// much is accumulating.
class SessionMonitor {
public:
using EventsAndStats =
std::pair<std::string /* events */, std::string /* stats */>;
SessionMonitor(int max_retention_bytes,
const net::IPAddress& receiver_address,
base::Value session_tags,
network::mojom::URLLoaderFactoryPtr loader_factory,
std::unique_ptr<WifiStatusMonitor> wifi_status_monitor);
~SessionMonitor();
enum SessionType {
AUDIO_ONLY,
VIDEO_ONLY,
AUDIO_AND_VIDEO,
};
// Notifies this monitor that it may now start/stop monitoring Cast Streaming
// events/stats.
void StartStreamingSession(
scoped_refptr<media::cast::CastEnvironment> cast_environment,
SessionType session_type,
bool is_remoting);
void StopStreamingSession();
// Called when error occurs. Only records the first error since last snapshot.
void OnStreamingError(SessionError error);
// Assembles one or more bundles of data, for inclusion in user feedback
// reports. The snapshot history is cleared each time this method is called,
// and so no two calls to this method will return the same data. The caller
// may request that multiple bundles be produced. This is used, for example,
// to get one bundle that meets the upload size maximum in addition to
// another. The total data size in bytes is strictly less-than-or-equal to
// |bundle_sizes|.
std::vector<EventsAndStats> AssembleBundlesAndClear(
const std::vector<int32_t>& bundle_sizes);
// Takes a snapshot of recent Cast Streaming events and statistics.
void TakeSnapshot();
private:
// Query the receiver for its current setup and uptime.
void QueryReceiverSetupInfo();
// Get Cast Streaming events/stats.
std::string GetEventLogsAndReset(bool is_audio,
const std::string& extra_data);
std::unique_ptr<base::Value> GetStatsAndReset(bool is_audio);
// Assemble the most-recent events+stats snapshots to a bundle of a byte size
// less than or equal to |max_bytes|.
EventsAndStats MakeSliceOfSnapshots(int32_t max_bytes);
const int max_retention_bytes_; // Maximum number of bytes to keep.
const net::IPAddress receiver_address_;
base::Value session_tags_; // Streaming session-level tags.
network::mojom::URLLoaderFactoryPtr url_loader_factory_;
// Monitors the WiFi status if not null.
const std::unique_ptr<WifiStatusMonitor> wifi_status_monitor_;
std::unique_ptr<media::cast::RawEventSubscriberBundle> event_subscribers_;
base::RepeatingTimer snapshot_timer_;
// The time that the current snapshot starts.
base::Time start_time_;
// The most recent snapshots, from oldest to newest. The total size of the
// data stored in this list is bounded by |max_retention_bytes_|.
base::circular_deque<EventsAndStats> snapshots_;
// The number of bytes currently stored in |snapshots_|.
int stored_snapshots_bytes_;
base::Time error_time_;
base::Optional<SessionError> error_;
base::WeakPtrFactory<SessionMonitor> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SessionMonitor);
};
} // namespace mirroring
#endif // COMPONENTS_MIRRORING_SERVICE_SESSION_MONITOR_H_
This diff is collapsed.
...@@ -111,6 +111,7 @@ class SessionTest : public ResourceProvider, ...@@ -111,6 +111,7 @@ class SessionTest : public ResourceProvider,
sink_info.capability = DeviceCapability::AUDIO_AND_VIDEO; sink_info.capability = DeviceCapability::AUDIO_AND_VIDEO;
// Expect to receive OFFER message when session is created. // Expect to receive OFFER message when session is created.
base::RunLoop run_loop; base::RunLoop run_loop;
EXPECT_CALL(*this, OnGetNetworkContext()).Times(1);
EXPECT_CALL(*this, OnError(_)).Times(0); EXPECT_CALL(*this, OnError(_)).Times(0);
EXPECT_CALL(*this, OnOffer()) EXPECT_CALL(*this, OnOffer())
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
...@@ -140,7 +141,6 @@ TEST_F(SessionTest, Mirroring) { ...@@ -140,7 +141,6 @@ TEST_F(SessionTest, Mirroring) {
// Except mirroing session starts after receiving ANSWER message. // Except mirroing session starts after receiving ANSWER message.
base::RunLoop run_loop; base::RunLoop run_loop;
EXPECT_CALL(*this, OnGetVideoCaptureHost()).Times(1); EXPECT_CALL(*this, OnGetVideoCaptureHost()).Times(1);
EXPECT_CALL(*this, OnGetNetworkContext()).Times(1);
EXPECT_CALL(*this, OnError(_)).Times(0); EXPECT_CALL(*this, OnError(_)).Times(0);
EXPECT_CALL(*this, DidStart()) EXPECT_CALL(*this, DidStart())
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
...@@ -180,7 +180,6 @@ TEST_F(SessionTest, AnswerTimeout) { ...@@ -180,7 +180,6 @@ TEST_F(SessionTest, AnswerTimeout) {
// Expect error. // Expect error.
base::RunLoop run_loop; base::RunLoop run_loop;
EXPECT_CALL(*this, OnGetVideoCaptureHost()).Times(0); EXPECT_CALL(*this, OnGetVideoCaptureHost()).Times(0);
EXPECT_CALL(*this, OnGetNetworkContext()).Times(0);
EXPECT_CALL(*this, DidStop()).Times(1); EXPECT_CALL(*this, DidStop()).Times(1);
EXPECT_CALL(*this, OnError(ANSWER_TIME_OUT)) EXPECT_CALL(*this, OnError(ANSWER_TIME_OUT))
.WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
......
...@@ -47,16 +47,18 @@ net::NetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag() { ...@@ -47,16 +47,18 @@ net::NetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag() {
} // namespace } // namespace
UdpSocketClient::UdpSocketClient(const net::IPEndPoint& remote_endpoint, UdpSocketClient::UdpSocketClient(const net::IPEndPoint& remote_endpoint,
network::mojom::NetworkContextPtr context, network::mojom::NetworkContext* context,
base::OnceClosure error_callback) base::OnceClosure error_callback)
: remote_endpoint_(remote_endpoint), : remote_endpoint_(remote_endpoint),
network_context_(std::move(context)), network_context_(context),
error_callback_(std::move(error_callback)), error_callback_(std::move(error_callback)),
binding_(this), binding_(this),
bytes_sent_(0), bytes_sent_(0),
allow_sending_(false), allow_sending_(false),
num_packets_pending_receive_(0), num_packets_pending_receive_(0),
weak_factory_(this) {} weak_factory_(this) {
DCHECK(network_context_);
}
UdpSocketClient::~UdpSocketClient() {} UdpSocketClient::~UdpSocketClient() {}
......
...@@ -24,7 +24,7 @@ class UdpSocketClient final : public media::cast::PacketTransport, ...@@ -24,7 +24,7 @@ class UdpSocketClient final : public media::cast::PacketTransport,
public network::mojom::UDPSocketReceiver { public network::mojom::UDPSocketReceiver {
public: public:
UdpSocketClient(const net::IPEndPoint& remote_endpoint, UdpSocketClient(const net::IPEndPoint& remote_endpoint,
network::mojom::NetworkContextPtr context, network::mojom::NetworkContext* context,
base::OnceClosure error_callback); base::OnceClosure error_callback);
~UdpSocketClient() override; ~UdpSocketClient() override;
...@@ -54,7 +54,7 @@ class UdpSocketClient final : public media::cast::PacketTransport, ...@@ -54,7 +54,7 @@ class UdpSocketClient final : public media::cast::PacketTransport,
const base::Optional<net::IPEndPoint>& addr); const base::Optional<net::IPEndPoint>& addr);
const net::IPEndPoint remote_endpoint_; const net::IPEndPoint remote_endpoint_;
const network::mojom::NetworkContextPtr network_context_; network::mojom::NetworkContext* const network_context_;
base::OnceClosure error_callback_; base::OnceClosure error_callback_;
mojo::Binding<network::mojom::UDPSocketReceiver> binding_; mojo::Binding<network::mojom::UDPSocketReceiver> binding_;
......
...@@ -30,11 +30,10 @@ namespace mirroring { ...@@ -30,11 +30,10 @@ namespace mirroring {
class UdpSocketClientTest : public ::testing::Test { class UdpSocketClientTest : public ::testing::Test {
public: public:
UdpSocketClientTest() { UdpSocketClientTest() {
network::mojom::NetworkContextPtr network_context_ptr;
network_context_ = std::make_unique<MockNetworkContext>( network_context_ = std::make_unique<MockNetworkContext>(
mojo::MakeRequest(&network_context_ptr)); mojo::MakeRequest(&network_context_ptr_));
udp_transport_client_ = std::make_unique<UdpSocketClient>( udp_transport_client_ = std::make_unique<UdpSocketClient>(
media::cast::test::GetFreeLocalPort(), std::move(network_context_ptr), media::cast::test::GetFreeLocalPort(), network_context_ptr_.get(),
base::OnceClosure()); base::OnceClosure());
} }
...@@ -49,6 +48,7 @@ class UdpSocketClientTest : public ::testing::Test { ...@@ -49,6 +48,7 @@ class UdpSocketClientTest : public ::testing::Test {
protected: protected:
base::test::ScopedTaskEnvironment scoped_task_environment_; base::test::ScopedTaskEnvironment scoped_task_environment_;
network::mojom::NetworkContextPtr network_context_ptr_;
std::unique_ptr<MockNetworkContext> network_context_; std::unique_ptr<MockNetworkContext> network_context_;
std::unique_ptr<UdpSocketClient> udp_transport_client_; std::unique_ptr<UdpSocketClient> udp_transport_client_;
std::unique_ptr<Packet> received_packet_; std::unique_ptr<Packet> received_packet_;
......
...@@ -135,6 +135,7 @@ Refer to README.md for content description and update process. ...@@ -135,6 +135,7 @@ Refer to README.md for content description and update process.
<item id="logo_tracker" hash_code="36859107" type="0" content_hash_code="67588075" os_list="linux,windows" file_path="components/search_provider_logos/logo_tracker.cc"/> <item id="logo_tracker" hash_code="36859107" type="0" content_hash_code="67588075" os_list="linux,windows" file_path="components/search_provider_logos/logo_tracker.cc"/>
<item id="metrics_report_ukm" hash_code="727478" type="0" content_hash_code="40919254" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> <item id="metrics_report_ukm" hash_code="727478" type="0" content_hash_code="40919254" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/>
<item id="metrics_report_uma" hash_code="727528" type="0" content_hash_code="10176197" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> <item id="metrics_report_uma" hash_code="727528" type="0" content_hash_code="10176197" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/>
<item id="mirroring_get_setup_info" hash_code="78447809" type="0" content_hash_code="112561099" os_list="linux,windows" file_path="components/mirroring/service/session_monitor.cc"/>
<item id="missing" hash_code="77012883" type="0" reserved="1" os_list="linux,windows" file_path=""/> <item id="missing" hash_code="77012883" type="0" reserved="1" os_list="linux,windows" file_path=""/>
<item id="mojo_context_state" hash_code="93232258" type="0" deprecated="2017-10-20" content_hash_code="124821232" file_path=""/> <item id="mojo_context_state" hash_code="93232258" type="0" deprecated="2017-10-20" content_hash_code="124821232" file_path=""/>
<item id="navigation_url_loader" hash_code="63171670" type="0" content_hash_code="129352907" os_list="linux,windows" file_path="content/browser/loader/navigation_url_loader_impl.cc"/> <item id="navigation_url_loader" hash_code="63171670" type="0" content_hash_code="129352907" os_list="linux,windows" file_path="content/browser/loader/navigation_url_loader_impl.cc"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment