Commit 7f12fada authored by Rayan Kanso's avatar Rayan Kanso Committed by Commit Bot

[Background Fetch] Create a Job Controller for active fetches on restart

After a fetch resumes, the Job Controller needs a
BackgroundFetchRequestInfo to update and complete the download.

Change-Id: Id8f8721381049cdf057214f08fa7372b5256c095
Reviewed-on: https://chromium-review.googlesource.com/1155584
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579894}
parent 40443959
......@@ -75,7 +75,7 @@ void BackgroundFetchContext::DidGetInitializationData(
for (auto& data : initialization_data) {
CreateController(data.registration_id, data.registration, data.options,
data.icon, data.ui_title, data.num_completed_requests,
data.num_requests, data.active_fetch_guids);
data.num_requests, std::move(data.active_fetch_requests));
}
}
......@@ -266,7 +266,7 @@ void BackgroundFetchContext::OnRegistrationCreated(
CreateController(registration_id, registration, options, icon, options.title,
0u /* num_completed_requests */, num_requests,
{} /* outstanding_guids */);
{} /* active_fetch_requests */);
}
void BackgroundFetchContext::OnUpdatedUI(
......@@ -300,7 +300,8 @@ void BackgroundFetchContext::CreateController(
const std::string& ui_title,
size_t num_completed_requests,
size_t num_requests,
const std::vector<std::string>& outstanding_guids) {
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto controller = std::make_unique<BackgroundFetchJobController>(
......@@ -314,7 +315,8 @@ void BackgroundFetchContext::CreateController(
base::Bind(&background_fetch::RecordSchedulerFinishedError)));
controller->InitializeRequestStatus(num_completed_requests, num_requests,
outstanding_guids, ui_title);
std::move(active_fetch_requests),
ui_title);
scheduler_->AddJobController(controller.get());
job_controllers_.emplace(registration_id.unique_id(), std::move(controller));
}
......
......@@ -34,6 +34,7 @@ class BackgroundFetchDataManager;
struct BackgroundFetchOptions;
class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier;
class BackgroundFetchRequestInfo;
class BackgroundFetchScheduler;
class BrowserContext;
class CacheStorageContextImpl;
......@@ -158,7 +159,8 @@ class CONTENT_EXPORT BackgroundFetchContext
const std::string& ui_title,
size_t num_completed_requests,
size_t num_requests,
const std::vector<std::string>& outstanding_guids);
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests);
// Called when an existing registration has been retrieved from the data
// manager. If the registration does not exist then |registration| is nullptr.
......
......@@ -1552,7 +1552,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
EXPECT_EQ(init.ui_title, kInitialTitle);
EXPECT_EQ(init.num_requests, requests.size());
EXPECT_EQ(init.num_completed_requests, 0u);
EXPECT_TRUE(init.active_fetch_guids.empty());
EXPECT_TRUE(init.active_fetch_requests.empty());
// Check icon.
ASSERT_FALSE(init.icon.drawsNothing());
......@@ -1574,7 +1574,16 @@ TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
EXPECT_EQ(data[0].num_requests, requests.size());
EXPECT_EQ(data[0].num_completed_requests, 1u);
EXPECT_EQ(data[0].active_fetch_guids.size(), 1u);
ASSERT_EQ(data[0].active_fetch_requests.size(), 1u);
const auto& init_request_info = data[0].active_fetch_requests[0];
ASSERT_TRUE(init_request_info);
EXPECT_EQ(request_info->download_guid(),
init_request_info->download_guid());
EXPECT_EQ(request_info->request_index(),
init_request_info->request_index());
EXPECT_EQ(request_info->fetch_request().Serialize(),
init_request_info->fetch_request().Serialize());
}
// Create another registration.
......
......@@ -241,8 +241,16 @@ void BackgroundFetchDelegateProxy::Core::OnDelegateShutdown() {
}
BackgroundFetchDelegateProxy::JobDetails::JobDetails(
base::WeakPtr<Controller> controller)
: controller(controller) {}
base::WeakPtr<Controller> controller,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests)
: controller(controller) {
for (auto& request_info : active_fetch_requests) {
DCHECK(request_info);
std::string download_guid = request_info->download_guid();
current_request_map[std::move(download_guid)] = std::move(request_info);
}
}
BackgroundFetchDelegateProxy::JobDetails::JobDetails(JobDetails&& details) =
default;
......@@ -283,12 +291,15 @@ void BackgroundFetchDelegateProxy::GetIconDisplaySize(
void BackgroundFetchDelegateProxy::CreateDownloadJob(
base::WeakPtr<Controller> controller,
std::unique_ptr<BackgroundFetchDescription> fetch_description) {
std::unique_ptr<BackgroundFetchDescription> fetch_description,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!job_details_map_.count(fetch_description->job_unique_id));
job_details_map_.emplace(fetch_description->job_unique_id,
JobDetails(controller));
job_details_map_.emplace(
fetch_description->job_unique_id,
JobDetails(controller, std::move(active_fetch_requests)));
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(&Core::CreateDownloadJob, ui_core_ptr_,
......@@ -371,6 +382,7 @@ void BackgroundFetchDelegateProxy::DidStartRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
job_details.current_request_map[guid];
DCHECK(request_info);
DCHECK_EQ(guid, request_info->download_guid());
request_info->PopulateWithResponse(std::move(response));
......@@ -403,6 +415,7 @@ void BackgroundFetchDelegateProxy::OnDownloadUpdated(
if (job_details.controller) {
const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
job_details.current_request_map[guid];
DCHECK(request_info);
DCHECK_EQ(guid, request_info->download_guid());
job_details.controller->DidUpdateRequest(request_info, bytes_downloaded);
}
......@@ -424,6 +437,7 @@ void BackgroundFetchDelegateProxy::OnDownloadComplete(
const scoped_refptr<BackgroundFetchRequestInfo>& request_info =
job_details.current_request_map[guid];
DCHECK(request_info);
DCHECK_EQ(guid, request_info->download_guid());
request_info->SetResult(std::move(result));
......
......@@ -74,11 +74,15 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
// GUIDs of in progress downloads, while completed downloads are recorded in
// |fetch_description.completed_parts|. The size of the completed parts is
// recorded in |fetch_description.completed_parts_size| and total download
// size is stored in |fetch_description.total_parts_size|. Should only be
// called from the Controller (on the IO thread).
// size is stored in |fetch_description.total_parts_size|.
// |active_fetch_requests| contains the BackgroundFetchRequestInfos
// needed to correctly resume an ongoing fetch.
// Should only be called from the Controller (on the IO thread).
void CreateDownloadJob(
base::WeakPtr<Controller> controller,
std::unique_ptr<BackgroundFetchDescription> fetch_description);
std::unique_ptr<BackgroundFetchDescription> fetch_description,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests);
// Requests that the download manager start fetching |request|.
// Should only be called from the Controller (on the IO
......@@ -131,7 +135,9 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
base::WeakPtr<Core> ui_core_ptr_;
struct JobDetails {
explicit JobDetails(base::WeakPtr<Controller> controller);
JobDetails(base::WeakPtr<Controller> controller,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests);
JobDetails(JobDetails&& details);
~JobDetails();
......
......@@ -164,7 +164,8 @@ TEST_F(BackgroundFetchDelegateProxyTest, StartRequest) {
0 /* completed_parts_size */, 0 /* total_parts_size */,
std::vector<std::string>());
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description));
std::move(fetch_description),
{} /* active_fetch_requests */);
delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
base::RunLoop().RunUntilIdle();
......@@ -188,7 +189,8 @@ TEST_F(BackgroundFetchDelegateProxyTest, StartRequest_NotCompleted) {
0 /* completed_parts_size */, 0 /* total_parts_size */,
std::vector<std::string>());
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description));
std::move(fetch_description),
{} /* active_fetch_requests */);
delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
base::RunLoop().RunUntilIdle();
......@@ -216,7 +218,8 @@ TEST_F(BackgroundFetchDelegateProxyTest, Abort) {
0 /* completed_parts_size */, 0 /* total_parts_size */,
std::vector<std::string>());
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description1));
std::move(fetch_description1),
{} /* active_fetch_requests */);
auto fetch_description2 = std::make_unique<BackgroundFetchDescription>(
kExampleUniqueId2, "Job 2", url::Origin(), SkBitmap(),
......@@ -224,7 +227,8 @@ TEST_F(BackgroundFetchDelegateProxyTest, Abort) {
0 /* completed_parts_size */, 0 /* total_parts_size */,
std::vector<std::string>());
delegate_proxy_.CreateDownloadJob(controller2.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description2));
std::move(fetch_description2),
{} /* active_fetch_requests */);
delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
delegate_proxy_.StartRequest(kExampleUniqueId2, url::Origin(), request2);
......@@ -260,7 +264,8 @@ TEST_F(BackgroundFetchDelegateProxyTest, UpdateUI) {
std::vector<std::string>());
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description));
std::move(fetch_description),
{} /* active_fetch_requests */);
delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
base::RunLoop().RunUntilIdle();
......
......@@ -35,7 +35,8 @@ BackgroundFetchJobController::BackgroundFetchJobController(
void BackgroundFetchJobController::InitializeRequestStatus(
int completed_downloads,
int total_downloads,
const std::vector<std::string>& outstanding_guids,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
const std::string& ui_title) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
......@@ -49,14 +50,19 @@ void BackgroundFetchJobController::InitializeRequestStatus(
// TODO(nator): Update this when we support uploads.
int total_downloads_size = options_.download_total;
std::vector<std::string> active_guids;
active_guids.reserve(active_fetch_requests.size());
for (const auto& request_info : active_fetch_requests)
active_guids.push_back(request_info->download_guid());
auto fetch_description = std::make_unique<BackgroundFetchDescription>(
registration_id().unique_id(), ui_title, registration_id().origin(),
icon_, completed_downloads, total_downloads,
complete_requests_downloaded_bytes_cache_, total_downloads_size,
outstanding_guids);
std::move(active_guids));
delegate_proxy_->CreateDownloadJob(GetWeakPtr(),
std::move(fetch_description));
delegate_proxy_->CreateDownloadJob(GetWeakPtr(), std::move(fetch_description),
std::move(active_fetch_requests));
}
BackgroundFetchJobController::~BackgroundFetchJobController() {
......
......@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "content/browser/background_fetch/background_fetch_delegate_proxy.h"
......@@ -65,7 +66,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final
void InitializeRequestStatus(
int completed_downloads,
int total_downloads,
const std::vector<std::string>& outstanding_guids,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
const std::string& ui_title);
// Gets the number of bytes downloaded for jobs that are currently running.
......
......@@ -10,6 +10,7 @@
#include "base/task_scheduler/task_traits.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/background_fetch/storage/image_helpers.h"
#include "content/browser/background_fetch/storage/mark_registration_for_deletion_task.h"
......@@ -233,8 +234,16 @@ class GetRequestsTask : public InitializationSubTask {
return;
}
DCHECK_EQ(sub_task_init().unique_id, active_request.unique_id());
sub_task_init().initialization_data->active_fetch_guids.push_back(
active_request.download_guid());
auto request_info = base::MakeRefCounted<BackgroundFetchRequestInfo>(
active_request.request_index(),
ServiceWorkerFetchRequest::ParseFromString(
active_request.serialized_request()));
request_info->SetDownloadGuid(active_request.download_guid());
sub_task_init().initialization_data->active_fetch_requests.push_back(
std::move(request_info));
pending_requests_to_delete.push_back(PendingRequestKey(
active_request.unique_id(), active_request.request_index()));
}
......
......@@ -10,6 +10,7 @@
#include <vector>
#include "base/callback.h"
#include "base/memory/scoped_refptr.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/storage/database_task.h"
#include "content/browser/service_worker/service_worker_info.h"
......@@ -21,6 +22,8 @@
namespace content {
class BackgroundFetchRequestInfo;
namespace background_fetch {
// All the information needed to create a JobController and resume the fetch
......@@ -36,7 +39,7 @@ struct CONTENT_EXPORT BackgroundFetchInitializationData {
BackgroundFetchRegistration registration;
size_t num_requests;
size_t num_completed_requests;
std::vector<std::string> active_fetch_guids;
std::vector<scoped_refptr<BackgroundFetchRequestInfo>> active_fetch_requests;
std::string ui_title;
// The error, if any, when getting the registration data.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment