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

#include <map>
#include <string>

#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
#include "base/test/scoped_task_environment.h"
#include "components/ukm/test_ukm_recorder.h"
#include "media/capabilities/video_decode_stats_db.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

using UkmEntry = ukm::builders::Media_VideoDecodePerfRecord;
using testing::Eq;
using testing::IsNull;
using testing::_;

namespace {

// Aliases for readability.
const bool kIsSmooth = true;
const bool kIsNotSmooth = false;
const bool kIsPowerEfficient = true;
const bool kIsNotPowerEfficient = false;
const url::Origin kOrigin = url::Origin::Create(GURL("http://example.com"));
const bool kIsTopFrame = true;
const uint64_t kPlayerId = 1234u;

}  // namespace

namespace media {

class FakeVideoDecodeStatsDB : public VideoDecodeStatsDB {
 public:
  FakeVideoDecodeStatsDB() = default;
  ~FakeVideoDecodeStatsDB() override = default;

  // Call CompleteInitialize(...) to run |init_cb| callback.
  void Initialize(base::OnceCallback<void(bool)> init_cb) override {
    pendnding_init_cb_ = std::move(init_cb);
  }

  // Completes fake initialization, running |init_cb| with the supplied value
  // for success.
  void CompleteInitialize(bool success) {
    DVLOG(2) << __func__ << " running with success = " << success;
    EXPECT_FALSE(pendnding_init_cb_.is_null());
    std::move(pendnding_init_cb_).Run(success);
  }

  void AppendDecodeStats(const VideoDescKey& key,
                         const DecodeStatsEntry& new_entry,
                         AppendDecodeStatsCB append_done_cb) override {
    std::string key_str = MakeKeyString(key);
    if (entries_.find(key_str) == entries_.end()) {
      entries_.emplace(std::make_pair(key_str, new_entry));
    } else {
      const DecodeStatsEntry& known_entry = entries_.at(key_str);
      entries_.at(key_str) = DecodeStatsEntry(
          known_entry.frames_decoded + new_entry.frames_decoded,
          known_entry.frames_dropped + new_entry.frames_dropped,
          known_entry.frames_decoded_power_efficient +
              new_entry.frames_decoded_power_efficient);
    }

    std::move(append_done_cb).Run(true);
  }

  void GetDecodeStats(const VideoDescKey& key,
                      GetDecodeStatsCB get_stats_cb) override {
    auto entry_it = entries_.find(MakeKeyString(key));
    if (entry_it == entries_.end()) {
      std::move(get_stats_cb).Run(true, nullptr);
    } else {
      std::move(get_stats_cb)
          .Run(true, std::make_unique<DecodeStatsEntry>(entry_it->second));
    }
  }

  void DestroyStats(base::OnceClosure destroy_done_cb) override {
    entries_.clear();
    std::move(destroy_done_cb).Run();
  }

 private:
  static std::string MakeKeyString(const VideoDescKey& key) {
    return base::StringPrintf("%d|%s|%d", static_cast<int>(key.codec_profile),
                              key.size.ToString().c_str(), key.frame_rate);
  }

  std::map<std::string, DecodeStatsEntry> entries_;

  base::OnceCallback<void(bool)> pendnding_init_cb_;
};

// Simple factory that always returns the pointer its given. The lifetime of
// |db| is managed by the CreateDB() caller.
class FakeVideoDecodeStatsDBFactory : public VideoDecodeStatsDBFactory {
 public:
  FakeVideoDecodeStatsDBFactory() = default;
  ~FakeVideoDecodeStatsDBFactory() override = default;

  std::unique_ptr<VideoDecodeStatsDB> CreateDB() override {
    return std::make_unique<FakeVideoDecodeStatsDB>();
  }
};

class VideoDecodePerfHistoryTest : public testing::Test {
 public:
  void SetUp() override {
    test_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
    perf_history_ = std::make_unique<VideoDecodePerfHistory>(
        std::make_unique<FakeVideoDecodeStatsDBFactory>());
  }

  void TearDown() override { perf_history_.reset(); }

  FakeVideoDecodeStatsDB* GetFakeDB() {
    return static_cast<FakeVideoDecodeStatsDB*>(perf_history_->db_.get());
  }

  void PreInitializeDB(bool initialize_success) {
    // Invoke private method to start initialization. Usually invoked by first
    // API call requiring DB access.
    perf_history_->InitDatabase();
    // Complete initialization by firing callback from our fake DB.
    GetFakeDB()->CompleteInitialize(initialize_success);
  }

  // Clearing history internally recreates and re-initializes the database.
  // Tests may set this as the callback for VideoDecodePerfHistory::ClearHistory
  // to automatically complete re-initialization and finally call
  // MockOnClearedHistory (which tests may EXPECT_CALL).
  void CompleteDBInitOnClearedHistory() {
    DCHECK_EQ(VideoDecodePerfHistory::InitStatus::PENDING,
              perf_history_->db_init_status_);

    GetFakeDB()->CompleteInitialize(true /* success */);

    DCHECK_EQ(VideoDecodePerfHistory::InitStatus::COMPLETE,
              perf_history_->db_init_status_);

    MockOnClearedHistory();
  }

  // Tests may set this as the callback for VideoDecodePerfHistory::GetPerfInfo
  // to check the results of the call.
  MOCK_METHOD2(MockGetPerfInfoCB,
               void(bool is_smooth, bool is_power_efficient));

  // Tests should EXPECT_CALL this method prior to ClearHistory() to know that
  // the operation has completed. See CompleteDBInitOnClearedHistory().
  MOCK_METHOD0(MockOnClearedHistory, void());

  MOCK_METHOD1(MockGetVideoDecodeStatsDBCB, void(VideoDecodeStatsDB* db));

  mojom::PredictionFeatures MakeFeatures(VideoCodecProfile profile,
                                         gfx::Size video_size,
                                         int frames_per_sec) {
    mojom::PredictionFeatures features;
    features.profile = profile;
    features.video_size = video_size;
    features.frames_per_sec = frames_per_sec;
    return features;
  }

  mojom::PredictionFeaturesPtr MakeFeaturesPtr(VideoCodecProfile profile,
                                               gfx::Size video_size,
                                               int frames_per_sec) {
    mojom::PredictionFeaturesPtr features = mojom::PredictionFeatures::New();
    *features = MakeFeatures(profile, video_size, frames_per_sec);
    return features;
  }

  mojom::PredictionTargets MakeTargets(
      uint32_t frames_decoded,
      uint32_t frames_dropped,
      uint32_t frames_decoded_power_efficient) {
    mojom::PredictionTargets targets;
    targets.frames_decoded = frames_decoded;
    targets.frames_dropped = frames_dropped;
    targets.frames_decoded_power_efficient = frames_decoded_power_efficient;
    return targets;
  }

 protected:
  using VideoDescKey = VideoDecodeStatsDB::VideoDescKey;
  using DecodeStatsEntry = VideoDecodeStatsDB::DecodeStatsEntry;

  static constexpr double kMaxSmoothDroppedFramesPercent =
      VideoDecodePerfHistory::kMaxSmoothDroppedFramesPercent;
  static constexpr double kMinPowerEfficientDecodedFramePercent =
      VideoDecodePerfHistory::kMinPowerEfficientDecodedFramePercent;

  base::test::ScopedTaskEnvironment scoped_task_environment_;

  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_recorder_;

  // The VideoDecodeStatsReporter being tested.
  std::unique_ptr<VideoDecodePerfHistory> perf_history_;
};

// When bool param is true, tests should wait until the end to run
// GetFakeDB()->CompleteInitialize(). Otherwise run PreInitializeDB() at the
// test start.
class VideoDecodePerfHistoryParamTest
    : public testing::WithParamInterface<bool>,
      public VideoDecodePerfHistoryTest {};

TEST_P(VideoDecodePerfHistoryParamTest, GetPerfInfo_Smooth) {
  // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
  // delayed until we db_->CompleteInitialize(). testing::InSequence enforces
  // that EXPECT_CALLs arrive in top-to-bottom order.
  bool defer_initialize = GetParam();
  testing::InSequence dummy;

  // Complete initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ true);

  // First add 2 records to the history. The second record has a higher frame
  // rate and a higher number of dropped frames such that it is "not smooth".
  const VideoCodecProfile kKnownProfile = VP9PROFILE_PROFILE0;
  const gfx::Size kKownSize(100, 200);
  const int kSmoothFrameRate = 30;
  const int kNotSmoothFrameRate = 90;
  const int kFramesDecoded = 1000;
  const int kNotPowerEfficientFramesDecoded = 0;
  // Sets the ratio of dropped frames to barely qualify as smooth.
  const int kSmoothFramesDropped =
      kFramesDecoded * kMaxSmoothDroppedFramesPercent;
  // Set the ratio of dropped frames to barely qualify as NOT smooth.
  const int kNotSmoothFramesDropped =
      kFramesDecoded * kMaxSmoothDroppedFramesPercent + 1;

  // Add the entries.
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame,
      MakeFeatures(kKnownProfile, kKownSize, kSmoothFrameRate),
      MakeTargets(kFramesDecoded, kSmoothFramesDropped,
                  kNotPowerEfficientFramesDecoded),
      kPlayerId);
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame,
      MakeFeatures(kKnownProfile, kKownSize, kNotSmoothFrameRate),
      MakeTargets(kFramesDecoded, kNotSmoothFramesDropped,
                  kNotPowerEfficientFramesDecoded),
      kPlayerId);

  // Verify perf history returns is_smooth = true for the smooth entry.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsNotPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kKnownProfile, kKownSize, kSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Verify perf history returns is_smooth = false for the NOT smooth entry.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsNotSmooth, kIsNotPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kKnownProfile, kKownSize, kNotSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Verify perf history optimistically returns is_smooth = true when no entry
  // can be found with the given configuration.
  const VideoCodecProfile kUnknownProfile = VP9PROFILE_PROFILE2;
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kUnknownProfile, kKownSize, kNotSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Complete successful deferred DB initialization (see comment at top of test)
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(true);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }
}

TEST_P(VideoDecodePerfHistoryParamTest, GetPerfInfo_PowerEfficient) {
  // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
  // delayed until we db_->CompleteInitialize(). testing::InSequence enforces
  // that EXPECT_CALLs arrive in top-to-bottom order.
  bool defer_initialize = GetParam();
  testing::InSequence dummy;

  // Complete initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ true);

  // First add 3 records to the history:
  // - the first has a high number of power efficiently decoded frames;
  // - the second has a low number of power efficiently decoded frames;
  // - the third is similar to the first with a high number of dropped frames.
  const VideoCodecProfile kPowerEfficientProfile = VP9PROFILE_PROFILE0;
  const VideoCodecProfile kNotPowerEfficientProfile = VP8PROFILE_ANY;
  const gfx::Size kKownSize(100, 200);
  const int kSmoothFrameRate = 30;
  const int kNotSmoothFrameRate = 90;
  const int kFramesDecoded = 1000;
  const int kPowerEfficientFramesDecoded =
      kFramesDecoded * kMinPowerEfficientDecodedFramePercent;
  const int kNotPowerEfficientFramesDecoded =
      kFramesDecoded * kMinPowerEfficientDecodedFramePercent - 1;
  // Sets the ratio of dropped frames to barely qualify as smooth.
  const int kSmoothFramesDropped =
      kFramesDecoded * kMaxSmoothDroppedFramesPercent;
  // Set the ratio of dropped frames to barely qualify as NOT smooth.
  const int kNotSmoothFramesDropped =
      kFramesDecoded * kMaxSmoothDroppedFramesPercent + 1;

  // Add the entries.
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame,
      MakeFeatures(kPowerEfficientProfile, kKownSize, kSmoothFrameRate),
      MakeTargets(kFramesDecoded, kSmoothFramesDropped,
                  kPowerEfficientFramesDecoded),
      kPlayerId);
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame,
      MakeFeatures(kNotPowerEfficientProfile, kKownSize, kSmoothFrameRate),
      MakeTargets(kFramesDecoded, kSmoothFramesDropped,
                  kNotPowerEfficientFramesDecoded),
      kPlayerId);
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame,
      MakeFeatures(kPowerEfficientProfile, kKownSize, kNotSmoothFrameRate),
      MakeTargets(kFramesDecoded, kNotSmoothFramesDropped,
                  kPowerEfficientFramesDecoded),
      kPlayerId);

  // Verify perf history returns is_smooth = true, is_power_efficient = true.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kPowerEfficientProfile, kKownSize, kSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Verify perf history returns is_smooth = true, is_power_efficient = false.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsNotPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kNotPowerEfficientProfile, kKownSize, kSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Verify perf history returns is_smooth = false, is_power_efficient = true.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsNotSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kPowerEfficientProfile, kKownSize, kNotSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Verify perf history optimistically returns is_smooth = true and
  // is_power_efficient = true when no entry can be found with the given
  // configuration.
  const VideoCodecProfile kUnknownProfile = VP9PROFILE_PROFILE2;
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kUnknownProfile, kKownSize, kNotSmoothFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Complete successful deferred DB initialization (see comment at top of test)
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(true);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }
}

TEST_P(VideoDecodePerfHistoryParamTest, GetPerfInfo_FailedInitialize) {
  bool defer_initialize = GetParam();
  // Fail initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ false);

  const VideoCodecProfile kProfile = VP9PROFILE_PROFILE0;
  const gfx::Size kSize(100, 200);
  const int kFrameRate = 30;

  // When initialization fails, callback should optimistically claim both smooth
  // and power efficient performance.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kProfile, kSize, kFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Fail deferred DB initialization (see comment at top of test).
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(false);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }
}

TEST_P(VideoDecodePerfHistoryParamTest, AppendAndDestroyStats) {
  // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
  // delayed until we db_->CompleteInitialize(). testing::InSequence enforces
  // that EXPECT_CALLs arrive in top-to-bottom order.
  bool defer_initialize = GetParam();
  testing::InSequence dummy;

  // Complete initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ true);

  // Add a simple record to the history.
  const VideoCodecProfile kProfile = VP9PROFILE_PROFILE0;
  const gfx::Size kSize(100, 200);
  const int kFrameRate = 30;
  const int kFramesDecoded = 1000;
  const int kManyFramesDropped = kFramesDecoded / 2;
  const int kFramesPowerEfficient = kFramesDecoded;
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame, MakeFeatures(kProfile, kSize, kFrameRate),
      MakeTargets(kFramesDecoded, kManyFramesDropped, kFramesPowerEfficient),
      kPlayerId);

  // Verify its there before we ClearHistory(). Note that perf is NOT smooth.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsNotSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kProfile, kSize, kFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Initiate async clearing of history.
  EXPECT_CALL(*this, MockOnClearedHistory());
  perf_history_->ClearHistory(base::BindOnce(
      &VideoDecodePerfHistoryParamTest::CompleteDBInitOnClearedHistory,
      base::Unretained(this)));

  // Verify record we added above is no longer present.
  // SUBTLE: The PerfHistory will optimistically respond kIsSmooth when no data
  // is found. So the signal that the entry was removed is the CB now claims
  // "smooth" when it claimed NOT smooth just moments before.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kProfile, kSize, kFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Complete successful deferred DB initialization (see comment at top of test)
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(true);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }

  const auto& entries = test_recorder_->GetEntriesByName(UkmEntry::kEntryName);
  EXPECT_EQ(1u, entries.size());
  for (const auto* entry : entries) {
    test_recorder_->ExpectEntrySourceHasUrl(entry, kOrigin.GetURL());

#define EXPECT_UKM(name, value) \
  test_recorder_->ExpectEntryMetric(entry, name, value)

    EXPECT_UKM(UkmEntry::kVideo_InTopFrameName, kIsTopFrame);
    EXPECT_UKM(UkmEntry::kVideo_PlayerIDName, kPlayerId);
    EXPECT_UKM(UkmEntry::kVideo_CodecProfileName, kProfile);
    EXPECT_UKM(UkmEntry::kVideo_FramesPerSecondName, kFrameRate);
#undef EXPECT_UKM

    // TODO(chcunningham): Expand UKM tests to include absence tests.
  }
}

TEST_P(VideoDecodePerfHistoryParamTest, GetVideoDecodeStatsDB) {
  // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
  // delayed until we db_->CompleteInitialize(). testing::InSequence enforces
  // that EXPECT_CALLs arrive in top-to-bottom order.
  bool defer_initialize = GetParam();
  testing::InSequence dummy;

  // Complete initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ true);

  // Request a pointer to VideoDecodeStatsDB and verify the callback.
  EXPECT_CALL(*this, MockGetVideoDecodeStatsDBCB(_))
      .WillOnce([&](const auto* db_ptr) {
        // Not able to simply use a matcher because the DB does not exist at the
        // time we setup the EXPECT_CALL.
        EXPECT_EQ(GetFakeDB(), db_ptr);
      });

  perf_history_->GetVideoDecodeStatsDB(
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetVideoDecodeStatsDBCB,
                     base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();

  // Complete successful deferred DB initialization (see comment at top of test)
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(true);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }
}

TEST_P(VideoDecodePerfHistoryParamTest,
       GetVideoDecodeStatsDB_FailedInitialize) {
  // NOTE: The when the DB initialization is deferred, All EXPECT_CALLs are then
  // delayed until we db_->CompleteInitialize(). testing::InSequence enforces
  // that EXPECT_CALLs arrive in top-to-bottom order.
  bool defer_initialize = GetParam();
  testing::InSequence dummy;

  // Complete initialization in advance of API calls when not asked to defer.
  if (!defer_initialize)
    PreInitializeDB(/* success */ false);

  // Request a pointer to VideoDecodeStatsDB and verify the callback provides
  // a nullptr due to failed initialization.
  EXPECT_CALL(*this, MockGetVideoDecodeStatsDBCB(IsNull()));
  perf_history_->GetVideoDecodeStatsDB(
      base::BindOnce(&VideoDecodePerfHistoryTest::MockGetVideoDecodeStatsDBCB,
                     base::Unretained(this)));

  scoped_task_environment_.RunUntilIdle();

  // Complete failed deferred DB initialization (see comment at top of test)
  if (defer_initialize) {
    GetFakeDB()->CompleteInitialize(false);

    // Allow initialize-deferred API calls to complete.
    scoped_task_environment_.RunUntilIdle();
  }
}

INSTANTIATE_TEST_CASE_P(VaryDBInitTiming,
                        VideoDecodePerfHistoryParamTest,
                        ::testing::Values(true, false));

TEST_F(VideoDecodePerfHistoryTest, AppendWhileDestroying) {
  // This test requires the DB to be always pre-initialized.
  PreInitializeDB(/* success */ true);

  // Add a simple record to the history.
  const VideoCodecProfile kProfile = VP9PROFILE_PROFILE0;
  const gfx::Size kSize(100, 200);
  const int kFrameRate = 30;
  const int kFramesDecoded = 1000;
  const int kManyFramesDropped = kFramesDecoded / 2;
  const int kFramesPowerEfficient = kFramesDecoded;

  // Initiate async clearing of history. Set the Mock callback to be called
  // directly, bypassing the reinitialization that occurs in
  // VideoDecodePerfHistoryTest::CompleteDBInitOnClearedHistory. This leaves the
  // initialization still "pending" while we attempt to SavePerfRecord() below.
  EXPECT_CALL(*this, MockOnClearedHistory());
  perf_history_->ClearHistory(
      base::BindOnce(&VideoDecodePerfHistoryTest::MockOnClearedHistory,
                     base::Unretained(this)));

  // With DB reinitialization still pending, save a record that indicates
  // NOT smooth performance.
  perf_history_->SavePerfRecord(
      kOrigin, kIsTopFrame, MakeFeatures(kProfile, kSize, kFrameRate),
      MakeTargets(kFramesDecoded, kManyFramesDropped, kFramesPowerEfficient),
      kPlayerId);

  // Expect that NOT smooth is eventually reported (after DB reinitialization
  // completes) when we query this stream description.
  EXPECT_CALL(*this, MockGetPerfInfoCB(kIsNotSmooth, kIsPowerEfficient));
  perf_history_->GetPerfInfo(
      MakeFeaturesPtr(kProfile, kSize, kFrameRate),
      base::BindOnce(&VideoDecodePerfHistoryParamTest::MockGetPerfInfoCB,
                     base::Unretained(this)));

  // Finally, complete DB reinitialization that was triggered by clearing the
  // history.
  GetFakeDB()->CompleteInitialize(/* success */ true);

  // Allow initialize-deferred API calls to complete.
  scoped_task_environment_.RunUntilIdle();
}

}  // namespace media
