Make CrxComponent an optional member in the CrxUpdateItem.

Since the instance of CrxComponent is provided by the clients of the
update_client::UpdateClient, it is possible that instance is missing in
some cases, such as when a CRX is uninstalled. That leads to corner
cases such as calls to UpdateClient::GetCrxUpdateState returning an
error, because an instance of CrxUpdateItem could not be returned.

This is a mechanical change to replace the std::unique_ptr wrapper of
the CrxComponent with a base::Optional wrapper, so that CrxUpdateItem
could have correct value semantics.

BUG=869663

Change-Id: I6aa805c2784af5ed959c8777f724322763404cb0
Reviewed-on: https://chromium-review.googlesource.com/1173018
Commit-Queue: Sorin Jianu <[email protected]>
Reviewed-by: Tommy Li <[email protected]>
Reviewed-by: Joshua Pawlicki <[email protected]>
Reviewed-by: Minh Nguyen <[email protected]>
Cr-Commit-Position: refs/heads/master@{#583913}
diff --git a/components/component_updater/component_installer_unittest.cc b/components/component_updater/component_installer_unittest.cc
index 03987aa..3bb5d08 100644
--- a/components/component_updater/component_installer_unittest.cc
+++ b/components/component_updater/component_installer_unittest.cc
@@ -311,7 +311,8 @@
 
   CrxUpdateItem item;
   EXPECT_TRUE(component_updater()->GetComponentDetails(id, &item));
-  const CrxComponent& component(item.component);
+  ASSERT_TRUE(item.component);
+  const CrxComponent& component = *item.component;
 
   update_client::InstallerAttributes expected_attrs;
   expected_attrs["ap"] = "fake-ap";
diff --git a/components/component_updater/component_updater_service.cc b/components/component_updater/component_updater_service.cc
index 5833ba3e..2c11f11 100644
--- a/components/component_updater/component_updater_service.cc
+++ b/components/component_updater/component_updater_service.cc
@@ -98,7 +98,6 @@
       base::TimeDelta::FromSeconds(config_->NextCheckDelay()),
       base::Bind(base::IgnoreResult(&CrxUpdateService::CheckForUpdates),
                  base::Unretained(this)),
-      // TODO: Stop component update if requested.
       base::DoNothing());
 }
 
@@ -200,7 +199,7 @@
   const auto it = component_ids_by_mime_type_.find(mime_type);
   if (it == component_ids_by_mime_type_.end())
     return nullptr;
-  auto* const component = GetComponent(it->second);
+  const auto component = GetComponent(it->second);
   if (!component)
     return nullptr;
   return std::make_unique<ComponentInfo>(
@@ -224,11 +223,13 @@
   return *this;
 }
 
-const CrxComponent* CrxUpdateService::GetComponent(
+base::Optional<CrxComponent> CrxUpdateService::GetComponent(
     const std::string& id) const {
   DCHECK(thread_checker_.CalledOnValidThread());
-  const auto it(components_.find(id));
-  return it != components_.end() ? &(it->second) : nullptr;
+  const auto it = components_.find(id);
+  if (it != components_.end())
+    return it->second;
+  return base::nullopt;
 }
 
 const CrxUpdateItem* CrxUpdateService::GetComponentState(
@@ -328,7 +329,7 @@
   for (const auto id : components_order_) {
     DCHECK(components_.find(id) != components_.end());
 
-    auto* component(GetComponent(id));
+    const auto component = GetComponent(id);
     if (!component || component->requires_network_encryption)
       secure_ids.push_back(id);
     else
@@ -392,16 +393,12 @@
   return false;
 }
 
-std::vector<std::unique_ptr<CrxComponent>> CrxUpdateService::GetCrxComponents(
+std::vector<base::Optional<CrxComponent>> CrxUpdateService::GetCrxComponents(
     const std::vector<std::string>& ids) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  std::vector<std::unique_ptr<CrxComponent>> components;
-  for (const auto& id : ids) {
-    const auto* registered_component = GetComponent(id);
-    components.push_back(registered_component ? std::make_unique<CrxComponent>(
-                                                    *registered_component)
-                                              : nullptr);
-  }
+  std::vector<base::Optional<CrxComponent>> components;
+  for (const auto& id : ids)
+    components.push_back(GetComponent(id));
   return components;
 }
 
@@ -420,7 +417,7 @@
 
   for (const auto id : components_pending_unregistration_) {
     if (!update_client_->IsUpdating(id)) {
-      const auto* component = GetComponent(id);
+      const auto component = GetComponent(id);
       if (component)
         DoUnregisterComponent(*component);
     }
@@ -451,16 +448,16 @@
     return;
 
   // Update the state of the item.
-  auto it = component_states_.find(id);
-  DCHECK(it != component_states_.end());
-  it->second = update_item;
+  const auto it = component_states_.find(id);
+  if (it != component_states_.end())
+    it->second = update_item;
 
   // Update the component registration with the new version.
   if (event == Observer::Events::COMPONENT_UPDATED) {
-    auto* component(const_cast<CrxComponent*>(GetComponent(id)));
-    if (component) {
-      component->version = update_item.next_version;
-      component->fingerprint = update_item.next_fp;
+    const auto it = components_.find(id);
+    if (it != components_.end()) {
+      it->second.version = update_item.next_version;
+      it->second.fingerprint = update_item.next_fp;
     }
   }
 }
diff --git a/components/component_updater/component_updater_service_internal.h b/components/component_updater/component_updater_service_internal.h
index 38db35c..341fbf7 100644
--- a/components/component_updater/component_updater_service_internal.h
+++ b/components/component_updater/component_updater_service_internal.h
@@ -12,6 +12,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/optional.h"
 #include "base/threading/thread_checker.h"
 #include "components/component_updater/update_scheduler.h"
 
@@ -77,11 +78,11 @@
 
   bool DoUnregisterComponent(const CrxComponent& component);
 
-  const CrxComponent* GetComponent(const std::string& id) const;
+  base::Optional<CrxComponent> GetComponent(const std::string& id) const;
 
   const CrxUpdateItem* GetComponentState(const std::string& id) const;
 
-  std::vector<std::unique_ptr<CrxComponent>> GetCrxComponents(
+  std::vector<base::Optional<CrxComponent>> GetCrxComponents(
       const std::vector<std::string>& ids);
   void OnUpdateComplete(Callback callback,
                         const base::TimeTicks& start_time,
diff --git a/components/update_client/action_runner.cc b/components/update_client/action_runner.cc
index 7b823bb..3e5a7d5 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 aba3bff..9ca75b69 100644
--- a/components/update_client/component.cc
+++ b/components/update_client/component.cc
@@ -256,7 +256,7 @@
 
   DCHECK_EQ(ComponentState::kNew, state());
 
-  crx_component_ = std::make_unique<CrxComponent>();
+  crx_component_ = CrxComponent();
   crx_component_->version = version;
 
   previous_version_ = version;
diff --git a/components/update_client/component.h b/components/update_client/component.h
index e9adacd7..bb42d07 100644
--- a/components/update_client/component.h
+++ b/components/update_client/component.h
@@ -73,9 +73,11 @@
 
   std::string id() const { return id_; }
 
-  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::Optional<CrxComponent>& crx_component() const {
+    return crx_component_;
+  }
+  void set_crx_component(const CrxComponent& crx_component) {
+    crx_component_ = crx_component;
   }
 
   const base::Version& previous_version() const { return previous_version_; }
@@ -371,7 +373,7 @@
   base::ThreadChecker thread_checker_;
 
   const std::string id_;
-  std::unique_ptr<CrxComponent> crx_component_;
+  base::Optional<CrxComponent> crx_component_;
 
   // The status of the updatecheck response.
   std::string status_;
diff --git a/components/update_client/crx_update_item.h b/components/update_client/crx_update_item.h
index 9fd7398..ac645b5 100644
--- a/components/update_client/crx_update_item.h
+++ b/components/update_client/crx_update_item.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 #include "base/version.h"
 #include "components/update_client/crx_downloader.h"
@@ -27,7 +28,12 @@
   ComponentState state;
 
   std::string id;
-  CrxComponent component;
+
+  // The value of this data member is provided to the |UpdateClient| by the
+  // caller by responding to the |CrxDataCallback|. If the caller can't
+  // provide this value, for instance, in cases where the CRX was uninstalled,
+  // then the |component| member will not be present.
+  base::Optional<CrxComponent> component;
 
   // Time when an update check for this CRX has happened.
   base::TimeTicks last_check;
diff --git a/components/update_client/ping_manager_unittest.cc b/components/update_client/ping_manager_unittest.cc
index 29e5481..3e0b9db9 100644
--- a/components/update_client/ping_manager_unittest.cc
+++ b/components/update_client/ping_manager_unittest.cc
@@ -112,7 +112,7 @@
 
   {
     Component component(*update_context, "abc");
-    component.crx_component_ = std::make_unique<CrxComponent>();
+    component.crx_component_ = CrxComponent();
     component.state_ = std::make_unique<Component::StateUpdated>(&component);
     component.previous_version_ = base::Version("1.0");
     component.next_version_ = base::Version("2.0");
@@ -145,7 +145,7 @@
   {
     // Test eventresult="0" is sent for failed updates.
     Component component(*update_context, "abc");
-    component.crx_component_ = std::make_unique<CrxComponent>();
+    component.crx_component_ = CrxComponent();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -169,7 +169,7 @@
   {
     // Test the error values and the fingerprints.
     Component component(*update_context, "abc");
-    component.crx_component_ = std::make_unique<CrxComponent>();
+    component.crx_component_ = CrxComponent();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -206,7 +206,7 @@
   {
     // Test an invalid |next_version| is not serialized.
     Component component(*update_context, "abc");
-    component.crx_component_ = std::make_unique<CrxComponent>();
+    component.crx_component_ = CrxComponent();
     component.state_ =
         std::make_unique<Component::StateUpdateError>(&component);
     component.previous_version_ = base::Version("1.0");
@@ -230,7 +230,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.crx_component_ = CrxComponent();
     component.Uninstall(base::Version("1.2.3.4"), 0);
     component.AppendEvent(BuildUninstalledEventElement(component));
 
@@ -251,7 +251,7 @@
   {
     // Test the download metrics.
     Component component(*update_context, "abc");
-    component.crx_component_ = std::make_unique<CrxComponent>();
+    component.crx_component_ = CrxComponent();
     component.state_ = std::make_unique<Component::StateUpdated>(&component);
     component.previous_version_ = base::Version("1.0");
     component.next_version_ = base::Version("2.0");
@@ -309,7 +309,7 @@
   const auto update_context = MakeMockUpdateContext();
 
   Component component(*update_context, "abc");
-  component.crx_component_ = std::make_unique<CrxComponent>();
+  component.crx_component_ = CrxComponent();
 
   // The default value for |requires_network_encryption| is true.
   EXPECT_TRUE(component.crx_component_->requires_network_encryption);
diff --git a/components/update_client/protocol_builder.cc b/components/update_client/protocol_builder.cc
index e708c46..54a172e 100644
--- a/components/update_client/protocol_builder.cc
+++ b/components/update_client/protocol_builder.cc
@@ -336,7 +336,7 @@
     DCHECK_EQ(1u, components.count(id));
     const auto& component = *components.at(id);
     const auto& component_id = component.id();
-    const auto* crx_component = component.crx_component();
+    const auto crx_component = component.crx_component();
 
     DCHECK(crx_component);
 
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc
index dd521b3..753d87d 100644
--- a/components/update_client/update_checker_unittest.cc
+++ b/components/update_client/update_checker_unittest.cc
@@ -227,17 +227,16 @@
 }
 
 std::unique_ptr<Component> UpdateCheckerTest::MakeComponent() const {
-  std::unique_ptr<CrxComponent> crx_component =
-      std::make_unique<CrxComponent>();
-  crx_component->name = "test_jebg";
-  crx_component->pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
-  crx_component->installer = nullptr;
-  crx_component->version = base::Version("0.9");
-  crx_component->fingerprint = "fp1";
+  CrxComponent crx_component;
+  crx_component.name = "test_jebg";
+  crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(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_ = std::move(crx_component);
+  component->crx_component_ = crx_component;
 
   return component;
 }
@@ -621,7 +620,7 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  auto* crx_component = const_cast<CrxComponent*>(component->crx_component());
+  auto crx_component = component->crx_component();
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -652,6 +651,7 @@
   update_context_->is_foreground = false;
   crx_component->install_source = "webstore";
   crx_component->install_location = "external";
+  component->set_crx_component(*crx_component);
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
@@ -668,6 +668,7 @@
   update_context_->is_foreground = true;
   crx_component->install_source = "sideload";
   crx_component->install_location = "policy";
+  component->set_crx_component(*crx_component);
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
@@ -689,7 +690,7 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
-  auto* crx_component = const_cast<CrxComponent*>(component->crx_component());
+  auto crx_component = component->crx_component();
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -705,6 +706,7 @@
   EXPECT_THAT(body0, testing::Not(testing::HasSubstr("<disabled")));
 
   crx_component->disabled_reasons = {};
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -720,6 +722,7 @@
   EXPECT_THAT(body1, testing::Not(testing::HasSubstr("<disabled")));
 
   crx_component->disabled_reasons = {0};
+  component->set_crx_component(*crx_component);
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
       test_file("updatecheck_reply_1.xml")));
@@ -734,6 +737,7 @@
   EXPECT_THAT(body2, testing::HasSubstr(R"(<disabled reason="0")"));
 
   crx_component->disabled_reasons = {1};
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -749,6 +753,7 @@
   EXPECT_THAT(body3, testing::HasSubstr(R"(<disabled reason="1")"));
 
   crx_component->disabled_reasons = {4, 8, 16};
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -766,6 +771,7 @@
   EXPECT_THAT(body4, testing::HasSubstr(R"(<disabled reason="16")"));
 
   crx_component->disabled_reasons = {0, 4, 8, 16};
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -792,14 +798,14 @@
   components[kUpdateItemId] = MakeComponent();
 
   auto& component = components[kUpdateItemId];
+  auto crx_component = component->crx_component();
 
   // Tests the scenario where:
   //  * the component does not support group policies.
   //  * 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(crx_component->supports_group_policy_enable_component_updates);
 
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -818,8 +824,8 @@
   //  * 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 =
-      true;
+  crx_component->supports_group_policy_enable_component_updates = true;
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -839,8 +845,8 @@
   //  * 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 =
-      false;
+  crx_component->supports_group_policy_enable_component_updates = false;
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
@@ -859,8 +865,8 @@
   //  * 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 =
-      true;
+  crx_component->supports_group_policy_enable_component_updates = true;
+  component->set_crx_component(*crx_component);
   update_checker_ = UpdateChecker::Create(config_, metadata_.get());
   EXPECT_TRUE(post_interceptor_->ExpectRequest(
       std::make_unique<PartialMatch>("updatecheck"),
diff --git a/components/update_client/update_client.cc b/components/update_client/update_client.cc
index 561bbcf9..ea69825 100644
--- a/components/update_client/update_client.cc
+++ b/components/update_client/update_client.cc
@@ -37,21 +37,15 @@
 namespace update_client {
 
 CrxUpdateItem::CrxUpdateItem() : state(ComponentState::kNew) {}
-
-CrxUpdateItem::~CrxUpdateItem() {
-}
-
+CrxUpdateItem::~CrxUpdateItem() = default;
 CrxUpdateItem::CrxUpdateItem(const CrxUpdateItem& other) = default;
 
 CrxComponent::CrxComponent()
     : allows_background_download(true),
       requires_network_encryption(true),
       supports_group_policy_enable_component_updates(false) {}
-
 CrxComponent::CrxComponent(const CrxComponent& other) = default;
-
-CrxComponent::~CrxComponent() {
-}
+CrxComponent::~CrxComponent() = default;
 
 // It is important that an instance of the UpdateClient binds an unretained
 // pointer to itself. Otherwise, a life time circular dependency between this
diff --git a/components/update_client/update_client.h b/components/update_client/update_client.h
index d8d546a1..0577a15 100644
--- a/components/update_client/update_client.h
+++ b/components/update_client/update_client.h
@@ -8,12 +8,12 @@
 #include <stdint.h>
 
 #include <map>
-#include <memory>
 #include <string>
 #include <vector>
 
 #include "base/callback_forward.h"
 #include "base/memory/ref_counted.h"
+#include "base/optional.h"
 #include "base/version.h"
 #include "components/update_client/update_client_errors.h"
 
@@ -211,7 +211,6 @@
 // may be used in the update checks requests.
 using InstallerAttributes = std::map<std::string, std::string>;
 
-// TODO(sorin): this structure will be refactored soon.
 struct CrxComponent {
   CrxComponent();
   CrxComponent(const CrxComponent& other);
@@ -275,7 +274,7 @@
 class UpdateClient : public base::RefCounted<UpdateClient> {
  public:
   using CrxDataCallback =
-      base::OnceCallback<std::vector<std::unique_ptr<CrxComponent>>(
+      base::OnceCallback<std::vector<base::Optional<CrxComponent>>(
           const std::vector<std::string>& ids)>;
 
   // Defines an interface to observe the UpdateClient. It provides
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc
index 0418cf7..7e652b8 100644
--- a/components/update_client/update_client_unittest.cc
+++ b/components/update_client/update_client_unittest.cc
@@ -215,15 +215,14 @@
 TEST_F(UpdateClientTest, OneCrxNoUpdate) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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));
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.9");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      std::vector<base::Optional<CrxComponent>> component = {crx};
       return component;
     }
   };
@@ -326,24 +325,21 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(jebg_hash));
-      crx1->version = base::Version("0.9");
-      crx1->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx1;
+      crx1.name = "test_jebg";
+      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx1.version = base::Version("0.9");
+      crx1.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 + base::size(abag_hash));
-      crx2->version = base::Version("2.2");
-      crx2->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx2;
+      crx2.name = "test_abag";
+      crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
+      crx2.version = base::Version("2.2");
+      crx2.installer = base::MakeRefCounted<TestInstaller>();
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx1));
-      component.push_back(std::move(crx2));
-      return component;
+      return {crx1, crx2};
     }
   };
 
@@ -545,24 +541,21 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateFirstServerIgnoresSecond) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(jebg_hash));
-      crx1->version = base::Version("0.9");
-      crx1->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx1;
+      crx1.name = "test_jebg";
+      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx1.version = base::Version("0.9");
+      crx1.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 + base::size(abag_hash));
-      crx2->version = base::Version("2.2");
-      crx2->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx2;
+      crx2.name = "test_abag";
+      crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
+      crx2.version = base::Version("2.2");
+      crx2.installer = base::MakeRefCounted<TestInstaller>();
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx1));
-      component.push_back(std::move(crx2));
-      return component;
+      return {crx1, crx2};
     }
   };
 
@@ -734,7 +727,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(5, static_cast<int>(item.error_category));
           EXPECT_EQ(-10004, item.error_code);
@@ -763,18 +756,14 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentData) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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));
-      component.push_back(std::move(nullptr));
-      return component;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.9");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx, base::nullopt};
     }
   };
 
@@ -962,12 +951,9 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentDataAtAll) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(nullptr));
-      component.push_back(std::move(nullptr));
-      return component;
+      return {base::nullopt, base::nullopt};
     }
   };
 
@@ -1057,24 +1043,21 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(jebg_hash));
-      crx1->version = base::Version("0.9");
-      crx1->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx1;
+      crx1.name = "test_jebg";
+      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx1.version = base::Version("0.9");
+      crx1.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 + base::size(ihfo_hash));
-      crx2->version = base::Version("0.8");
-      crx2->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx2;
+      crx2.name = "test_ihfo";
+      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
+      crx2.version = base::Version("0.8");
+      crx2.installer = base::MakeRefCounted<TestInstaller>();
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx1));
-      component.push_back(std::move(crx2));
-      return component;
+      return {crx1, crx2};
     }
   };
 
@@ -1287,7 +1270,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(1, static_cast<int>(item.error_category));
           EXPECT_EQ(-118, item.error_code);
@@ -1329,7 +1312,7 @@
 TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
       static int num_calls = 0;
 
@@ -1339,21 +1322,19 @@
 
       ++num_calls;
 
-      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
-      crx->name = "test_ihfo";
-      crx->pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
-      crx->installer = installer;
+      CrxComponent crx;
+      crx.name = "test_ihfo";
+      crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(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();
       }
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx));
-      return component;
+      return {crx};
     }
   };
 
@@ -1668,7 +1649,7 @@
 
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
       scoped_refptr<MockInstaller> installer =
           base::MakeRefCounted<MockInstaller>();
@@ -1678,15 +1659,13 @@
       EXPECT_CALL(*installer, GetInstalledFile(_, _)).Times(0);
       EXPECT_CALL(*installer, Uninstall()).Times(0);
 
-      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
-      crx->name = "test_jebg";
-      crx->pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
-      crx->version = base::Version("0.9");
-      crx->installer = installer;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(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;
+      return {crx};
     }
   };
 
@@ -1856,7 +1835,7 @@
 TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
       static int num_calls = 0;
 
@@ -1866,21 +1845,19 @@
 
       ++num_calls;
 
-      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
-      crx->name = "test_ihfo";
-      crx->pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
-      crx->installer = installer;
+      CrxComponent crx;
+      crx.name = "test_ihfo";
+      crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(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();
       }
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx));
-      return component;
+      return {crx};
     }
   };
 
@@ -2173,16 +2150,14 @@
 TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.9");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx};
     }
   };
 
@@ -2294,17 +2269,14 @@
 TEST_F(UpdateClientTest, OneCrxInstall) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.0");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx};
     }
   };
 
@@ -2482,11 +2454,9 @@
 TEST_F(UpdateClientTest, OneCrxInstallNoCrxComponentData) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(nullptr);
-      return component;
+      return {base::nullopt};
     }
   };
 
@@ -2550,7 +2520,20 @@
   InSequence seq;
   EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                 "jebgalgnebhfojomionfpkfelancnnkf"))
-      .Times(1);
+      .Times(1)
+      .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
+        // Tests that the state of the component when the CrxComponent data
+        // is not provided. In this case, the optional |item.component| instance
+        // is not present.
+        CrxUpdateItem item;
+        EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
+        EXPECT_EQ(ComponentState::kUpdateError, item.state);
+        EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf", item.id.c_str());
+        EXPECT_FALSE(item.component);
+        EXPECT_EQ(ErrorCategory::kService, item.error_category);
+        EXPECT_EQ(static_cast<int>(Error::CRX_NOT_FOUND), item.error_code);
+        EXPECT_EQ(0, item.extra_code1);
+      }));
 
   update_client->AddObserver(&observer);
 
@@ -2568,16 +2551,14 @@
 TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.0");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx};
     }
   };
 
@@ -2695,7 +2676,7 @@
 TEST_F(UpdateClientTest, EmptyIdList) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
       return {};
     }
@@ -2834,16 +2815,14 @@
 TEST_F(UpdateClientTest, RetryAfter) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.9");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx};
     }
   };
 
@@ -3028,25 +3007,22 @@
 TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(jebg_hash));
-      crx1->version = base::Version("0.9");
-      crx1->installer = base::MakeRefCounted<TestInstaller>();
-      crx1->supports_group_policy_enable_component_updates = true;
+      CrxComponent crx1;
+      crx1.name = "test_jebg";
+      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx1.version = base::Version("0.9");
+      crx1.installer = base::MakeRefCounted<TestInstaller>();
+      crx1.supports_group_policy_enable_component_updates = true;
 
-      std::unique_ptr<CrxComponent> crx2 = std::make_unique<CrxComponent>();
-      crx2->name = "test_ihfo";
-      crx2->pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
-      crx2->version = base::Version("0.8");
-      crx2->installer = base::MakeRefCounted<TestInstaller>();
+      CrxComponent crx2;
+      crx2.name = "test_ihfo";
+      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
+      crx2.version = base::Version("0.8");
+      crx2.installer = base::MakeRefCounted<TestInstaller>();
 
-      std::vector<std::unique_ptr<CrxComponent>> component;
-      component.push_back(std::move(crx1));
-      component.push_back(std::move(crx2));
-      return component;
+      return {crx1, crx2};
     }
   };
 
@@ -3286,16 +3262,14 @@
 TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<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 + base::size(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;
+      CrxComponent crx;
+      crx.name = "test_jebg";
+      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+      crx.version = base::Version("0.9");
+      crx.installer = base::MakeRefCounted<TestInstaller>();
+      return {crx};
     }
   };
 
@@ -3372,7 +3346,7 @@
       .Times(1)
       .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
         CrxUpdateItem item;
-        update_client->GetCrxUpdateState(id, &item);
+        EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
         EXPECT_EQ(ComponentState::kUpdateError, item.state);
         EXPECT_EQ(5, static_cast<int>(item.error_category));
         EXPECT_EQ(-1, item.error_code);
@@ -3396,38 +3370,41 @@
 TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
   class DataCallbackMock {
    public:
-    static std::vector<std::unique_ptr<CrxComponent>> Callback(
+    static std::vector<base::Optional<CrxComponent>> Callback(
         const std::vector<std::string>& ids) {
-      std::vector<std::unique_ptr<CrxComponent>> component;
-
-      std::unique_ptr<CrxComponent> crx = std::make_unique<CrxComponent>();
-      crx->name = "test_jebg";
-      crx->pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
-      crx->version = base::Version("0.9");
-      crx->installer = base::MakeRefCounted<TestInstaller>();
-      component.push_back(std::move(crx));
-
-      crx = std::make_unique<CrxComponent>();
-      crx->name = "test_abag";
-      crx->pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
-      crx->version = base::Version("0.1");
-      crx->installer = base::MakeRefCounted<TestInstaller>();
-      component.push_back(std::move(crx));
-
-      crx = std::make_unique<CrxComponent>();
-      crx->name = "test_ihfo";
-      crx->pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
-      crx->version = base::Version("0.2");
-      crx->installer = base::MakeRefCounted<TestInstaller>();
-      component.push_back(std::move(crx));
-
-      crx = std::make_unique<CrxComponent>();
-      crx->name = "test_gjpm";
-      crx->pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
-      crx->version = base::Version("0.3");
-      crx->installer = base::MakeRefCounted<TestInstaller>();
-      component.push_back(std::move(crx));
-
+      std::vector<base::Optional<CrxComponent>> component;
+      {
+        CrxComponent crx;
+        crx.name = "test_jebg";
+        crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
+        crx.version = base::Version("0.9");
+        crx.installer = base::MakeRefCounted<TestInstaller>();
+        component.push_back(crx);
+      }
+      {
+        CrxComponent crx;
+        crx.name = "test_abag";
+        crx.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
+        crx.version = base::Version("0.1");
+        crx.installer = base::MakeRefCounted<TestInstaller>();
+        component.push_back(crx);
+      }
+      {
+        CrxComponent crx;
+        crx.name = "test_ihfo";
+        crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
+        crx.version = base::Version("0.2");
+        crx.installer = base::MakeRefCounted<TestInstaller>();
+        component.push_back(crx);
+      }
+      {
+        CrxComponent crx;
+        crx.name = "test_gjpm";
+        crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
+        crx.version = base::Version("0.3");
+        crx.installer = base::MakeRefCounted<TestInstaller>();
+        component.push_back(crx);
+      }
       return component;
     }
   };
@@ -3520,7 +3497,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(5, static_cast<int>(item.error_category));
           EXPECT_EQ(-10006, item.error_code);  // UNKNOWN_APPPLICATION.
@@ -3537,7 +3514,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(5, static_cast<int>(item.error_category));
           EXPECT_EQ(-10007, item.error_code);  // RESTRICTED_APPLICATION.
@@ -3554,7 +3531,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(5, static_cast<int>(item.error_category));
           EXPECT_EQ(-10008, item.error_code);  // INVALID_APPID.
@@ -3571,7 +3548,7 @@
         .Times(1)
         .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
           CrxUpdateItem item;
-          update_client->GetCrxUpdateState(id, &item);
+          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
           EXPECT_EQ(ComponentState::kUpdateError, item.state);
           EXPECT_EQ(5, static_cast<int>(item.error_category));
           EXPECT_EQ(-10004, item.error_code);  // UPDATE_RESPONSE_NOT_FOUND.
@@ -3742,14 +3719,12 @@
   update_client->Install(
       std::string("gjpmebpgbhcamgdgjcmnjfhggjpgcimm"),
       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 + base::size(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;
+        CrxComponent crx;
+        crx.name = "test_niea";
+        crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
+        crx.version = base::Version("0.0");
+        crx.installer = base::MakeRefCounted<VersionedTestInstaller>();
+        return std::vector<base::Optional<CrxComponent>>{crx};
       }),
       base::BindOnce(
           [](base::OnceClosure quit_closure, Error error) {
@@ -3890,15 +3865,13 @@
       base::BindOnce(
           [](const base::FilePath& unpack_path,
              const std::vector<std::string>& ids) {
-            auto crx = std::make_unique<CrxComponent>();
-            crx->name = "test_niea";
-            crx->pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
-            crx->version = base::Version("1.0");
-            crx->installer =
+            CrxComponent crx;
+            crx.name = "test_niea";
+            crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
+            crx.version = base::Version("1.0");
+            crx.installer =
                 base::MakeRefCounted<ReadOnlyTestInstaller>(unpack_path);
-            std::vector<std::unique_ptr<CrxComponent>> component;
-            component.push_back(std::move(crx));
-            return component;
+            return std::vector<base::Optional<CrxComponent>>{crx};
           },
           unpack_path),
       false,
diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc
index a778b7d9..0e3dd3ff 100644
--- a/components/update_client/update_engine.cc
+++ b/components/update_client/update_engine.cc
@@ -11,6 +11,7 @@
 #include "base/guid.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/optional.h"
 #include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/prefs/pref_service.h"
@@ -103,7 +104,7 @@
 
   // Calls out to get the corresponding CrxComponent data for the CRXs in this
   // update context.
-  std::vector<std::unique_ptr<CrxComponent>> crx_components =
+  const auto crx_components =
       std::move(update_context->crx_data_callback).Run(update_context->ids);
   DCHECK_EQ(update_context->ids.size(), crx_components.size());
 
@@ -112,12 +113,12 @@
 
     DCHECK(update_context->components[id]->state() == ComponentState::kNew);
 
-    auto& crx_component = crx_components[i];
+    const auto crx_component = crx_components[i];
     if (crx_component) {
       // This component can be checked for updates.
       DCHECK_EQ(id, GetCrxComponentID(*crx_component));
       auto& component = update_context->components[id];
-      component->set_crx_component(std::move(crx_component));
+      component->set_crx_component(*crx_component);
       component->set_previous_version(component->crx_component()->version);
       component->set_previous_fp(component->crx_component()->fingerprint);
       update_context->components_to_check_for_updates.push_back(id);
@@ -379,7 +380,7 @@
   for (const auto& context : update_contexts_) {
     const auto& components = context.second->components;
     const auto it = components.find(id);
-    if (it != components.end() && it->second->crx_component()) {
+    if (it != components.end()) {
       *update_item = it->second->GetCrxUpdateItem();
       return true;
     }