Replace CrxComponent with std::unique_ptr<CrxComponent>.

This is a mechanical refactoring. A future CL will change the behavior to
allow injecting nullptr as a CrxComponent when the CRX is uninstalled
during an update check.

Bug: 837371,722942

Change-Id: I5f70fdd032a37c08bf35a286c51b109a2ca07ce0
Reviewed-on: https://chromium-review.googlesource.com/1027116
Reviewed-by: Joshua Pawlicki <[email protected]>
Reviewed-by: Devlin <[email protected]>
Commit-Queue: Sorin Jianu <[email protected]>
Cr-Commit-Position: refs/heads/master@{#554166}
diff --git a/components/update_client/action_runner.cc b/components/update_client/action_runner.cc
index c91388a..8cfb13c 100644
--- a/components/update_client/action_runner.cc
+++ b/components/update_client/action_runner.cc
@@ -44,7 +44,7 @@
 
 void ActionRunner::Unpack(
     std::unique_ptr<service_manager::Connector> connector) {
-  const auto& installer = component_.crx_component().installer;
+  const auto& installer = component_.crx_component()->installer;
 
   base::FilePath file_path;
   installer->GetInstalledFile(component_.action_run(), &file_path);
diff --git a/components/update_client/component.cc b/components/update_client/component.cc
index cbed9b7..6905698 100644
--- a/components/update_client/component.cc
+++ b/components/update_client/component.cc
@@ -27,12 +27,12 @@
 
 // The state machine representing how a CRX component changes during an update.
 //
-//     +------------------------> kNew <---------------------+--------+
-//     |                            |                        |        |
-//     |                            V                        |        |
-//     |                        kChecking                    |        |
-//     |                            |                        |        |
-//     |                error       V     no           no    |        |
+//     +------------------------- kNew
+//     |                            |
+//     |                            V
+//     |                        kChecking
+//     |                            |
+//     V                error       V     no           no
 //  kUpdateError <------------- [update?] -> [action?] -> kUpToDate  kUpdated
 //     ^                            |           |            ^        ^
 //     |                        yes |           | yes        |        |
@@ -212,7 +212,8 @@
   CrxUpdateItem crx_update_item;
   crx_update_item.state = state_->state();
   crx_update_item.id = id_;
-  crx_update_item.component = crx_component_;
+  if (crx_component_)
+    crx_update_item.component = *crx_component_;
   crx_update_item.last_check = last_check_;
   crx_update_item.next_version = next_version_;
   crx_update_item.next_fp = next_fp_;
@@ -256,6 +257,9 @@
 
   DCHECK_EQ(ComponentState::kNew, state());
 
+  crx_component_ = std::make_unique<CrxComponent>();
+  crx_component_->version = version;
+
   previous_version_ = version;
   next_version_ = base::Version("0");
   extra_code1_ = reason;
@@ -274,7 +278,8 @@
 
 bool Component::CanDoBackgroundDownload() const {
   // Foreground component updates are always downloaded in foreground.
-  return !is_foreground() && crx_component_.allows_background_download &&
+  return !is_foreground() &&
+         (crx_component() && crx_component()->allows_background_download) &&
          update_context_.config->EnabledBackgroundDownloader();
 }
 
@@ -361,6 +366,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto& component = State::component();
+  DCHECK(component.crx_component());
 
   component.last_check_ = base::TimeTicks::Now();
   component.update_check_complete_ = base::BindOnce(
@@ -421,11 +427,13 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto& component = State::component();
+  DCHECK(component.crx_component());
 
   component.is_update_available_ = true;
   component.NotifyObservers(Events::COMPONENT_UPDATE_FOUND);
 
-  if (component.crx_component_.supports_group_policy_enable_component_updates &&
+  if (component.crx_component()
+          ->supports_group_policy_enable_component_updates &&
       !component.update_context_.enabled_component_updates) {
     component.error_category_ = static_cast<int>(ErrorCategory::kServiceError);
     component.error_code_ = static_cast<int>(ServiceError::UPDATE_DISABLED);
@@ -462,6 +470,7 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto& component = State::component();
+  DCHECK(component.crx_component());
 
   component.NotifyObservers(Events::COMPONENT_NOT_UPDATED);
   EndState();
@@ -480,6 +489,8 @@
   const auto& component = Component::State::component();
   const auto& update_context = component.update_context_;
 
+  DCHECK(component.crx_component());
+
   crx_downloader_ = update_context.crx_downloader_factory(
       component.CanDoBackgroundDownload(),
       update_context.config->RequestContext());
@@ -548,6 +559,8 @@
   const auto& component = Component::State::component();
   const auto& update_context = component.update_context_;
 
+  DCHECK(component.crx_component());
+
   crx_downloader_ = update_context.crx_downloader_factory(
       component.CanDoBackgroundDownload(),
       update_context.config->RequestContext());
@@ -615,6 +628,8 @@
   const auto& component = Component::State::component();
   const auto& update_context = component.update_context_;
 
+  DCHECK(component.crx_component());
+
   component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
 
   // Create a fresh connector that can be used on the other task runner.
@@ -627,8 +642,8 @@
           base::BindOnce(
               &update_client::StartInstallOnBlockingTaskRunner,
               base::ThreadTaskRunnerHandle::Get(),
-              component.crx_component_.pk_hash, component.crx_path_,
-              component.next_fp_, component.crx_component_.installer,
+              component.crx_component()->pk_hash, component.crx_path_,
+              component.next_fp_, component.crx_component()->installer,
               std::move(connector),
               base::BindOnce(&Component::StateUpdatingDiff::InstallComplete,
                              base::Unretained(this))));
@@ -679,6 +694,8 @@
   const auto& component = Component::State::component();
   const auto& update_context = component.update_context_;
 
+  DCHECK(component.crx_component());
+
   component.NotifyObservers(Events::COMPONENT_UPDATE_READY);
 
   // Create a fresh connector that can be used on the other task runner.
@@ -690,8 +707,8 @@
                  base::BindOnce(
                      &update_client::StartInstallOnBlockingTaskRunner,
                      base::ThreadTaskRunnerHandle::Get(),
-                     component.crx_component_.pk_hash, component.crx_path_,
-                     component.next_fp_, component.crx_component_.installer,
+                     component.crx_component()->pk_hash, component.crx_path_,
+                     component.next_fp_, component.crx_component()->installer,
                      std::move(connector),
                      base::BindOnce(&Component::StateUpdating::InstallComplete,
                                     base::Unretained(this))));
@@ -737,8 +754,10 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto& component = State::component();
-  component.crx_component_.version = component.next_version_;
-  component.crx_component_.fingerprint = component.next_fp_;
+  DCHECK(component.crx_component());
+
+  component.crx_component_->version = component.next_version_;
+  component.crx_component_->fingerprint = component.next_fp_;
 
   component.AppendEvent(BuildUpdateCompleteEventElement(component));
 
@@ -759,6 +778,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   auto& component = State::component();
+  DCHECK(component.crx_component());
+
   component.AppendEvent(BuildUninstalledEventElement(component));
 
   EndState();
@@ -775,6 +796,8 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   const auto& component = State::component();
+  DCHECK(component.crx_component());
+
   action_runner_ = std::make_unique<ActionRunner>(component);
   action_runner_->Run(
       base::BindOnce(&StateRun::ActionRunComplete, base::Unretained(this)));
diff --git a/components/update_client/component.h b/components/update_client/component.h
index ff52638..0e357fb15 100644
--- a/components/update_client/component.h
+++ b/components/update_client/component.h
@@ -72,9 +72,9 @@
 
   std::string id() const { return id_; }
 
-  const CrxComponent& crx_component() const { return crx_component_; }
-  void set_crx_component(const CrxComponent& crx_component) {
-    crx_component_ = crx_component;
+  const CrxComponent* crx_component() const { return crx_component_.get(); }
+  void set_crx_component(std::unique_ptr<CrxComponent> crx_component) {
+    crx_component_ = std::move(crx_component);
   }
 
   const base::Version& previous_version() const { return previous_version_; }
@@ -369,7 +369,7 @@
   base::ThreadChecker thread_checker_;
 
   const std::string id_;
-  CrxComponent crx_component_;
+  std::unique_ptr<CrxComponent> crx_component_;
 
   // The status of the updatecheck response.
   std::string status_;
diff --git a/components/update_client/ping_manager.cc b/components/update_client/ping_manager.cc
index 7ec516eb..f9b885b4 100644
--- a/components/update_client/ping_manager.cc
+++ b/components/update_client/ping_manager.cc
@@ -70,8 +70,10 @@
     return;
   }
 
+  DCHECK(component.crx_component());
+
   auto urls(config_->PingUrl());
-  if (component.crx_component().requires_network_encryption)
+  if (component.crx_component()->requires_network_encryption)
     RemoveUnsecureUrls(&urls);
 
   if (urls.empty()) {
diff --git a/components/update_client/ping_manager_unittest.cc b/components/update_client/ping_manager_unittest.cc
index 7f945bc..e704457 100644
--- a/components/update_client/ping_manager_unittest.cc
+++ b/components/update_client/ping_manager_unittest.cc
@@ -114,7 +114,7 @@
 
   {
     Component component(*update_context, "abc");
-
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.state_ = std::make_unique<Component::StateUpdated>(&component);
     component.previous_version_ = base::Version("1.0");
     component.next_version_ = base::Version("2.0");
@@ -147,6 +147,7 @@
   {
     // Test eventresult="0" is sent for failed updates.
     Component component(*update_context, "abc");
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -170,6 +171,7 @@
   {
     // Test the error values and the fingerprints.
     Component component(*update_context, "abc");
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -206,6 +208,7 @@
   {
     // Test an invalid |next_version| is not serialized.
     Component component(*update_context, "abc");
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -229,6 +232,7 @@
     // Test a valid |previouversion| and |next_version| = base::Version("0")
     // are serialized correctly under <event...> for uninstall.
     Component component(*update_context, "abc");
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.Uninstall(base::Version("1.2.3.4"), 0);
     component.AppendEvent(BuildUninstalledEventElement(component));
 
@@ -249,6 +253,7 @@
   {
     // Test the download metrics.
     Component component(*update_context, "abc");
+    component.crx_component_ = std::make_unique<CrxComponent>();
     component.state_ = std::make_unique<Component::StateUpdated>(&component);
     component.previous_version_ = base::Version("1.0");
     component.next_version_ = base::Version("2.0");
@@ -306,9 +311,10 @@
   const auto update_context = MakeMockUpdateContext();
 
   Component component(*update_context, "abc");
+  component.crx_component_ = std::make_unique<CrxComponent>();
 
   // The default value for |requires_network_encryption| is true.
-  EXPECT_TRUE(component.crx_component_.requires_network_encryption);
+  EXPECT_TRUE(component.crx_component_->requires_network_encryption);
 
   component.state_ = std::make_unique<Component::StateUpdated>(&component);
   component.previous_version_ = base::Version("1.0");
diff --git a/components/update_client/protocol_builder.cc b/components/update_client/protocol_builder.cc
index e49737c8..3119038 100644
--- a/components/update_client/protocol_builder.cc
+++ b/components/update_client/protocol_builder.cc
@@ -334,25 +334,27 @@
   for (const auto& id : ids_checked) {
     DCHECK_EQ(1u, components.count(id));
     const auto& component = *components.at(id);
-    const auto& crx_component = component.crx_component();
     const auto& component_id = component.id();
+    const auto* crx_component = component.crx_component();
+
+    DCHECK(crx_component);
 
     const update_client::InstallerAttributes installer_attributes(
-        SanitizeInstallerAttributes(crx_component.installer_attributes));
+        SanitizeInstallerAttributes(crx_component->installer_attributes));
     std::string app("<app ");
     base::StringAppendF(&app, "appid=\"%s\" version=\"%s\"",
                         component_id.c_str(),
-                        crx_component.version.GetString().c_str());
+                        crx_component->version.GetString().c_str());
     if (!brand.empty())
       base::StringAppendF(&app, " brand=\"%s\"", brand.c_str());
-    if (!crx_component.install_source.empty())
+    if (!crx_component->install_source.empty())
       base::StringAppendF(&app, " installsource=\"%s\"",
-                          crx_component.install_source.c_str());
+                          crx_component->install_source.c_str());
     else if (component.is_foreground())
       base::StringAppendF(&app, " installsource=\"ondemand\"");
-    if (!crx_component.install_location.empty())
+    if (!crx_component->install_location.empty())
       base::StringAppendF(&app, " installedby=\"%s\"",
-                          crx_component.install_location.c_str());
+                          crx_component->install_location.c_str());
     for (const auto& attr : installer_attributes) {
       base::StringAppendF(&app, " %s=\"%s\"", attr.first.c_str(),
                           attr.second.c_str());
@@ -360,7 +362,7 @@
     const auto& cohort = metadata->GetCohort(component_id);
     const auto& cohort_name = metadata->GetCohortName(component_id);
     const auto& cohort_hint = metadata->GetCohortHint(component_id);
-    const auto& disabled_reasons = crx_component.disabled_reasons;
+    const auto& disabled_reasons = crx_component->disabled_reasons;
     if (!cohort.empty())
       base::StringAppendF(&app, " cohort=\"%s\"", cohort.c_str());
     if (!cohort_name.empty())
@@ -374,7 +376,7 @@
       base::StringAppendF(&app, "<disabled reason=\"%d\"/>", disabled_reason);
 
     base::StringAppendF(&app, "<updatecheck");
-    if (crx_component.supports_group_policy_enable_component_updates &&
+    if (crx_component->supports_group_policy_enable_component_updates &&
         !enabled_component_updates) {
       base::StringAppendF(&app, " updatedisabled=\"true\"");
     }
@@ -402,12 +404,12 @@
     base::StringAppendF(&app, " ping_freshness=\"%s\"/>",
                         metadata->GetPingFreshness(component_id).c_str());
 
-    if (!crx_component.fingerprint.empty()) {
+    if (!crx_component->fingerprint.empty()) {
       base::StringAppendF(&app,
                           "<packages>"
                           "<package fp=\"%s\"/>"
                           "</packages>",
-                          crx_component.fingerprint.c_str());
+                          crx_component->fingerprint.c_str());
     }
     base::StringAppendF(&app, "</app>");
     app_elements.append(app);
diff --git a/components/update_client/update_checker.cc b/components/update_client/update_checker.cc
index d63f0eb1..1fb0479 100644
--- a/components/update_client/update_checker.cc
+++ b/components/update_client/update_checker.cc
@@ -41,7 +41,8 @@
 bool IsEncryptionRequired(const IdToComponentPtrMap& components) {
   for (const auto& item : components) {
     const auto& component = item.second;
-    if (component->crx_component().requires_network_encryption)
+    if (component->crx_component() &&
+        component->crx_component()->requires_network_encryption)
       return true;
   }
   return false;
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc
index b7ddb0f..6c1eb25d 100644
--- a/components/update_client/update_checker_unittest.cc
+++ b/components/update_client/update_checker_unittest.cc
@@ -212,16 +212,17 @@
 }
 
 std::unique_ptr<Component> UpdateCheckerTest::MakeComponent() const {
-  CrxComponent crx_component;
-  crx_component.name = "test_jebg";
-  crx_component.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-  crx_component.installer = nullptr;
-  crx_component.version = base::Version("0.9");
-  crx_component.fingerprint = "fp1";
+  std::unique_ptr<CrxComponent> crx_component =
+      std::make_unique<CrxComponent>();
+  crx_component->name = "test_jebg";
+  crx_component->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+  crx_component->installer = nullptr;
+  crx_component->version = base::Version("0.9");
+  crx_component->fingerprint = "fp1";
 
   auto component = std::make_unique<Component>(*update_context_, kUpdateItemId);
   component->state_ = std::make_unique<Component::StateNew>(component.get());
-  component->crx_component_ = crx_component;
+  component->crx_component_ = std::move(crx_component);
 
   return component;
 }
@@ -239,11 +240,11 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  component->crx_component_.installer_attributes["ap"] = "some_ap";
+  component->crx_component_->installer_attributes["ap"] = "some_ap";
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -323,11 +324,10 @@
 
   // Make "ap" too long.
   auto& component = components[kUpdateItemId];
-  component->crx_component_.installer_attributes["ap"] = std::string(257, 'a');
+  component->crx_component_->installer_attributes["ap"] = std::string(257, 'a');
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
 
@@ -355,8 +355,7 @@
   components[kUpdateItemId] = MakeComponent();
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
 
@@ -386,8 +385,7 @@
   auto& component = components[kUpdateItemId];
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -414,8 +412,8 @@
   components[kUpdateItemId] = MakeComponent();
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
 
@@ -443,8 +441,7 @@
   const auto& component = components[kUpdateItemId];
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
 
@@ -481,11 +478,10 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  component->crx_component_.requires_network_encryption = true;
+  component->crx_component_->requires_network_encryption = true;
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -512,16 +508,16 @@
   // Do two update-checks.
   activity_data_service_->SetDaysSinceLastRollCall(kUpdateItemId, 5);
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
 
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -555,8 +551,8 @@
   activity_data_service_->SetActiveBit(kUpdateItemId, true);
   activity_data_service_->SetDaysSinceLastActive(kUpdateItemId, 10);
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -567,8 +563,8 @@
   activity_data_service_->SetActiveBit(kUpdateItemId, true);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -578,8 +574,8 @@
 
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "extra=\"params\"", true,
+      update_context_->session_id, {kUpdateItemId}, components,
+      "extra=\"params\"", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -606,14 +602,13 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  auto& crx_component = const_cast<CrxComponent&>(component->crx_component());
+  auto* crx_component = const_cast<CrxComponent*>(component->crx_component());
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -626,8 +621,7 @@
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -637,14 +631,13 @@
   EXPECT_THAT(body1, testing::Not(testing::HasSubstr(R"(installedby=)")));
 
   update_context_->is_foreground = false;
-  crx_component.install_source = "webstore";
-  crx_component.install_location = "external";
+  crx_component->install_source = "webstore";
+  crx_component->install_location = "external";
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -654,14 +647,13 @@
   EXPECT_THAT(body2, testing::HasSubstr(R"(installedby="external")"));
 
   update_context_->is_foreground = true;
-  crx_component.install_source = "sideload";
-  crx_component.install_location = "policy";
+  crx_component->install_source = "sideload";
+  crx_component->install_location = "policy";
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -678,14 +670,13 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  auto& crx_component = const_cast<CrxComponent&>(component->crx_component());
+  auto* crx_component = const_cast<CrxComponent*>(component->crx_component());
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -694,14 +685,13 @@
   EXPECT_THAT(body0, testing::HasSubstr(R"(enabled="1")"));
   EXPECT_THAT(body0, testing::Not(testing::HasSubstr("<disabled")));
 
-  crx_component.disabled_reasons = std::vector<int>();
+  crx_component->disabled_reasons = {};
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -710,13 +700,12 @@
   EXPECT_THAT(body1, testing::HasSubstr(R"(enabled="1")"));
   EXPECT_THAT(body1, testing::Not(testing::HasSubstr("<disabled")));
 
-  crx_component.disabled_reasons = std::vector<int>({0});
+  crx_component->disabled_reasons = {0};
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -725,14 +714,13 @@
   EXPECT_THAT(body2, testing::HasSubstr(R"(enabled="0")"));
   EXPECT_THAT(body2, testing::HasSubstr(R"(<disabled reason="0")"));
 
-  crx_component.disabled_reasons = std::vector<int>({1});
+  crx_component->disabled_reasons = {1};
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -741,14 +729,13 @@
   EXPECT_THAT(body3, testing::HasSubstr(R"(enabled="0")"));
   EXPECT_THAT(body3, testing::HasSubstr(R"(<disabled reason="1")"));
 
-  crx_component.disabled_reasons = std::vector<int>({4, 8, 16});
+  crx_component->disabled_reasons = {4, 8, 16};
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -759,14 +746,13 @@
   EXPECT_THAT(body4, testing::HasSubstr(R"(<disabled reason="8")"));
   EXPECT_THAT(body4, testing::HasSubstr(R"(<disabled reason="16")"));
 
-  crx_component.disabled_reasons = std::vector<int>({0, 4, 8, 16});
+  crx_component->disabled_reasons = {0, 4, 8, 16};
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -793,15 +779,14 @@
   //  * the component updates are disabled.
   // Expects the group policy to be ignored and the update check to not
   // include the "updatedisabled" attribute.
-  EXPECT_FALSE(
-      component->crx_component_.supports_group_policy_enable_component_updates);
+  EXPECT_FALSE(component->crx_component_
+                   ->supports_group_policy_enable_component_updates);
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -814,15 +799,14 @@
   //  * the component supports group policies.
   //  * the component updates are disabled.
   // Expects the update check to include the "updatedisabled" attribute.
-  component->crx_component_.supports_group_policy_enable_component_updates =
+  component->crx_component_->supports_group_policy_enable_component_updates =
       true;
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", false,
+      update_context_->session_id, {kUpdateItemId}, components, "", false,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -836,15 +820,14 @@
   //  * the component does not support group policies.
   //  * the component updates are enabled.
   // Expects the update check to not include the "updatedisabled" attribute.
-  component->crx_component_.supports_group_policy_enable_component_updates =
+  component->crx_component_->supports_group_policy_enable_component_updates =
       false;
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -857,15 +840,14 @@
   //  * the component supports group policies.
   //  * the component updates are enabled.
   // Expects the update check to not include the "updatedisabled" attribute.
-  component->crx_component_.supports_group_policy_enable_component_updates =
+  component->crx_component_->supports_group_policy_enable_component_updates =
       true;
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -888,8 +870,7 @@
   auto& component = components[kUpdateItemId];
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -920,8 +901,7 @@
   components[kUpdateItemId] = MakeComponent();
 
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   RunThreads();
@@ -955,8 +935,7 @@
 
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   update_checker_->CheckForUpdates(
-      update_context_->session_id, std::vector<std::string>{kUpdateItemId},
-      components, "", true,
+      update_context_->session_id, {kUpdateItemId}, components, "", true,
       base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                      base::Unretained(this)));
   runloop.Run();
diff --git a/components/update_client/update_client.h b/components/update_client/update_client.h
index d2ec6e0e..d8d546a1 100644
--- a/components/update_client/update_client.h
+++ b/components/update_client/update_client.h
@@ -275,8 +275,8 @@
 class UpdateClient : public base::RefCounted<UpdateClient> {
  public:
   using CrxDataCallback =
-      base::OnceCallback<void(const std::vector<std::string>& ids,
-                              std::vector<CrxComponent>* components)>;
+      base::OnceCallback<std::vector<std::unique_ptr<CrxComponent>>(
+          const std::vector<std::string>& ids)>;
 
   // Defines an interface to observe the UpdateClient. It provides
   // notifications when state changes occur for the service itself or for the
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc
index 4b9c0b1f..c051f43b 100644
--- a/components/update_client/update_client_unittest.cc
+++ b/components/update_client/update_client_unittest.cc
@@ -213,14 +213,16 @@
 TEST_F(UpdateClientTest, OneCrxNoUpdate) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.9");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
-      components->push_back(crx);
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.9");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -319,22 +321,24 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx1;
-      crx1.name = "test_jebg";
-      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx1.version = base::Version("0.9");
-      crx1.installer = base::MakeRefCounted<TestInstaller>();
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx1 = std::make_unique<CrxComponent>();
+      crx1->name = "test_jebg";
+      crx1->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx1->version = base::Version("0.9");
+      crx1->installer = base::MakeRefCounted<TestInstaller>();
 
-      CrxComponent crx2;
-      crx2.name = "test_abag";
-      crx2.pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
-      crx2.version = base::Version("2.2");
-      crx2.installer = base::MakeRefCounted<TestInstaller>();
+      std::unique_ptr<CrxComponent> crx2 = std::make_unique<CrxComponent>();
+      crx2->name = "test_abag";
+      crx2->pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
+      crx2->version = base::Version("2.2");
+      crx2->installer = base::MakeRefCounted<TestInstaller>();
 
-      components->push_back(crx1);
-      components->push_back(crx2);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx1));
+      component.push_back(std::move(crx2));
+      return component;
     }
   };
 
@@ -532,22 +536,24 @@
 TEST_F(UpdateClientTest, TwoCrxUpdate) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx1;
-      crx1.name = "test_jebg";
-      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx1.version = base::Version("0.9");
-      crx1.installer = base::MakeRefCounted<TestInstaller>();
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx1 = std::make_unique<CrxComponent>();
+      crx1->name = "test_jebg";
+      crx1->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx1->version = base::Version("0.9");
+      crx1->installer = base::MakeRefCounted<TestInstaller>();
 
-      CrxComponent crx2;
-      crx2.name = "test_ihfo";
-      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
-      crx2.version = base::Version("0.8");
-      crx2.installer = base::MakeRefCounted<TestInstaller>();
+      std::unique_ptr<CrxComponent> crx2 = std::make_unique<CrxComponent>();
+      crx2->name = "test_ihfo";
+      crx2->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
+      crx2->version = base::Version("0.8");
+      crx2->installer = base::MakeRefCounted<TestInstaller>();
 
-      components->push_back(crx1);
-      components->push_back(crx2);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx1));
+      component.push_back(std::move(crx2));
+      return component;
     }
   };
 
@@ -804,22 +810,24 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx1;
-      crx1.name = "test_jebg";
-      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx1.version = base::Version("0.9");
-      crx1.installer = base::MakeRefCounted<TestInstaller>();
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx1 = std::make_unique<CrxComponent>();
+      crx1->name = "test_jebg";
+      crx1->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx1->version = base::Version("0.9");
+      crx1->installer = base::MakeRefCounted<TestInstaller>();
 
-      CrxComponent crx2;
-      crx2.name = "test_ihfo";
-      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
-      crx2.version = base::Version("0.8");
-      crx2.installer = base::MakeRefCounted<TestInstaller>();
+      std::unique_ptr<CrxComponent> crx2 = std::make_unique<CrxComponent>();
+      crx2->name = "test_ihfo";
+      crx2->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
+      crx2->version = base::Version("0.8");
+      crx2->installer = base::MakeRefCounted<TestInstaller>();
 
-      components->push_back(crx1);
-      components->push_back(crx2);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx1));
+      component.push_back(std::move(crx2));
+      return component;
     }
   };
 
@@ -1068,8 +1076,8 @@
 TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
       static int num_calls = 0;
 
       // Must use the same stateful installer object.
@@ -1078,19 +1086,21 @@
 
       ++num_calls;
 
-      CrxComponent crx;
-      crx.name = "test_ihfo";
-      crx.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
-      crx.installer = installer;
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_ihfo";
+      crx->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
+      crx->installer = installer;
       if (num_calls == 1) {
-        crx.version = base::Version("0.8");
+        crx->version = base::Version("0.8");
       } else if (num_calls == 2) {
-        crx.version = base::Version("1.0");
+        crx->version = base::Version("1.0");
       } else {
         NOTREACHED();
       }
 
-      components->push_back(crx);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -1408,8 +1418,8 @@
 
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
       scoped_refptr<MockInstaller> installer =
           base::MakeRefCounted<MockInstaller>();
 
@@ -1418,12 +1428,15 @@
       EXPECT_CALL(*installer, GetInstalledFile(_, _)).Times(0);
       EXPECT_CALL(*installer, Uninstall()).Times(0);
 
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.9");
-      crx.installer = installer;
-      components->push_back(crx);
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.9");
+      crx->installer = installer;
+
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -1593,8 +1606,8 @@
 TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
       static int num_calls = 0;
 
       // Must use the same stateful installer object.
@@ -1603,19 +1616,21 @@
 
       ++num_calls;
 
-      CrxComponent crx;
-      crx.name = "test_ihfo";
-      crx.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
-      crx.installer = installer;
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_ihfo";
+      crx->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
+      crx->installer = installer;
       if (num_calls == 1) {
-        crx.version = base::Version("0.8");
+        crx->version = base::Version("0.8");
       } else if (num_calls == 2) {
-        crx.version = base::Version("1.0");
+        crx->version = base::Version("1.0");
       } else {
         NOTREACHED();
       }
 
-      components->push_back(crx);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -1911,14 +1926,16 @@
 TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.9");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
-      components->push_back(crx);
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.9");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -2028,15 +2045,17 @@
 TEST_F(UpdateClientTest, OneCrxInstall) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.0");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.0");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
 
-      components->push_back(crx);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -2212,15 +2231,16 @@
 TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.0");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
-
-      components->push_back(crx);
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.0");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -2337,8 +2357,10 @@
 TEST_F(UpdateClientTest, EmptyIdList) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {}
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      return {};
+    }
   };
 
   class CompletionCallbackMock {
@@ -2474,14 +2496,16 @@
 TEST_F(UpdateClientTest, RetryAfter) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.9");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
-      components->push_back(crx);
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.9");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -2666,23 +2690,25 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx1;
-      crx1.name = "test_jebg";
-      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx1.version = base::Version("0.9");
-      crx1.installer = base::MakeRefCounted<TestInstaller>();
-      crx1.supports_group_policy_enable_component_updates = true;
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx1 = std::make_unique<CrxComponent>();
+      crx1->name = "test_jebg";
+      crx1->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx1->version = base::Version("0.9");
+      crx1->installer = base::MakeRefCounted<TestInstaller>();
+      crx1->supports_group_policy_enable_component_updates = true;
 
-      CrxComponent crx2;
-      crx2.name = "test_ihfo";
-      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
-      crx2.version = base::Version("0.8");
-      crx2.installer = base::MakeRefCounted<TestInstaller>();
+      std::unique_ptr<CrxComponent> crx2 = std::make_unique<CrxComponent>();
+      crx2->name = "test_ihfo";
+      crx2->pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
+      crx2->version = base::Version("0.8");
+      crx2->installer = base::MakeRefCounted<TestInstaller>();
 
-      components->push_back(crx1);
-      components->push_back(crx2);
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx1));
+      component.push_back(std::move(crx2));
+      return component;
     }
   };
 
@@ -2924,14 +2950,16 @@
 TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
   class DataCallbackMock {
    public:
-    static void Callback(const std::vector<std::string>& ids,
-                         std::vector<CrxComponent>* components) {
-      CrxComponent crx;
-      crx.name = "test_jebg";
-      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
-      crx.version = base::Version("0.9");
-      crx.installer = base::MakeRefCounted<TestInstaller>();
-      components->push_back(crx);
+    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+        const std::vector<std::string>& ids) {
+      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
+      crx->name = "test_jebg";
+      crx->pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
+      crx->version = base::Version("0.9");
+      crx->installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<std::unique_ptr<CrxComponent>> component;
+      component.push_back(std::move(crx));
+      return component;
     }
   };
 
@@ -3170,14 +3198,15 @@
   // The action is a program which returns 1877345072 as a hardcoded value.
   update_client->Install(
       std::string("gjpmebpgbhcamgdgjcmnjfhggjpgcimm"),
-      base::BindOnce([](const std::vector<std::string>& ids,
-                        std::vector<CrxComponent>* components) {
-        CrxComponent crx;
-        crx.name = "test_niea";
-        crx.pk_hash.assign(gjpm_hash, gjpm_hash + arraysize(gjpm_hash));
-        crx.version = base::Version("0.0");
-        crx.installer = base::MakeRefCounted<VersionedTestInstaller>();
-        components->push_back(crx);
+      base::BindOnce([](const std::vector<std::string>& ids) {
+        auto crx = std::make_unique<CrxComponent>();
+        crx->name = "test_niea";
+        crx->pk_hash.assign(gjpm_hash, gjpm_hash + arraysize(gjpm_hash));
+        crx->version = base::Version("0.0");
+        crx->installer = base::MakeRefCounted<VersionedTestInstaller>();
+        std::vector<std::unique_ptr<CrxComponent>> component;
+        component.push_back(std::move(crx));
+        return component;
       }),
       base::BindOnce(
           [](base::OnceClosure quit_closure, Error error) {
@@ -3278,7 +3307,7 @@
     base::OnceClosure quit_closure = runloop.QuitClosure();
 
     auto config = base::MakeRefCounted<TestConfigurator>();
-    scoped_refptr<ComponentUnpacker> component_unpacker = new ComponentUnpacker(
+    auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
         std::vector<uint8_t>(std::begin(gjpm_hash), std::end(gjpm_hash)),
         TestFilePath("runaction_test_win.crx3"), nullptr,
         config->CreateServiceManagerConnector());
@@ -3317,15 +3346,16 @@
       ids,
       base::BindOnce(
           [](const base::FilePath& unpack_path,
-             const std::vector<std::string>& ids,
-             std::vector<CrxComponent>* components) {
-            CrxComponent crx;
-            crx.name = "test_niea";
-            crx.pk_hash.assign(gjpm_hash, gjpm_hash + arraysize(gjpm_hash));
-            crx.version = base::Version("1.0");
-            crx.installer =
+             const std::vector<std::string>& ids) {
+            auto crx = std::make_unique<CrxComponent>();
+            crx->name = "test_niea";
+            crx->pk_hash.assign(gjpm_hash, gjpm_hash + arraysize(gjpm_hash));
+            crx->version = base::Version("1.0");
+            crx->installer =
                 base::MakeRefCounted<ReadOnlyTestInstaller>(unpack_path);
-            components->push_back(crx);
+            std::vector<std::unique_ptr<CrxComponent>> component;
+            component.push_back(std::move(crx));
+            return component;
           },
           unpack_path),
       false,
diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc
index 1f33635..6ab9932 100644
--- a/components/update_client/update_engine.cc
+++ b/components/update_client/update_engine.cc
@@ -99,23 +99,21 @@
   // update context.
   DCHECK_EQ(ids.size(), update_context->ids.size());
   DCHECK_EQ(update_context->ids.size(), update_context->components.size());
-  std::vector<CrxComponent> crx_components;
-  std::move(update_context->crx_data_callback)
-      .Run(update_context->ids, &crx_components);
+  std::vector<std::unique_ptr<CrxComponent>> crx_components =
+      std::move(update_context->crx_data_callback).Run(update_context->ids);
   DCHECK_EQ(update_context->ids.size(), crx_components.size());
 
   for (size_t i = 0; i != update_context->ids.size(); ++i) {
     const auto& id = update_context->ids[i];
-    const auto& crx_component = crx_components[i];
 
-    DCHECK_EQ(id, GetCrxComponentID(crx_component));
+    DCHECK_EQ(id, GetCrxComponentID(*crx_components[i]));
     DCHECK_EQ(1u, update_context->components.count(id));
     DCHECK(update_context->components.at(id));
 
     auto& component = *update_context->components.at(id);
-    component.set_crx_component(crx_component);
-    component.set_previous_version(crx_component.version);
-    component.set_previous_fp(crx_component.fingerprint);
+    component.set_crx_component(std::move(crx_components[i]));
+    component.set_previous_version(component.crx_component()->version);
+    component.set_previous_fp(component.crx_component()->fingerprint);
 
     // Handle |kNew| state. This will transition the components to |kChecking|.
     component.Handle(