[Background Fetch] Get options and title on initialization.

Bug: 853058
Change-Id: Ib5ef98ad0cd988a5ac361b96fa55cebb0e09b800
Reviewed-on: https://chromium-review.googlesource.com/1128863
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Reviewed-by: Peter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#574566}
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index cab30b6..e6ec938 100644
--- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -1365,6 +1365,8 @@
 
   std::vector<ServiceWorkerFetchRequest> requests(2u);
   BackgroundFetchOptions options;
+  options.title = kInitialTitle;
+  options.download_total = 42u;
   blink::mojom::BackgroundFetchError error;
   // Register a Background Fetch.
   BackgroundFetchRegistrationId registration_id(
@@ -1372,6 +1374,8 @@
 
   CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
   ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  UpdateRegistrationUI(registration_id, kUpdatedTitle, &error);
+  ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
   {
     std::vector<BackgroundFetchInitializationData> data =
         GetInitializationData();
@@ -1380,6 +1384,9 @@
     EXPECT_EQ(data[0].registration_id, registration_id);
     EXPECT_EQ(data[0].registration.unique_id, kExampleUniqueId);
     EXPECT_EQ(data[0].registration.developer_id, kExampleDeveloperId);
+    EXPECT_EQ(data[0].options.title, kInitialTitle);
+    EXPECT_EQ(data[0].options.download_total, 42u);
+    EXPECT_EQ(data[0].ui_title, kUpdatedTitle);
     EXPECT_EQ(data[0].num_requests, requests.size());
     EXPECT_EQ(data[0].num_completed_requests, 0u);
     EXPECT_TRUE(data[0].active_fetch_guids.empty());
diff --git a/content/browser/background_fetch/storage/get_initialization_data_task.cc b/content/browser/background_fetch/storage/get_initialization_data_task.cc
index 40f8c65c..40d3975 100644
--- a/content/browser/background_fetch/storage/get_initialization_data_task.cc
+++ b/content/browser/background_fetch/storage/get_initialization_data_task.cc
@@ -5,9 +5,11 @@
 #include "content/browser/background_fetch/storage/get_initialization_data_task.h"
 
 #include "base/barrier_closure.h"
+#include "base/strings/utf_string_conversions.h"
 #include "content/browser/background_fetch/background_fetch.pb.h"
 #include "content/browser/background_fetch/storage/database_helpers.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
 #include "url/origin.h"
 
 namespace content {
@@ -61,6 +63,46 @@
   DISALLOW_COPY_AND_ASSIGN(InitializationSubTask);
 };
 
+// Fills the BackgroundFetchInitializationData with the most recent UI title.
+class GetTitleTask : public InitializationSubTask {
+ public:
+  GetTitleTask(DatabaseTaskHost* host,
+               const SubTaskInit& sub_task_init,
+               base::OnceClosure done_closure)
+      : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+        weak_factory_(this) {}
+
+  ~GetTitleTask() override = default;
+
+  void Start() override {
+    service_worker_context()->GetRegistrationUserData(
+        sub_task_init().service_worker_registration_id,
+        {TitleKey(sub_task_init().unique_id)},
+        base::BindOnce(&GetTitleTask::DidGetTitle, weak_factory_.GetWeakPtr()));
+  }
+
+ private:
+  void DidGetTitle(const std::vector<std::string>& data,
+                   blink::ServiceWorkerStatusCode status) {
+    switch (ToDatabaseStatus(status)) {
+      case DatabaseStatus::kFailed:
+        *sub_task_init().error =
+            blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+        FinishTask();
+        return;
+      case DatabaseStatus::kNotFound:
+      case DatabaseStatus::kOk:
+        break;
+    }
+
+    if (!data.empty())
+      sub_task_init().initialization_data->ui_title = data.front();
+    FinishTask();
+  }
+
+  base::WeakPtrFactory<GetTitleTask> weak_factory_;  // Keep as last.
+};
+
 // Fills the BackgroundFetchInitializationData with the number of completed
 // requests.
 class GetCompletedRequestsTask : public InitializationSubTask {
@@ -76,7 +118,7 @@
   void Start() override {
     service_worker_context()->GetRegistrationUserDataByKeyPrefix(
         sub_task_init().service_worker_registration_id,
-        {CompletedRequestKeyPrefix(sub_task_init().unique_id)},
+        CompletedRequestKeyPrefix(sub_task_init().unique_id),
         base::BindOnce(&GetCompletedRequestsTask::DidGetCompletedRequests,
                        weak_factory_.GetWeakPtr()));
   }
@@ -118,7 +160,7 @@
   void Start() override {
     service_worker_context()->GetRegistrationUserDataByKeyPrefix(
         sub_task_init().service_worker_registration_id,
-        {ActiveRequestKeyPrefix(sub_task_init().unique_id)},
+        ActiveRequestKeyPrefix(sub_task_init().unique_id),
         base::BindOnce(&GetActiveRequestsTask::DidGetActiveRequests,
                        weak_factory_.GetWeakPtr()));
   }
@@ -234,8 +276,34 @@
     // Total number of requests.
     sub_task_init().initialization_data->num_requests = metadata.num_fetches();
 
-    // TODO(rayankans): Fill BackgroundFetchOptions and the icon after it is
-    // persisted.
+    // Fill BackgroundFetchOptions.
+    auto& options = sub_task_init().initialization_data->options;
+    options.title = metadata.options().title();
+    options.download_total = metadata.options().download_total();
+    options.icons.reserve(metadata.options().icons_size());
+    for (const auto& icon : metadata.options().icons()) {
+      blink::Manifest::ImageResource ir;
+      ir.src = GURL(icon.src());
+      ir.type = base::ASCIIToUTF16(icon.type());
+
+      ir.sizes.reserve(icon.sizes_size());
+      for (const auto& size : icon.sizes())
+        ir.sizes.emplace_back(size.width(), size.height());
+
+      ir.purpose.reserve(icon.purpose_size());
+      for (auto purpose : icon.purpose()) {
+        switch (purpose) {
+          case proto::BackgroundFetchOptions_ImageResource_Purpose_ANY:
+            ir.purpose.push_back(blink::Manifest::ImageResource::Purpose::ANY);
+            break;
+          case proto::BackgroundFetchOptions_ImageResource_Purpose_BADGE:
+            ir.purpose.push_back(
+                blink::Manifest::ImageResource::Purpose::BADGE);
+            break;
+        }
+      }
+    }
+
     FinishTask();
   }
 
@@ -257,14 +325,14 @@
   ~FillBackgroundFetchInitializationDataTask() override = default;
 
   void Start() override {
-    // We need 3 queries to get the initialization data. These are wrapped
+    // We need 4 queries to get the initialization data. These are wrapped
     // in a BarrierClosure to avoid querying them serially.
     // 1. Metadata
     // 2. Active Requests
     // 3. Completed Requests
-    // TODO(rayankans): 4. UI Title
+    // 4. UI Title
     base::RepeatingClosure barrier_closure = base::BarrierClosure(
-        3u,
+        4u,
         base::BindOnce(&FillBackgroundFetchInitializationDataTask::FinishTask,
                        weak_factory_.GetWeakPtr()));
     AddSubTask(std::make_unique<FillFromMetadataTask>(this, sub_task_init(),
@@ -273,6 +341,8 @@
                                                           barrier_closure));
     AddSubTask(std::make_unique<GetActiveRequestsTask>(this, sub_task_init(),
                                                        barrier_closure));
+    AddSubTask(
+        std::make_unique<GetTitleTask>(this, sub_task_init(), barrier_closure));
   }
 
  private:
diff --git a/content/browser/background_fetch/storage/get_initialization_data_task.h b/content/browser/background_fetch/storage/get_initialization_data_task.h
index 42c722e..380323e6 100644
--- a/content/browser/background_fetch/storage/get_initialization_data_task.h
+++ b/content/browser/background_fetch/storage/get_initialization_data_task.h
@@ -37,6 +37,9 @@
   size_t num_requests;
   size_t num_completed_requests;
   std::vector<std::string> active_fetch_guids;
+  // The most recent title. This can be different from |options.title| if the
+  // developer called `updateUI` on the BackgroundFetchUpdateEvent.
+  std::string ui_title;
 
   DISALLOW_COPY_AND_ASSIGN(BackgroundFetchInitializationData);
 };