// Copyright 2014 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.

#include <memory>
#include <numeric>
#include <utility>

#include "base/base64.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/task_scheduler.h"
#include "base/threading/thread_task_runner_handle.h"
#include "jingle/glue/thread_wrapper.h"
#include "net/test/test_data_directory.h"
#include "net/url_request/url_request_context_getter.h"
#include "remoting/base/rsa_key_pair.h"
#include "remoting/base/url_request.h"
#include "remoting/client/audio/audio_player.h"
#include "remoting/client/chromoting_client.h"
#include "remoting/client/client_context.h"
#include "remoting/client/client_user_interface.h"
#include "remoting/client/software_video_renderer.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/fake_desktop_environment.h"
#include "remoting/protocol/auth_util.h"
#include "remoting/protocol/client_authentication_config.h"
#include "remoting/protocol/frame_consumer.h"
#include "remoting/protocol/frame_stats.h"
#include "remoting/protocol/jingle_session_manager.h"
#include "remoting/protocol/me2me_host_authenticator_factory.h"
#include "remoting/protocol/session_config.h"
#include "remoting/protocol/transport_context.h"
#include "remoting/protocol/video_frame_pump.h"
#include "remoting/protocol/video_renderer.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "remoting/test/cyclic_frame_generator.h"
#include "remoting/test/fake_network_dispatcher.h"
#include "remoting/test/fake_port_allocator.h"
#include "remoting/test/fake_socket_factory.h"
#include "remoting/test/scroll_frame_generator.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

using protocol::ChannelConfig;

namespace {

const char kHostJid[] = "host_jid@example.com/host";
const char kHostOwner[] = "jane.doe@example.com";
const char kClientJid[] = "jane.doe@example.com/client";
const char kHostId[] = "ABC123";
const char kHostPin[] = "123456";

struct NetworkPerformanceParams {
  // |buffer_s| defines buffer size in seconds. actual buffer size is calculated
  // based on bandwidth_kbps
  NetworkPerformanceParams(int bandwidth_kbps,
                           double buffer_s,
                           double latency_average_ms,
                           double latency_stddev_ms,
                           double out_of_order_rate,
                           double signaling_latency_ms)
      : bandwidth_kbps(bandwidth_kbps),
        max_buffers(buffer_s * bandwidth_kbps * 1000 / 8),
        latency_average(base::TimeDelta::FromMillisecondsD(latency_average_ms)),
        latency_stddev(base::TimeDelta::FromMillisecondsD(latency_stddev_ms)),
        out_of_order_rate(out_of_order_rate),
        signaling_latency(
            base::TimeDelta::FromMillisecondsD(signaling_latency_ms)) {}

  int bandwidth_kbps;
  int max_buffers;
  base::TimeDelta latency_average;
  base::TimeDelta latency_stddev;
  double out_of_order_rate;
  base::TimeDelta signaling_latency;
};

class FakeCursorShapeStub : public protocol::CursorShapeStub {
 public:
  FakeCursorShapeStub() = default;
  ~FakeCursorShapeStub() override = default;

  // protocol::CursorShapeStub interface.
  void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) override {}
};

}  // namespace

class ProtocolPerfTest
    : public testing::Test,
      public testing::WithParamInterface<NetworkPerformanceParams>,
      public ClientUserInterface,
      public protocol::FrameConsumer,
      public protocol::FrameStatsConsumer,
      public HostStatusObserver {
 public:
  ProtocolPerfTest()
      : host_thread_("host"),
        capture_thread_("capture"),
        encode_thread_("encode"),
        decode_thread_("decode") {
    host_thread_.StartWithOptions(
        base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
    capture_thread_.Start();
    encode_thread_.Start();
    decode_thread_.Start();

    base::TaskScheduler::CreateAndStartWithDefaultParams("ProtocolPerfTest");

    desktop_environment_factory_.reset(
        new FakeDesktopEnvironmentFactory(capture_thread_.task_runner()));
  }

  virtual ~ProtocolPerfTest() {
    host_thread_.task_runner()->DeleteSoon(FROM_HERE, host_.release());
    host_thread_.task_runner()->DeleteSoon(FROM_HERE,
                                           host_signaling_.release());
    base::RunLoop().RunUntilIdle();
  }

  // ClientUserInterface interface.
  void OnConnectionState(protocol::ConnectionToHost::State state,
                         protocol::ErrorCode error) override {
    if (state == protocol::ConnectionToHost::CONNECTED) {
      client_connected_ = true;
      if (host_connected_)
        connecting_loop_->Quit();
    }
  }
  void OnConnectionReady(bool ready) override {}
  void OnRouteChanged(const std::string& channel_name,
                      const protocol::TransportRoute& route) override {}
  void SetCapabilities(const std::string& capabilities) override {}
  void SetPairingResponse(
      const protocol::PairingResponse& pairing_response) override {}
  void DeliverHostMessage(const protocol::ExtensionMessage& message) override {}
  void SetDesktopSize(const webrtc::DesktopSize& size,
                      const webrtc::DesktopVector& dpi) override {}
  protocol::ClipboardStub* GetClipboardStub() override { return nullptr; }
  protocol::CursorShapeStub* GetCursorShapeStub() override {
    return &cursor_shape_stub_;
  }

  // protocol::FrameConsumer interface.
  std::unique_ptr<webrtc::DesktopFrame> AllocateFrame(
      const webrtc::DesktopSize& size) override {
    return std::make_unique<webrtc::BasicDesktopFrame>(size);
  }

  void DrawFrame(std::unique_ptr<webrtc::DesktopFrame> frame,
                 const base::Closure& done) override {
    last_video_frame_ = std::move(frame);
    if (!on_frame_task_.is_null())
      on_frame_task_.Run();
    if (!done.is_null())
      done.Run();
  }

  protocol::FrameConsumer::PixelFormat GetPixelFormat() override {
    return FORMAT_BGRA;
  }

  // FrameStatsConsumer interface.
  void OnVideoFrameStats(const protocol::FrameStats& frame_stats) override {
    // Ignore store stats for empty frames.
    if (!frame_stats.host_stats.frame_size)
      return;

    frame_stats_.push_back(frame_stats);

    if (waiting_frame_stats_loop_ &&
        frame_stats_.size() >= num_expected_frame_stats_) {
      waiting_frame_stats_loop_->Quit();
    }
  }

  // HostStatusObserver interface.
  void OnClientAuthenticated(const std::string& jid) override {
    if (event_timestamp_source_) {
      auto& session = host_->client_sessions_for_tests().front();
      session->SetEventTimestampsSourceForTests(
          std::move(event_timestamp_source_));
    }
  }

  void OnClientConnected(const std::string& jid) override {
    message_loop_.task_runner()->PostTask(
        FROM_HERE, base::Bind(&ProtocolPerfTest::OnHostConnectedMainThread,
                              base::Unretained(this)));
  }

 protected:
  void WaitConnected() {
    client_connected_ = false;
    host_connected_ = false;

    connecting_loop_.reset(new base::RunLoop());
    connecting_loop_->Run();

    ASSERT_TRUE(client_connected_ && host_connected_);
  }

  void OnHostConnectedMainThread() {
    host_connected_ = true;
    if (client_connected_)
      connecting_loop_->Quit();
  }

  std::unique_ptr<webrtc::DesktopFrame> ReceiveFrame() {
    last_video_frame_.reset();

    waiting_frames_loop_.reset(new base::RunLoop());
    on_frame_task_ = waiting_frames_loop_->QuitClosure();
    waiting_frames_loop_->Run();
    waiting_frames_loop_.reset();

    EXPECT_TRUE(last_video_frame_);
    return std::move(last_video_frame_);
  }

  void WaitFrameStats(int num_frames) {
    num_expected_frame_stats_ = num_frames;

    waiting_frame_stats_loop_.reset(new base::RunLoop());
    waiting_frame_stats_loop_->Run();
    waiting_frame_stats_loop_.reset();

    EXPECT_GE(frame_stats_.size(), num_expected_frame_stats_);
  }

  // Creates test host and client and starts connection between them. Caller
  // should call WaitConnected() to wait until connection is established. The
  // host is started on |host_thread_| while the client works on the main
  // thread.
  void StartHostAndClient(bool use_webrtc) {
    fake_network_dispatcher_ =  new FakeNetworkDispatcher();

    client_signaling_.reset(
        new FakeSignalStrategy(SignalingAddress(kClientJid)));

    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();

    protocol_config_ = protocol::CandidateSessionConfig::CreateDefault();
    protocol_config_->DisableAudioChannel();
    protocol_config_->set_webrtc_supported(use_webrtc);
    protocol_config_->set_ice_supported(!use_webrtc);

    host_thread_.task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&ProtocolPerfTest::StartHost, base::Unretained(this)));
  }

  void StartHost() {
    DCHECK(host_thread_.task_runner()->BelongsToCurrentThread());

    jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();

    host_signaling_.reset(new FakeSignalStrategy(SignalingAddress(kHostJid)));
    host_signaling_->set_send_delay(GetParam().signaling_latency);
    host_signaling_->ConnectTo(client_signaling_.get());

    protocol::NetworkSettings network_settings(
        protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING);

    std::unique_ptr<FakePortAllocatorFactory> port_allocator_factory(
        new FakePortAllocatorFactory(fake_network_dispatcher_));
    port_allocator_factory->socket_factory()->SetBandwidth(
        GetParam().bandwidth_kbps * 1000 / 8, GetParam().max_buffers);
    port_allocator_factory->socket_factory()->SetLatency(
        GetParam().latency_average, GetParam().latency_stddev);
    port_allocator_factory->socket_factory()->set_out_of_order_rate(
        GetParam().out_of_order_rate);
    scoped_refptr<protocol::TransportContext> transport_context(
        new protocol::TransportContext(
            host_signaling_.get(), std::move(port_allocator_factory), nullptr,
            network_settings, protocol::TransportRole::SERVER));
    std::unique_ptr<protocol::SessionManager> session_manager(
        new protocol::JingleSessionManager(host_signaling_.get()));
    session_manager->set_protocol_config(protocol_config_->Clone());

    // Encoder runs on a separate thread, main thread is used for everything
    // else.
    host_.reset(new ChromotingHost(
        desktop_environment_factory_.get(), std::move(session_manager),
        transport_context, host_thread_.task_runner(),
        encode_thread_.task_runner(),
        DesktopEnvironmentOptions::CreateDefault()));

    base::FilePath certs_dir(net::GetTestCertsDirectory());

    std::string host_cert;
    ASSERT_TRUE(base::ReadFileToString(
        certs_dir.AppendASCII("unittest.selfsigned.der"), &host_cert));

    base::FilePath key_path = certs_dir.AppendASCII("unittest.key.bin");
    std::string key_string;
    ASSERT_TRUE(base::ReadFileToString(key_path, &key_string));
    std::string key_base64;
    base::Base64Encode(key_string, &key_base64);
    scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::FromString(key_base64);
    ASSERT_TRUE(key_pair.get());

    std::string host_pin_hash =
        protocol::GetSharedSecretHash(kHostId, kHostPin);
    std::unique_ptr<protocol::AuthenticatorFactory> auth_factory =
        protocol::Me2MeHostAuthenticatorFactory::CreateWithPin(
            true, kHostOwner, host_cert, key_pair, std::vector<std::string>(),
            host_pin_hash, nullptr);
    host_->SetAuthenticatorFactory(std::move(auth_factory));

    host_->status_monitor()->AddStatusObserver(this);
    host_->Start(kHostOwner);

    message_loop_.task_runner()->PostTask(
        FROM_HERE, base::Bind(&ProtocolPerfTest::StartClientAfterHost,
                              base::Unretained(this)));
  }

  void StartClientAfterHost() {
    client_signaling_->set_send_delay(GetParam().signaling_latency);
    client_signaling_->ConnectTo(host_signaling_.get());

    protocol::NetworkSettings network_settings(
        protocol::NetworkSettings::NAT_TRAVERSAL_OUTGOING);

    // Initialize client.
    client_context_.reset(
        new ClientContext(base::ThreadTaskRunnerHandle::Get()));
    client_context_->Start();

    std::unique_ptr<FakePortAllocatorFactory> port_allocator_factory(
        new FakePortAllocatorFactory(fake_network_dispatcher_));
    client_socket_factory_ = port_allocator_factory->socket_factory();
    port_allocator_factory->socket_factory()->SetBandwidth(
        GetParam().bandwidth_kbps * 1000 / 8, GetParam().max_buffers);
    port_allocator_factory->socket_factory()->SetLatency(
        GetParam().latency_average, GetParam().latency_stddev);
    port_allocator_factory->socket_factory()->set_out_of_order_rate(
        GetParam().out_of_order_rate);
    scoped_refptr<protocol::TransportContext> transport_context(
        new protocol::TransportContext(
            host_signaling_.get(), std::move(port_allocator_factory), nullptr,
            network_settings, protocol::TransportRole::CLIENT));

    protocol::ClientAuthenticationConfig client_auth_config;
    client_auth_config.host_id = kHostId;
    client_auth_config.fetch_secret_callback =
        base::Bind(&ProtocolPerfTest::FetchPin, base::Unretained(this));

    video_renderer_.reset(new SoftwareVideoRenderer(this));
    video_renderer_->Initialize(*client_context_, this);

    client_.reset(new ChromotingClient(client_context_.get(), this,
                                       video_renderer_.get(), nullptr));
    client_->set_protocol_config(protocol_config_->Clone());
    client_->Start(client_signaling_.get(), client_auth_config,
                   transport_context, kHostJid, std::string());
  }

  void FetchPin(
      bool pairing_supported,
      const protocol::SecretFetchedCallback& secret_fetched_callback) {
    secret_fetched_callback.Run(kHostPin);
  }

  void MeasureTotalLatency(bool use_webrtc);
  void MeasureScrollPerformance(bool use_webrtc);

  base::MessageLoopForIO message_loop_;

  scoped_refptr<FakeNetworkDispatcher> fake_network_dispatcher_;

  base::Thread host_thread_;
  base::Thread capture_thread_;
  base::Thread encode_thread_;
  base::Thread decode_thread_;
  std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_;

  scoped_refptr<protocol::InputEventTimestampsSource> event_timestamp_source_;

  FakeCursorShapeStub cursor_shape_stub_;

  std::unique_ptr<protocol::CandidateSessionConfig> protocol_config_;

  std::unique_ptr<FakeSignalStrategy> host_signaling_;
  std::unique_ptr<FakeSignalStrategy> client_signaling_;

  std::unique_ptr<ChromotingHost> host_;
  std::unique_ptr<ClientContext> client_context_;
  std::unique_ptr<SoftwareVideoRenderer> video_renderer_;
  std::unique_ptr<ChromotingClient> client_;

  FakePacketSocketFactory* client_socket_factory_;

  std::unique_ptr<base::RunLoop> connecting_loop_;
  std::unique_ptr<base::RunLoop> waiting_frames_loop_;

  std::unique_ptr<base::RunLoop> waiting_frame_stats_loop_;
  size_t num_expected_frame_stats_;

  bool client_connected_;
  bool host_connected_;

  base::Closure on_frame_task_;

  std::unique_ptr<VideoPacket> last_video_packet_;
  std::unique_ptr<webrtc::DesktopFrame> last_video_frame_;
  std::vector<protocol::FrameStats> frame_stats_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ProtocolPerfTest);
};

INSTANTIATE_TEST_CASE_P(
    NoDelay,
    ProtocolPerfTest,
    ::testing::Values(NetworkPerformanceParams(0, 0, 0, 0, 0.0, 0)));

INSTANTIATE_TEST_CASE_P(
    HighLatency,
    ProtocolPerfTest,
    ::testing::Values(NetworkPerformanceParams(0, 0, 300, 30, 0.0, 0),
                      NetworkPerformanceParams(0, 0, 30, 10, 0.0, 0)));

INSTANTIATE_TEST_CASE_P(
    OutOfOrder,
    ProtocolPerfTest,
    ::testing::Values(NetworkPerformanceParams(0, 0, 2, 0, 0.01, 0),
                      NetworkPerformanceParams(0, 0, 30, 1, 0.01, 0),
                      NetworkPerformanceParams(0, 0, 30, 1, 0.1, 0),
                      NetworkPerformanceParams(0, 0, 300, 20, 0.01, 0),
                      NetworkPerformanceParams(0, 0, 300, 20, 0.1, 0)));

INSTANTIATE_TEST_CASE_P(
    LimitedBandwidth,
    ProtocolPerfTest,
    ::testing::Values(
        // 100 Mbps
        NetworkPerformanceParams(100000, 0.25, 2, 1, 0.0, 0),
        NetworkPerformanceParams(100000, 1.0, 2, 1, 0.0, 0),
        // 8 Mbps
        NetworkPerformanceParams(8000, 0.25, 30, 5, 0.01, 0),
        NetworkPerformanceParams(8000, 1.0, 30, 5, 0.01, 0),
        // 2 Mbps
        NetworkPerformanceParams(2000, 0.25, 30, 5, 0.01, 0),
        NetworkPerformanceParams(2000, 1.0, 30, 5, 0.01, 0),
        // 800 kbps
        NetworkPerformanceParams(800, 0.25, 130, 5, 0.00, 0),
        NetworkPerformanceParams(800, 1.0, 130, 5, 0.00, 0)));

INSTANTIATE_TEST_CASE_P(
    SlowSignaling,
    ProtocolPerfTest,
    ::testing::Values(NetworkPerformanceParams(8000, 0.25, 30, 0, 0.0, 50),
                      NetworkPerformanceParams(8000, 0.25, 30, 0, 0.0, 500)));

// TotalLatency[Ice|Webrtc] tests measure video latency in the case when the
// whole screen is updated occasionally. It's intended to simulate the case when
// user actions (e.g. Alt-Tab, click on the task bar) cause whole screen to be
// updated.
void ProtocolPerfTest::MeasureTotalLatency(bool use_webrtc) {
  scoped_refptr<test::CyclicFrameGenerator> frame_generator =
      test::CyclicFrameGenerator::Create();
  desktop_environment_factory_->set_frame_generator(
      base::Bind(&test::CyclicFrameGenerator::GenerateFrame, frame_generator));
  event_timestamp_source_ = frame_generator;

  StartHostAndClient(use_webrtc);
  ASSERT_NO_FATAL_FAILURE(WaitConnected());

  int total_frames = 0;

  const base::TimeDelta kWarmUpTime = base::TimeDelta::FromSeconds(2);
  const base::TimeDelta kTestTime = base::TimeDelta::FromSeconds(5);

  base::TimeTicks start_time = base::TimeTicks::Now();
  while ((base::TimeTicks::Now() - start_time) < (kWarmUpTime + kTestTime)) {
    ReceiveFrame();
    ++total_frames;
  }

  WaitFrameStats(total_frames);

  int warm_up_frames = 0;

  int big_update_count = 0;
  base::TimeDelta total_latency_big_updates;
  int small_update_count = 0;
  base::TimeDelta total_latency_small_updates;
  for (int i = 0; i < total_frames; ++i) {
    const protocol::FrameStats& stats = frame_stats_[i];

    // CyclicFrameGenerator::TakeLastEventTimestamps() always returns non-null
    // timestamps.
    CHECK(!stats.host_stats.latest_event_timestamp.is_null());

    test::CyclicFrameGenerator::ChangeInfoList changes =
        frame_generator->GetChangeList(stats.host_stats.latest_event_timestamp);

    // Allow 2 seconds for the connection to warm-up, e.g. to get bandwidth
    // estimate, etc. These frames are ignored when calculating stats below.
    if (stats.client_stats.time_rendered < (start_time + kWarmUpTime)) {
      ++warm_up_frames;
      continue;
    }

    for (auto& change_info : changes) {
      base::TimeDelta latency =
          stats.client_stats.time_rendered - change_info.timestamp;
      switch (change_info.type) {
        case test::CyclicFrameGenerator::ChangeType::NO_CHANGES:
          NOTREACHED();
          break;
        case test::CyclicFrameGenerator::ChangeType::FULL:
          total_latency_big_updates += latency;
          ++big_update_count;
          break;
        case test::CyclicFrameGenerator::ChangeType::CURSOR:
          total_latency_small_updates += latency;
          ++small_update_count;
          break;
      }
    }
  }

  WaitFrameStats(total_frames);

  CHECK(big_update_count);
  VLOG(0) << "Average latency for big updates: "
          << (total_latency_big_updates / big_update_count).InMillisecondsF();

  if (small_update_count) {
    VLOG(0)
        << "Average latency for small updates: "
        << (total_latency_small_updates / small_update_count).InMillisecondsF();
  }

  double average_bwe =
      std::accumulate(frame_stats_.begin() + warm_up_frames,
                      frame_stats_.begin() + total_frames, 0.0,
                      [](double sum, const protocol::FrameStats& stats) {
                        return sum + stats.host_stats.bandwidth_estimate_kbps;
                      }) /
      (total_frames - warm_up_frames);
  VLOG(0) << "Average BW estimate: " << average_bwe
          << " (actual: " << GetParam().bandwidth_kbps << ")";
}

TEST_P(ProtocolPerfTest, TotalLatencyIce) {
  MeasureTotalLatency(false);
}

TEST_P(ProtocolPerfTest, TotalLatencyWebrtc) {
  MeasureTotalLatency(true);
}

// ScrollPerformance[Ice|Webrtc] tests simulate whole screen being scrolled
// continuously. They measure FPS and video latency.
void ProtocolPerfTest::MeasureScrollPerformance(bool use_webrtc) {
  scoped_refptr<test::ScrollFrameGenerator> frame_generator =
      new test::ScrollFrameGenerator();
  desktop_environment_factory_->set_frame_generator(
      base::Bind(&test::ScrollFrameGenerator::GenerateFrame, frame_generator));
  event_timestamp_source_ = frame_generator;

  StartHostAndClient(use_webrtc);
  ASSERT_NO_FATAL_FAILURE(WaitConnected());

  const base::TimeDelta kWarmUpTime = base::TimeDelta::FromSeconds(2);
  const base::TimeDelta kTestTime = base::TimeDelta::FromSeconds(2);

  int num_frames = 0;
  int warm_up_frames = 0;
  base::TimeTicks start_time = base::TimeTicks::Now();
  while ((base::TimeTicks::Now() - start_time) < (kTestTime + kWarmUpTime)) {
    ReceiveFrame();
    ++num_frames;

    // Allow 2 seconds for the connection to warm-up, e.g. to get bandwidth
    // estimate, etc. These frames are ignored when calculating stats below.
    if ((base::TimeTicks::Now() - start_time) < kWarmUpTime) {
      ++warm_up_frames;
      client_socket_factory_->ResetStats();
    }
  }

  base::TimeDelta total_time = (base::TimeTicks::Now() - start_time);

  WaitFrameStats(warm_up_frames + num_frames);

  int total_size =
      std::accumulate(frame_stats_.begin() + warm_up_frames,
                      frame_stats_.begin() + warm_up_frames + num_frames, 0,
                      [](int sum, const protocol::FrameStats& stats) {
                        return sum + stats.host_stats.frame_size;
                      });

  base::TimeDelta latency_sum = std::accumulate(
      frame_stats_.begin() + warm_up_frames,
      frame_stats_.begin() + warm_up_frames + num_frames, base::TimeDelta(),
      [](base::TimeDelta sum, const protocol::FrameStats& stats) {
        return sum + (stats.client_stats.time_rendered -
                      stats.host_stats.latest_event_timestamp);
      });

  double average_bwe =
      std::accumulate(frame_stats_.begin() + warm_up_frames,
                      frame_stats_.begin() + warm_up_frames + num_frames, 0.0,
                      [](double sum, const protocol::FrameStats& stats) {
                        return sum + stats.host_stats.bandwidth_estimate_kbps;
                      }) /
      num_frames;

  VLOG(0) << "FPS: " << num_frames / total_time.InSecondsF();
  VLOG(0) << "Average latency: " << latency_sum.InMillisecondsF() / num_frames
          << " ms";
  VLOG(0) << "Total size: " << total_size << " bytes";
  VLOG(0) << "Bandwidth utilization: "
          << 100 * total_size / (total_time.InSecondsF() *
                                 GetParam().bandwidth_kbps * 1000 / 8)
          << "%";
  VLOG(0) << "Network buffer delay (bufferbloat), average: "
          << client_socket_factory_->average_buffer_delay().InMilliseconds()
          << " ms,  max:"
          << client_socket_factory_->max_buffer_delay().InMilliseconds()
          << " ms";
  VLOG(0) << "Packet drop rate: " << client_socket_factory_->drop_rate();
  VLOG(0) << "Average BW estimate: " << average_bwe
          << " (actual: " << GetParam().bandwidth_kbps << ")";
}

TEST_P(ProtocolPerfTest, ScrollPerformanceIce) {
  MeasureScrollPerformance(false);
}

TEST_P(ProtocolPerfTest, ScrollPerformanceWebrtc) {
  MeasureScrollPerformance(true);
}

}  // namespace remoting
