Commit 8a0eece2 authored by Rayan Kanso's avatar Rayan Kanso Committed by Commit Bot

[Background Fetch] Handle start-up resumption cases

Update the BackgroundFetchDownloadClient to handle the new
DownloadService contract. The Background Fetch scheduler will attempt to
start all active downloads on start-up. The ones that are actually resuming will
be ignored by the client.

Since the response metadata and the actual response are propagated in
different calls, the response metadata will be propagated twice to
account for restarts. This will be fixed in a follow-up CL where all of the information
associated with the response will be sent once to the Background Fetch scheduler.

Bug: 881314
Change-Id: I4d806c0eec2cb9c35a42da568613fb2d5ede856e
Reviewed-on: https://chromium-review.googlesource.com/1227995Reviewed-by: default avatarMugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Commit-Queue: Rayan Kanso <rayankans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593164}
parent 1dac4a97
...@@ -79,7 +79,6 @@ BackgroundFetchDelegateImpl::JobDetails::JobDetails( ...@@ -79,7 +79,6 @@ BackgroundFetchDelegateImpl::JobDetails::JobDetails(
fetch_description->job_unique_id)), fetch_description->job_unique_id)),
fetch_description(std::move(fetch_description)) { fetch_description(std::move(fetch_description)) {
offline_item.is_off_the_record = is_off_the_record; offline_item.is_off_the_record = is_off_the_record;
current_download_guids = std::move(this->fetch_description->current_guids);
UpdateOfflineItem(); UpdateOfflineItem();
} }
...@@ -213,9 +212,6 @@ void BackgroundFetchDelegateImpl::CreateDownloadJob( ...@@ -213,9 +212,6 @@ void BackgroundFetchDelegateImpl::CreateDownloadJob(
std::unique_ptr<content::BackgroundFetchDescription> fetch_description) { std::unique_ptr<content::BackgroundFetchDescription> fetch_description) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Initialize the download service in case it hasn't been yet.
GetDownloadService();
std::string job_unique_id = fetch_description->job_unique_id; std::string job_unique_id = fetch_description->job_unique_id;
DCHECK(!job_details_map_.count(job_unique_id)); DCHECK(!job_details_map_.count(job_unique_id));
auto emplace_result = job_details_map_.emplace( auto emplace_result = job_details_map_.emplace(
...@@ -224,14 +220,8 @@ void BackgroundFetchDelegateImpl::CreateDownloadJob( ...@@ -224,14 +220,8 @@ void BackgroundFetchDelegateImpl::CreateDownloadJob(
profile_->IsOffTheRecord())); profile_->IsOffTheRecord()));
const JobDetails& details = emplace_result.first->second; const JobDetails& details = emplace_result.first->second;
for (const auto& download_guid : details.current_download_guids) { for (auto* observer : observers_)
DCHECK(!download_job_unique_id_map_.count(download_guid));
download_job_unique_id_map_.emplace(download_guid, job_unique_id);
}
for (auto* observer : observers_) {
observer->OnItemsAdded({details.offline_item}); observer->OnItemsAdded({details.offline_item});
}
} }
void BackgroundFetchDelegateImpl::DownloadUrl( void BackgroundFetchDelegateImpl::DownloadUrl(
...@@ -459,6 +449,9 @@ void BackgroundFetchDelegateImpl::OnDownloadReceived( ...@@ -459,6 +449,9 @@ void BackgroundFetchDelegateImpl::OnDownloadReceived(
case StartResult::ACCEPTED: case StartResult::ACCEPTED:
// Nothing to do. // Nothing to do.
break; break;
case StartResult::UNEXPECTED_GUID:
// The download started in a previous session. Nothing to do.
break;
case StartResult::BACKOFF: case StartResult::BACKOFF:
// TODO(delphick): try again later? // TODO(delphick): try again later?
NOTREACHED(); NOTREACHED();
...@@ -468,10 +461,6 @@ void BackgroundFetchDelegateImpl::OnDownloadReceived( ...@@ -468,10 +461,6 @@ void BackgroundFetchDelegateImpl::OnDownloadReceived(
// DownloadClient. // DownloadClient.
NOTREACHED(); NOTREACHED();
break; break;
case StartResult::UNEXPECTED_GUID:
// TODO(delphick): try again with a different GUID.
NOTREACHED();
break;
case StartResult::CLIENT_CANCELLED: case StartResult::CLIENT_CANCELLED:
// TODO(delphick): do we need to do anything here, since we will have // TODO(delphick): do we need to do anything here, since we will have
// cancelled it? // cancelled it?
...@@ -615,3 +604,31 @@ void BackgroundFetchDelegateImpl::AddObserver(Observer* observer) { ...@@ -615,3 +604,31 @@ void BackgroundFetchDelegateImpl::AddObserver(Observer* observer) {
void BackgroundFetchDelegateImpl::RemoveObserver(Observer* observer) { void BackgroundFetchDelegateImpl::RemoveObserver(Observer* observer) {
observers_.erase(observer); observers_.erase(observer);
} }
bool BackgroundFetchDelegateImpl::IsGuidOutstanding(
const std::string& guid) const {
auto unique_id_it = download_job_unique_id_map_.find(guid);
if (unique_id_it == download_job_unique_id_map_.end())
return false;
auto job_details_it = job_details_map_.find(unique_id_it->second);
if (job_details_it == job_details_map_.end())
return false;
std::vector<std::string>& outstanding_guids =
job_details_it->second.fetch_description->outstanding_guids;
return std::find(outstanding_guids.begin(), outstanding_guids.end(), guid) !=
outstanding_guids.end();
}
std::set<std::string> BackgroundFetchDelegateImpl::TakeOutstandingGuids() {
std::set<std::string> outstanding_guids;
for (auto& job_id_details : job_details_map_) {
std::vector<std::string>& job_outstanding_guids =
job_id_details.second.fetch_description->outstanding_guids;
for (std::string& outstanding_guid : job_outstanding_guids)
outstanding_guids.insert(std::move(outstanding_guid));
job_outstanding_guids.clear();
}
return outstanding_guids;
}
...@@ -108,6 +108,15 @@ class BackgroundFetchDelegateImpl ...@@ -108,6 +108,15 @@ class BackgroundFetchDelegateImpl
void AddObserver(Observer* observer) override; void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override;
// Whether the provided GUID is resuming from the perspective of Background
// Fetch.
bool IsGuidOutstanding(const std::string& guid) const;
// Returns the set of download GUIDs that have started but did not finish
// according to Background Fetch. Clears out all references to outstanding
// GUIDs.
std::set<std::string> TakeOutstandingGuids();
base::WeakPtr<BackgroundFetchDelegateImpl> GetWeakPtr() { base::WeakPtr<BackgroundFetchDelegateImpl> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr(); return weak_ptr_factory_.GetWeakPtr();
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/background_fetch/background_fetch_download_client.h" #include "chrome/browser/background_fetch/background_fetch_download_client.h"
#include <memory> #include <memory>
#include <set>
#include <utility> #include <utility>
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
...@@ -26,17 +27,31 @@ BackgroundFetchDownloadClient::~BackgroundFetchDownloadClient() = default; ...@@ -26,17 +27,31 @@ BackgroundFetchDownloadClient::~BackgroundFetchDownloadClient() = default;
void BackgroundFetchDownloadClient::OnServiceInitialized( void BackgroundFetchDownloadClient::OnServiceInitialized(
bool state_lost, bool state_lost,
const std::vector<download::DownloadMetaData>& downloads) { const std::vector<download::DownloadMetaData>& downloads) {
content::BackgroundFetchDelegate* delegate = std::set<std::string> outstanding_guids =
browser_context_->GetBackgroundFetchDelegate(); GetDelegate()->TakeOutstandingGuids();
for (const auto& download : downloads) {
// TODO(crbug.com/766082): Support incognito mode in if (!outstanding_guids.count(download.guid)) {
// BackgroundFetchDelegateFactory, currently |delegate| will be nullptr in // Background Fetch is not aware of this GUID, so it successfully
// incognito mode. // completed but the information is still around.
if (!delegate) continue;
return; }
if (download.completion_info) {
// The download finished but was not persisted.
OnDownloadSucceeded(download.guid, *download.completion_info);
}
// The download is resuming, and will call the appropriate functions.
}
delegate_ = static_cast<BackgroundFetchDelegateImpl*>(delegate)->GetWeakPtr(); // There is also the case that the Download Service is not aware of the GUID.
DCHECK(delegate_); // i.e. there is a guid in |outstanding_guids| not in |downloads|.
// This can be due to:
// 1. The browser crashing before the download started.
// 2. The download failing before persisting the state.
// 3. The browser was forced to clean-up the the download.
// In either case the download should be allowed to restart, so there is
// nothing to do here.
} }
void BackgroundFetchDownloadClient::OnServiceUnavailable() {} void BackgroundFetchDownloadClient::OnServiceUnavailable() {}
...@@ -46,11 +61,9 @@ BackgroundFetchDownloadClient::OnDownloadStarted( ...@@ -46,11 +61,9 @@ BackgroundFetchDownloadClient::OnDownloadStarted(
const std::string& guid, const std::string& guid,
const std::vector<GURL>& url_chain, const std::vector<GURL>& url_chain,
const scoped_refptr<const net::HttpResponseHeaders>& headers) { const scoped_refptr<const net::HttpResponseHeaders>& headers) {
if (delegate_) { std::unique_ptr<content::BackgroundFetchResponse> response =
std::unique_ptr<content::BackgroundFetchResponse> response = std::make_unique<content::BackgroundFetchResponse>(url_chain, headers);
std::make_unique<content::BackgroundFetchResponse>(url_chain, headers); GetDelegate()->OnDownloadStarted(guid, std::move(response));
delegate_->OnDownloadStarted(guid, std::move(response));
}
// TODO(delphick): validate the chain/headers before returning CONTINUE // TODO(delphick): validate the chain/headers before returning CONTINUE
return download::Client::ShouldDownload::CONTINUE; return download::Client::ShouldDownload::CONTINUE;
...@@ -59,31 +72,34 @@ BackgroundFetchDownloadClient::OnDownloadStarted( ...@@ -59,31 +72,34 @@ BackgroundFetchDownloadClient::OnDownloadStarted(
void BackgroundFetchDownloadClient::OnDownloadUpdated( void BackgroundFetchDownloadClient::OnDownloadUpdated(
const std::string& guid, const std::string& guid,
uint64_t bytes_downloaded) { uint64_t bytes_downloaded) {
if (delegate_) GetDelegate()->OnDownloadUpdated(guid, bytes_downloaded);
delegate_->OnDownloadUpdated(guid, bytes_downloaded);
} }
void BackgroundFetchDownloadClient::OnDownloadFailed( void BackgroundFetchDownloadClient::OnDownloadFailed(
const std::string& guid, const std::string& guid,
const download::CompletionInfo& info, const download::CompletionInfo& info,
download::Client::FailureReason reason) { download::Client::FailureReason reason) {
if (delegate_) GetDelegate()->OnDownloadFailed(guid, reason);
delegate_->OnDownloadFailed(guid, reason);
} }
void BackgroundFetchDownloadClient::OnDownloadSucceeded( void BackgroundFetchDownloadClient::OnDownloadSucceeded(
const std::string& guid, const std::string& guid,
const download::CompletionInfo& info) { const download::CompletionInfo& info) {
if (delegate_) // Pass the response headers and url_chain to the client again, in case
delegate_->OnDownloadSucceeded(guid, info.path, info.blob_handle, // this fetch was restarted and the client has lost this info.
info.bytes_downloaded); // TODO(crbug.com/884672): Move CORS checks to `OnDownloadStarted`,
// and pass all the completion info to the client once.
OnDownloadStarted(guid, info.url_chain, info.response_headers);
GetDelegate()->OnDownloadSucceeded(guid, info.path, info.blob_handle,
info.bytes_downloaded);
} }
bool BackgroundFetchDownloadClient::CanServiceRemoveDownloadedFile( bool BackgroundFetchDownloadClient::CanServiceRemoveDownloadedFile(
const std::string& guid, const std::string& guid,
bool force_delete) { bool force_delete) {
// TODO(delphick): Return false if the background fetch hasn't finished yet // If |force_delete| is true the file will be removed anyway.
return true; // TODO(rayankans): Add UMA to see how often this happens.
return force_delete || GetDelegate()->IsGuidOutstanding(guid);
} }
void BackgroundFetchDownloadClient::GetUploadData( void BackgroundFetchDownloadClient::GetUploadData(
...@@ -92,3 +108,15 @@ void BackgroundFetchDownloadClient::GetUploadData( ...@@ -92,3 +108,15 @@ void BackgroundFetchDownloadClient::GetUploadData(
base::SequencedTaskRunnerHandle::Get()->PostTask( base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), nullptr)); FROM_HERE, base::BindOnce(std::move(callback), nullptr));
} }
BackgroundFetchDelegateImpl* BackgroundFetchDownloadClient::GetDelegate() {
if (delegate_)
return delegate_.get();
content::BackgroundFetchDelegate* delegate =
browser_context_->GetBackgroundFetchDelegate();
delegate_ = static_cast<BackgroundFetchDelegateImpl*>(delegate)->GetWeakPtr();
DCHECK(delegate_);
return delegate_.get();
}
...@@ -26,6 +26,9 @@ class BackgroundFetchDownloadClient : public download::Client { ...@@ -26,6 +26,9 @@ class BackgroundFetchDownloadClient : public download::Client {
~BackgroundFetchDownloadClient() override; ~BackgroundFetchDownloadClient() override;
private: private:
// Lazily initializes and returns |delegate_| as a raw pointer.
BackgroundFetchDelegateImpl* GetDelegate();
// download::Client implementation // download::Client implementation
void OnServiceInitialized( void OnServiceInitialized(
bool state_lost, bool state_lost,
......
...@@ -44,15 +44,13 @@ void BackgroundFetchJobController::InitializeRequestStatus( ...@@ -44,15 +44,13 @@ void BackgroundFetchJobController::InitializeRequestStatus(
DCHECK_GT(total_downloads, 0); DCHECK_GT(total_downloads, 0);
DCHECK_EQ(total_downloads_, 0); DCHECK_EQ(total_downloads_, 0);
outstanding_requests_ = active_fetch_requests;
completed_downloads_ = completed_downloads; completed_downloads_ = completed_downloads;
total_downloads_ = total_downloads; total_downloads_ = total_downloads;
// TODO(nator): Update this when we support uploads. // TODO(nator): Update this when we support uploads.
total_downloads_size_ = options_.download_total; total_downloads_size_ = options_.download_total;
if (!active_fetch_requests.empty())
is_processing_a_request_ = true;
std::vector<std::string> active_guids; std::vector<std::string> active_guids;
active_guids.reserve(active_fetch_requests.size()); active_guids.reserve(active_fetch_requests.size());
for (const auto& request_info : active_fetch_requests) for (const auto& request_info : active_fetch_requests)
...@@ -83,9 +81,7 @@ void BackgroundFetchJobController::StartRequest( ...@@ -83,9 +81,7 @@ void BackgroundFetchJobController::StartRequest(
DCHECK_LT(completed_downloads_, total_downloads_); DCHECK_LT(completed_downloads_, total_downloads_);
DCHECK(request_finished_callback); DCHECK(request_finished_callback);
DCHECK(request); DCHECK(request);
DCHECK(!is_processing_a_request_);
is_processing_a_request_ = true;
active_request_downloaded_bytes_ = 0; active_request_downloaded_bytes_ = 0;
active_request_finished_callback_ = std::move(request_finished_callback); active_request_finished_callback_ = std::move(request_finished_callback);
...@@ -93,15 +89,9 @@ void BackgroundFetchJobController::StartRequest( ...@@ -93,15 +89,9 @@ void BackgroundFetchJobController::StartRequest(
registration_id().origin(), request); registration_id().origin(), request);
} }
bool BackgroundFetchJobController::IsProcessingARequest() { std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
return is_processing_a_request_; BackgroundFetchJobController::TakeOutstandingRequests() {
} return std::move(outstanding_requests_);
void BackgroundFetchJobController::Resume(
RequestFinishedCallback request_finished_callback) {
// At the moment, the Download Service immediately resumes downloading a
// request on startup. Ideally we should be able to control when this happens.
active_request_finished_callback_ = std::move(request_finished_callback);
} }
void BackgroundFetchJobController::DidStartRequest( void BackgroundFetchJobController::DidStartRequest(
...@@ -143,8 +133,6 @@ void BackgroundFetchJobController::DidCompleteRequest( ...@@ -143,8 +133,6 @@ void BackgroundFetchJobController::DidCompleteRequest(
complete_requests_downloaded_bytes_cache_ += request->GetFileSize(); complete_requests_downloaded_bytes_cache_ += request->GetFileSize();
++completed_downloads_; ++completed_downloads_;
is_processing_a_request_ = false;
std::move(active_request_finished_callback_).Run(request); std::move(active_request_finished_callback_).Run(request);
} }
......
...@@ -110,8 +110,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final ...@@ -110,8 +110,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final
bool HasMoreRequests() override; bool HasMoreRequests() override;
void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request,
RequestFinishedCallback request_finished_callback) override; RequestFinishedCallback request_finished_callback) override;
bool IsProcessingARequest() override; std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
void Resume(RequestFinishedCallback request_finished_callback) override; TakeOutstandingRequests() override;
void Abort( void Abort(
blink::mojom::BackgroundFetchFailureReason reason_to_abort) override; blink::mojom::BackgroundFetchFailureReason reason_to_abort) override;
...@@ -122,6 +122,10 @@ class CONTENT_EXPORT BackgroundFetchJobController final ...@@ -122,6 +122,10 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Icon for the represented background fetch registration. // Icon for the represented background fetch registration.
SkBitmap icon_; SkBitmap icon_;
// The list of requests for this fetch that started in a previous session
// and did not finish.
std::vector<scoped_refptr<BackgroundFetchRequestInfo>> outstanding_requests_;
// Number of bytes downloaded for the active request. // Number of bytes downloaded for the active request.
uint64_t active_request_downloaded_bytes_ = 0; uint64_t active_request_downloaded_bytes_ = 0;
...@@ -148,9 +152,6 @@ class CONTENT_EXPORT BackgroundFetchJobController final ...@@ -148,9 +152,6 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Number of the requests that have been completed so far. // Number of the requests that have been completed so far.
int completed_downloads_ = 0; int completed_downloads_ = 0;
// Whether the DownloadService is processing a request.
bool is_processing_a_request_ = false;
// The reason background fetch was aborted. // The reason background fetch was aborted.
blink::mojom::BackgroundFetchFailureReason reason_to_abort_ = blink::mojom::BackgroundFetchFailureReason reason_to_abort_ =
blink::mojom::BackgroundFetchFailureReason::NONE; blink::mojom::BackgroundFetchFailureReason::NONE;
......
...@@ -52,19 +52,26 @@ BackgroundFetchScheduler::~BackgroundFetchScheduler() = default; ...@@ -52,19 +52,26 @@ BackgroundFetchScheduler::~BackgroundFetchScheduler() = default;
void BackgroundFetchScheduler::AddJobController(Controller* controller) { void BackgroundFetchScheduler::AddJobController(Controller* controller) {
DCHECK(controller); DCHECK(controller);
controller_queue_.push_back(controller);
if (controller->IsProcessingARequest()) { std::vector<scoped_refptr<content::BackgroundFetchRequestInfo>>
// There is a resuming download from the previous session, no need to outstanding_requests = controller->TakeOutstandingRequests();
// schedule. // There are active downloads from the previous session.
if (!outstanding_requests.empty()) {
// The current assumption is that there can be at most one active fetch
// at any given time.
DCHECK(!active_controller_); DCHECK(!active_controller_);
DCHECK_EQ(outstanding_requests.size(), 1u);
active_controller_ = controller; active_controller_ = controller;
active_controller_->Resume( for (auto& request_info : outstanding_requests) {
base::BindOnce(&BackgroundFetchScheduler::MarkRequestAsComplete, active_controller_->StartRequest(
weak_ptr_factory_.GetWeakPtr())); std::move(request_info),
return; base::BindOnce(&BackgroundFetchScheduler::MarkRequestAsComplete,
weak_ptr_factory_.GetWeakPtr()));
}
} }
controller_queue_.push_back(controller);
if (!active_controller_) if (!active_controller_)
ScheduleDownload(); ScheduleDownload();
} }
......
...@@ -46,12 +46,10 @@ class CONTENT_EXPORT BackgroundFetchScheduler { ...@@ -46,12 +46,10 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
virtual void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, virtual void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request,
RequestFinishedCallback callback) = 0; RequestFinishedCallback callback) = 0;
// Whether the controller has a request that is being serviced by // Returns a list of requests that started in a previous session and did not
// DownloadService. This can span sessions. // complete. Clears the list of outstanding GUIDs in the controller.
virtual bool IsProcessingARequest() = 0; virtual std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
TakeOutstandingRequests() = 0;
// Resumes a fetch started in a previous session.
virtual void Resume(RequestFinishedCallback request_finished_callback) = 0;
void Finish(blink::mojom::BackgroundFetchFailureReason reason_to_abort); void Finish(blink::mojom::BackgroundFetchFailureReason reason_to_abort);
......
...@@ -55,8 +55,11 @@ class FakeController : public BackgroundFetchScheduler::Controller { ...@@ -55,8 +55,11 @@ class FakeController : public BackgroundFetchScheduler::Controller {
FROM_HERE, {BrowserThread::IO}, FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), std::move(request))); base::BindOnce(std::move(callback), std::move(request)));
} }
bool IsProcessingARequest() override { return false; }
void Resume(RequestFinishedCallback callback) override { NOTREACHED(); } std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
TakeOutstandingRequests() override {
return {};
}
private: private:
int jobs_started_ = 0; int jobs_started_ = 0;
......
...@@ -15,7 +15,7 @@ BackgroundFetchDescription::BackgroundFetchDescription( ...@@ -15,7 +15,7 @@ BackgroundFetchDescription::BackgroundFetchDescription(
int total_parts, int total_parts,
int completed_parts_size, int completed_parts_size,
int total_parts_size, int total_parts_size,
std::vector<std::string> current_guids) std::vector<std::string> outstanding_guids)
: job_unique_id(job_unique_id), : job_unique_id(job_unique_id),
title(title), title(title),
origin(origin), origin(origin),
...@@ -24,7 +24,7 @@ BackgroundFetchDescription::BackgroundFetchDescription( ...@@ -24,7 +24,7 @@ BackgroundFetchDescription::BackgroundFetchDescription(
total_parts(total_parts), total_parts(total_parts),
completed_parts_size(completed_parts_size), completed_parts_size(completed_parts_size),
total_parts_size(total_parts_size), total_parts_size(total_parts_size),
current_guids(std::move(current_guids)) {} outstanding_guids(std::move(outstanding_guids)) {}
BackgroundFetchDescription::~BackgroundFetchDescription() = default; BackgroundFetchDescription::~BackgroundFetchDescription() = default;
......
...@@ -23,7 +23,7 @@ struct CONTENT_EXPORT BackgroundFetchDescription { ...@@ -23,7 +23,7 @@ struct CONTENT_EXPORT BackgroundFetchDescription {
int total_parts, int total_parts,
int completed_parts_size, int completed_parts_size,
int total_parts_size, int total_parts_size,
std::vector<std::string> current_guids); std::vector<std::string> outstanding_guids);
~BackgroundFetchDescription(); ~BackgroundFetchDescription();
const std::string job_unique_id; const std::string job_unique_id;
...@@ -34,7 +34,7 @@ struct CONTENT_EXPORT BackgroundFetchDescription { ...@@ -34,7 +34,7 @@ struct CONTENT_EXPORT BackgroundFetchDescription {
int total_parts; int total_parts;
int completed_parts_size; int completed_parts_size;
int total_parts_size; int total_parts_size;
std::vector<std::string> current_guids; std::vector<std::string> outstanding_guids;
private: private:
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchDescription); DISALLOW_COPY_AND_ASSIGN(BackgroundFetchDescription);
......
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