| Index: content/browser/background_fetch/background_fetch_data_manager.cc
|
| diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc
|
| index b4d60f16581d34766878e12bf532aa8fb0175780..5def082d44ad09db2ad89496d84f98cf182835fb 100644
|
| --- a/content/browser/background_fetch/background_fetch_data_manager.cc
|
| +++ b/content/browser/background_fetch/background_fetch_data_manager.cc
|
| @@ -6,23 +6,27 @@
|
|
|
| #include "base/memory/ptr_util.h"
|
| #include "content/browser/background_fetch/background_fetch_context.h"
|
| +#include "content/browser/background_fetch/background_fetch_job_response_data.h"
|
| #include "content/browser/background_fetch/background_fetch_request_info.h"
|
| +#include "content/public/browser/blob_handle.h"
|
| +#include "content/public/browser/browser_context.h"
|
| +#include "content/public/browser/download_interrupt_reasons.h"
|
| +#include "content/public/browser/download_item.h"
|
|
|
| namespace content {
|
|
|
| BackgroundFetchDataManager::BackgroundFetchDataManager(
|
| - BackgroundFetchContext* background_fetch_context)
|
| - : background_fetch_context_(background_fetch_context) {
|
| - DCHECK(background_fetch_context_);
|
| + BrowserContext* browser_context)
|
| + : browser_context_(browser_context), weak_ptr_factory_(this) {
|
| + DCHECK(browser_context_);
|
| // TODO(harkness) Read from persistent storage and recreate requests.
|
| }
|
|
|
| BackgroundFetchDataManager::~BackgroundFetchDataManager() = default;
|
|
|
| -std::unique_ptr<BackgroundFetchJobData>
|
| -BackgroundFetchDataManager::CreateRequest(
|
| +void BackgroundFetchDataManager::CreateRequest(
|
| std::unique_ptr<BackgroundFetchJobInfo> job_info,
|
| - BackgroundFetchRequestInfos request_infos) {
|
| + std::vector<std::unique_ptr<BackgroundFetchRequestInfo>> request_infos) {
|
| BackgroundFetchRegistrationId registration_id(
|
| job_info->service_worker_registration_id(), job_info->origin(),
|
| job_info->tag());
|
| @@ -34,36 +38,190 @@ BackgroundFetchDataManager::CreateRequest(
|
| << " has already created a batch request with tag "
|
| << job_info->tag();
|
| // TODO(harkness) Figure out how to return errors like this.
|
| - return nullptr;
|
| + return;
|
| }
|
|
|
| - // Add the request to our maps and return a JobData to track the individual
|
| - // files in the request.
|
| + // Add the JobInfo to the in-memory map, and write the individual requests out
|
| + // to storage.
|
| + job_info->set_num_requests(request_infos.size());
|
| const std::string job_guid = job_info->guid();
|
| known_registrations_.insert(std::move(registration_id));
|
| WriteJobToStorage(std::move(job_info), std::move(request_infos));
|
| - // TODO(harkness): Remove data when the job is complete.
|
| -
|
| - return base::MakeUnique<BackgroundFetchJobData>(
|
| - ReadRequestsFromStorage(job_guid));
|
| }
|
|
|
| void BackgroundFetchDataManager::WriteJobToStorage(
|
| std::unique_ptr<BackgroundFetchJobInfo> job_info,
|
| - BackgroundFetchRequestInfos request_infos) {
|
| - // TODO(harkness): Replace these maps with actually writing to storage.
|
| + std::vector<std::unique_ptr<BackgroundFetchRequestInfo>> request_infos) {
|
| // TODO(harkness): Check for job_guid clash.
|
| const std::string job_guid = job_info->guid();
|
| job_map_[job_guid] = std::move(job_info);
|
| - request_map_[job_guid] = std::move(request_infos);
|
| +
|
| + // Make an explicit copy of the original requests
|
| + // TODO(harkness): Replace this with actually writing to storage.
|
| + std::vector<BackgroundFetchRequestInfo> requests;
|
| + for (const auto& request_info : request_infos) {
|
| + requests.emplace_back(*(request_info.get()));
|
| + }
|
| + request_map_[job_guid] = std::move(requests);
|
| +
|
| + // |request_infos| will be destroyed when it leaves scope here.
|
| +}
|
| +
|
| +void BackgroundFetchDataManager::WriteRequestToStorage(
|
| + const std::string& job_guid,
|
| + BackgroundFetchRequestInfo* request_info) {
|
| + std::vector<BackgroundFetchRequestInfo>& request_infos =
|
| + request_map_[job_guid];
|
| +
|
| + // Copy the updated |request_info| over the in-memory version.
|
| + for (size_t i = 0; i < request_infos.size(); i++) {
|
| + if (request_infos[i].guid() == request_info->guid())
|
| + request_infos[i] = *request_info;
|
| + }
|
| +}
|
| +
|
| +std::unique_ptr<BackgroundFetchRequestInfo>
|
| +BackgroundFetchDataManager::GetRequestInfo(const std::string& job_guid,
|
| + size_t request_index) {
|
| + // Explicitly create a copy. When this is persisted to StorageWorkerStorage,
|
| + // the request_map_ will not exist.
|
| + auto iter = request_map_.find(job_guid);
|
| + DCHECK(iter != request_map_.end());
|
| + const std::vector<BackgroundFetchRequestInfo>& request_infos = iter->second;
|
| +
|
| + DCHECK(request_index <= request_infos.size());
|
| + return base::MakeUnique<BackgroundFetchRequestInfo>(
|
| + request_infos[request_index]);
|
| }
|
|
|
| -// TODO(harkness): This should be changed to read (and cache) small numbers of
|
| -// the RequestInfos instead of returning all of them.
|
| -BackgroundFetchRequestInfos&
|
| -BackgroundFetchDataManager::ReadRequestsFromStorage(
|
| +void BackgroundFetchDataManager::GetJobResponse(
|
| + const std::string& job_guid,
|
| + const BackgroundFetchResponseCompleteCallback& callback) {
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| +
|
| + // Create a BackgroundFetchJobResponseData object which will aggregate
|
| + // together the response blobs.
|
| + job_info->set_job_response_data(
|
| + base::MakeUnique<BackgroundFetchJobResponseData>(job_info->num_requests(),
|
| + callback));
|
| +
|
| + // Iterate over the requests and create blobs for each response.
|
| + for (size_t request_index = 0; request_index < job_info->num_requests();
|
| + request_index++) {
|
| + // TODO(harkness): This will need to be asynchronous.
|
| + std::unique_ptr<BackgroundFetchRequestInfo> request_info =
|
| + GetRequestInfo(job_guid, request_index);
|
| +
|
| + // TODO(harkness): Only create a blob response if the request was
|
| + // successful. Otherwise create an error response.
|
| + content::BrowserContext::CreateFileBackedBlob(
|
| + browser_context_, request_info->file_path(), 0 /* offset */,
|
| + request_info->received_bytes(),
|
| + base::Time() /* expected_modification_time */,
|
| + base::Bind(&BackgroundFetchDataManager::DidGetRequestResponse,
|
| + weak_ptr_factory_.GetWeakPtr(), job_guid, request_index));
|
| + }
|
| +}
|
| +
|
| +void BackgroundFetchDataManager::DidGetRequestResponse(
|
| + const std::string& job_guid,
|
| + int request_sequence_number,
|
| + std::unique_ptr<BlobHandle> blob_handle) {
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| +
|
| + BackgroundFetchJobResponseData* job_response_data =
|
| + job_info->job_response_data();
|
| + DCHECK(job_response_data);
|
| +
|
| + job_response_data->AddResponse(request_sequence_number,
|
| + std::move(blob_handle));
|
| +}
|
| +
|
| +bool BackgroundFetchDataManager::UpdateRequestState(
|
| + const std::string& job_guid,
|
| + const std::string& request_guid,
|
| + DownloadItem::DownloadState state,
|
| + DownloadInterruptReason interrupt_reason) {
|
| + // Find the request and set the state and the interrupt reason.
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| + BackgroundFetchRequestInfo* request =
|
| + job_info->GetActiveRequest(request_guid);
|
| + DCHECK(request);
|
| + request->set_state(state);
|
| + request->set_interrupt_reason(interrupt_reason);
|
| +
|
| + // If the request is now finished, remove it from the active requests.
|
| + switch (state) {
|
| + case DownloadItem::DownloadState::COMPLETE:
|
| + case DownloadItem::DownloadState::CANCELLED:
|
| + WriteRequestToStorage(job_guid, request);
|
| + job_info->RemoveActiveRequest(request_guid);
|
| + break;
|
| + case DownloadItem::DownloadState::IN_PROGRESS:
|
| + case DownloadItem::DownloadState::INTERRUPTED:
|
| + case DownloadItem::DownloadState::MAX_DOWNLOAD_STATE:
|
| + break;
|
| + }
|
| +
|
| + // Return a boolean indicating whether there are more requests to be
|
| + // processed.
|
| + return job_info->HasRequestsRemaining();
|
| +}
|
| +
|
| +void BackgroundFetchDataManager::UpdateRequestStorageState(
|
| + const std::string& job_guid,
|
| + const std::string& request_guid,
|
| + const base::FilePath& file_path,
|
| + int64_t received_bytes) {
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| + BackgroundFetchRequestInfo* request =
|
| + job_info->GetActiveRequest(request_guid);
|
| + DCHECK(request);
|
| + request->set_file_path(file_path);
|
| + request->set_received_bytes(received_bytes);
|
| +}
|
| +
|
| +const BackgroundFetchRequestInfo&
|
| +BackgroundFetchDataManager::GetNextBackgroundFetchRequestInfo(
|
| const std::string& job_guid) {
|
| - return request_map_[job_guid];
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| +
|
| + // TODO(harkness): This needs to be async when it queries real storage.
|
| + std::unique_ptr<BackgroundFetchRequestInfo> request_info =
|
| + GetRequestInfo(job_guid, job_info->next_request_index());
|
| + const std::string request_guid = request_info->guid();
|
| + job_info->AddActiveRequest(std::move(request_info));
|
| + return *job_info->GetActiveRequest(request_guid);
|
| +}
|
| +
|
| +bool BackgroundFetchDataManager::IsComplete(const std::string& job_guid) const {
|
| + auto iter = job_map_.find(job_guid);
|
| + DCHECK(iter != job_map_.end());
|
| + return iter->second->IsComplete();
|
| +}
|
| +
|
| +bool BackgroundFetchDataManager::HasRequestsRemaining(
|
| + const std::string& job_guid) const {
|
| + auto iter = job_map_.find(job_guid);
|
| + DCHECK(iter != job_map_.end());
|
| + return iter->second->HasRequestsRemaining();
|
| +}
|
| +
|
| +void BackgroundFetchDataManager::UpdateRequestDownloadGuid(
|
| + const std::string& job_guid,
|
| + const std::string& request_guid,
|
| + const std::string& download_guid) {
|
| + BackgroundFetchJobInfo* job_info = job_map_[job_guid].get();
|
| + DCHECK(job_info);
|
| + BackgroundFetchRequestInfo* request =
|
| + job_info->GetActiveRequest(request_guid);
|
| + DCHECK(request);
|
| + request->set_download_guid(download_guid);
|
| }
|
|
|
| } // namespace content
|
|
|