Add FieldTrialsView::clone

To mitigate life-cycle problems when passing
these between object with different life cycle.

Bug: webrtc:443588673
Change-Id: I85fab04a27678fb8dd96b98415a74c4b1a543829
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/408881
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45614}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 1d7d864..47f3e23 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -1721,6 +1721,7 @@
   visibility = [ "*" ]
   sources = [ "field_trials_view.h" ]
   deps = [
+    "../rtc_base:checks",
     "../rtc_base/system:rtc_export",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
diff --git a/api/environment/deprecated_global_field_trials.h b/api/environment/deprecated_global_field_trials.h
index 6af9cae..424c778 100644
--- a/api/environment/deprecated_global_field_trials.h
+++ b/api/environment/deprecated_global_field_trials.h
@@ -10,6 +10,7 @@
 #ifndef API_ENVIRONMENT_DEPRECATED_GLOBAL_FIELD_TRIALS_H_
 #define API_ENVIRONMENT_DEPRECATED_GLOBAL_FIELD_TRIALS_H_
 
+#include <memory>
 #include <string>
 
 #include "absl/strings/string_view.h"
@@ -22,6 +23,10 @@
  public:
   static void Set(const char* field_trials);
 
+  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
+    return std::make_unique<DeprecatedGlobalFieldTrials>();
+  }
+
  private:
   std::string GetValue(absl::string_view key) const override;
 };
diff --git a/api/environment/environment_unittest.cc b/api/environment/environment_unittest.cc
index 12dd40d..c00c104 100644
--- a/api/environment/environment_unittest.cc
+++ b/api/environment/environment_unittest.cc
@@ -58,6 +58,10 @@
     return "fake";
   }
 
+  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
+    return std::make_unique<FakeFieldTrials>([] {});
+  }
+
  private:
   absl::AnyInvocable<void() &&> on_destroyed_;
 };
diff --git a/api/field_trials.h b/api/field_trials.h
index 5cb36bf..e3c2419 100644
--- a/api/field_trials.h
+++ b/api/field_trials.h
@@ -70,6 +70,11 @@
   // Setting empty `group` is valid and removes the `trial`.
   void Set(absl::string_view trial, absl::string_view group);
 
+  // Create a copy of this view.
+  std::unique_ptr<FieldTrialsView> CreateCopy() const override {
+    return std::make_unique<FieldTrials>(*this);
+  }
+
  private:
   explicit FieldTrials(flat_map<std::string, std::string> key_value_map)
       : key_value_map_(std::move(key_value_map)) {}
diff --git a/api/field_trials_unittest.cc b/api/field_trials_unittest.cc
index e27ab4e..c1b4fc4 100644
--- a/api/field_trials_unittest.cc
+++ b/api/field_trials_unittest.cc
@@ -155,5 +155,15 @@
   EXPECT_EQ(f2.Lookup("Audio"), "Disabled");
 }
 
+TEST(FieldTrialsTest, CreateCopy) {
+  auto f = std::make_unique<FieldTrials>("Audio/Enabled/");
+  f->RegisterKeysForTesting({"Audio"});
+
+  FieldTrialsView* view = f.get();
+  auto copy = view->CreateCopy();
+  f.reset();
+  EXPECT_EQ(copy->Lookup("Audio"), "Enabled");
+}
+
 }  // namespace
 }  // namespace webrtc
diff --git a/api/field_trials_view.h b/api/field_trials_view.h
index d8df845..286bd43 100644
--- a/api/field_trials_view.h
+++ b/api/field_trials_view.h
@@ -10,10 +10,12 @@
 #ifndef API_FIELD_TRIALS_VIEW_H_
 #define API_FIELD_TRIALS_VIEW_H_
 
+#include <memory>
 #include <string>
 
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
+#include "rtc_base/checks.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -39,6 +41,16 @@
   bool IsDisabled(absl::string_view key) const {
     return absl::StartsWith(Lookup(key), "Disabled");
   }
+
+  // Create a copy of this view.
+  //
+  // This method can't be pure virtual, due to downstream projects
+  // but that is fine since they won't use the method...if they
+  // implement their own FieldTrialsView.
+  virtual std::unique_ptr<FieldTrialsView> CreateCopy() const {
+    RTC_CHECK_NOTREACHED();
+    return nullptr;
+  }
 };
 
 }  // namespace webrtc
diff --git a/video/corruption_detection/evaluation/BUILD.gn b/video/corruption_detection/evaluation/BUILD.gn
index 04db552..9d67d2d 100644
--- a/video/corruption_detection/evaluation/BUILD.gn
+++ b/video/corruption_detection/evaluation/BUILD.gn
@@ -143,7 +143,7 @@
       ":picture_pair_provider",
       ":utils",
       ":webrtc_picture_pair_provider",
-      "../../../api:field_trials_view",
+      "../../../api:field_trials",
       "../../../api:mock_video_codec_factory",
       "../../../api:mock_video_decoder",
       "../../../api:mock_video_encoder",
diff --git a/video/corruption_detection/evaluation/webrtc_picture_pair_provider_unittest.cc b/video/corruption_detection/evaluation/webrtc_picture_pair_provider_unittest.cc
index cc11ec0..b687155 100644
--- a/video/corruption_detection/evaluation/webrtc_picture_pair_provider_unittest.cc
+++ b/video/corruption_detection/evaluation/webrtc_picture_pair_provider_unittest.cc
@@ -22,7 +22,7 @@
 
 #include "absl/strings/string_view.h"
 #include "api/environment/environment_factory.h"
-#include "api/field_trials_view.h"
+#include "api/field_trials.h"
 #include "api/scoped_refptr.h"
 #include "api/test/mock_video_decoder.h"
 #include "api/test/mock_video_decoder_factory.h"
@@ -130,11 +130,6 @@
                                  kCodecMode);
 }
 
-class EmptyFieldTrials : public FieldTrialsView {
- public:
-  std::string Lookup(absl::string_view key) const override { return ""; }
-};
-
 class WebRtcPicturePairProviderTest : public TestWithParam<VideoCodecType> {
  protected:
   WebRtcPicturePairProviderTest()
@@ -385,7 +380,7 @@
   codec_config.spatialLayers[0].maxBitrate = bitrate_kbps;
   codec_config.spatialLayers[0].active = true;
 
-  SvcRateAllocator svc_rate_allocator(codec_config, EmptyFieldTrials());
+  SvcRateAllocator svc_rate_allocator(codec_config, FieldTrials(""));
   VideoEncoder::RateControlParameters rate_params =
       VideoEncoder::RateControlParameters(
           svc_rate_allocator.GetAllocation(kDefaultBitrate.bps(), kFramerate),