Commit 9a87f0b8 authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[Background Fetch] Get settled fetches for a specific request.

Two capabilities have been added to the GetSettledFetches task:
1. Support CacheQueryOptions, while fetching responses for completed
fetches from the Cache Storage.
2. Support for filtering responses corresponding to a specific request from
completed fetches.

Both will be useful to support match() and matchAll() methods on
BackgroundFetchSettledEvent.

Bug: 863016
Change-Id: Icababdd71cd1687644cacc9460550de89bdfc4d5
Reviewed-on: https://chromium-review.googlesource.com/1140324Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Reviewed-by: default avatarRayan Kanso <rayankans@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577269}
parent c54b0c34
......@@ -424,6 +424,8 @@ jumbo_source_set("browser") {
"background_fetch/background_fetch_request_info.cc",
"background_fetch/background_fetch_request_info.h",
"background_fetch/background_fetch_request_manager.h",
"background_fetch/background_fetch_request_match_params.cc",
"background_fetch/background_fetch_request_match_params.h",
"background_fetch/background_fetch_scheduler.cc",
"background_fetch/background_fetch_scheduler.h",
"background_fetch/background_fetch_service_impl.cc",
......
......@@ -12,6 +12,7 @@
#include "content/browser/background_fetch/background_fetch_metrics.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_registration_notifier.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/background_fetch/background_fetch_scheduler.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/background_fetch_delegate.h"
......@@ -364,6 +365,7 @@ void BackgroundFetchContext::DidMarkForDeletion(
// This will send a BackgroundFetchFetched or BackgroundFetchFail event.
data_manager_->GetSettledFetchesForRegistration(
registration_id,
std::make_unique<BackgroundFetchRequestMatchParams>(),
base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
weak_factory_.GetWeakPtr(), registration_id));
return;
......
......@@ -213,11 +213,12 @@ void BackgroundFetchDataManager::MarkRequestAsComplete(
void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
const BackgroundFetchRegistrationId& registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
SettledFetchesCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
AddDatabaseTask(std::make_unique<background_fetch::GetSettledFetchesTask>(
this, registration_id, std::move(callback)));
this, registration_id, std::move(match_params), std::move(callback)));
}
void BackgroundFetchDataManager::MarkRegistrationForDeletion(
......
......@@ -36,6 +36,7 @@ namespace content {
class BackgroundFetchDataManagerObserver;
class BackgroundFetchRequestInfo;
class BackgroundFetchRequestMatchParams;
struct BackgroundFetchSettledFetch;
class BrowserContext;
class CacheStorageManager;
......@@ -122,11 +123,13 @@ class CONTENT_EXPORT BackgroundFetchDataManager
const std::string& title,
blink::mojom::BackgroundFetchService::UpdateUICallback callback);
// Reads all settled fetches for the given |registration_id|. Both the Request
// and Response objects will be initialised based on the stored data. Will
// invoke the |callback| when the list of fetches has been compiled.
// Reads the settled fetches for the given |registration_id| based on
// |match_params|. Both the Request and Response objects will be initialised
// based on the stored data. Will invoke the |callback| when the list of
// fetches has been compiled.
void GetSettledFetchesForRegistration(
const BackgroundFetchRegistrationId& registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
SettledFetchesCallback callback);
// Marks that the backgroundfetched/backgroundfetchfail/backgroundfetchabort
......
......@@ -18,6 +18,7 @@
#include "base/strings/string_number_conversions.h"
#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
#include "content/browser/background_fetch/background_fetch_test_data_manager.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
......@@ -26,6 +27,7 @@
#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/skia/include/core/SkBitmap.h"
......@@ -334,6 +336,7 @@ class BackgroundFetchDataManagerTest
// BackgroundFetchDataManager::GetSettledFetchesForRegistration().
void GetSettledFetchesForRegistration(
const BackgroundFetchRegistrationId& registration_id,
base::Optional<ServiceWorkerFetchRequest> request_to_match,
blink::mojom::BackgroundFetchError* out_error,
bool* out_succeeded,
std::vector<BackgroundFetchSettledFetch>* out_settled_fetches) {
......@@ -342,8 +345,10 @@ class BackgroundFetchDataManagerTest
DCHECK(out_settled_fetches);
base::RunLoop run_loop;
auto match_params = std::make_unique<BackgroundFetchRequestMatchParams>(
request_to_match, nullptr /* cache_query_params */);
background_fetch_data_manager_->GetSettledFetchesForRegistration(
registration_id,
registration_id, std::move(match_params),
base::BindOnce(&BackgroundFetchDataManagerTest::
DidGetSettledFetchesForRegistration,
base::Unretained(this), run_loop.QuitClosure(),
......@@ -1091,8 +1096,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
// Nothing is downloaded yet.
bool succeeded = false;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(succeeded);
EXPECT_EQ(settled_fetches.size(), 0u);
......@@ -1112,8 +1118,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
(ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
requests.size() /* completed_requests */}));
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// We are marking the responses as failed in Download Manager.
......@@ -1137,8 +1144,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
bool succeeded = false;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
// Nothing is downloaded yet.
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(succeeded);
EXPECT_EQ(settled_fetches.size(), 0u);
......@@ -1150,8 +1158,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
true /* success */);
MarkRequestAsComplete(registration_id, request_info.get());
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(succeeded);
EXPECT_EQ(settled_fetches.size(), 1u);
......@@ -1162,8 +1171,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
true /* success */);
MarkRequestAsComplete(registration_id, request_info.get());
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(succeeded);
ASSERT_EQ(settled_fetches.size(), 2u);
......@@ -1178,13 +1188,92 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
RestartDataManagerFromPersistentStorage();
GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
&settled_fetches);
GetSettledFetchesForRegistration(registration_id,
base::nullopt /* request_to_match */, &error,
&succeeded, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(succeeded);
EXPECT_EQ(settled_fetches.size(), 2u);
}
TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForASpecificRequest) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
auto requests = CreateValidRequests(origin(), 2u /* num_requests */);
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
BackgroundFetchRegistrationId registration_id(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
for (size_t i = 0; i < requests.size(); i++) {
SCOPED_TRACE(i);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
PopNextRequest(registration_id, &request_info);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
MarkRequestAsComplete(registration_id, request_info.get());
}
EXPECT_EQ(
GetRequestStats(sw_id),
(ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
requests.size() /* completed_requests */}));
bool succeeded = false;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(registration_id,
requests[0] /* request_to_match */, &error,
&succeeded, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// We are marking the responses as failed in Download Manager.
EXPECT_FALSE(succeeded);
EXPECT_EQ(settled_fetches.size(), 1u);
}
TEST_F(BackgroundFetchDataManagerTest,
GetSettledFetchesForANonMatchingRequest) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
auto requests = CreateValidRequests(origin(), 3u /* num_requests */);
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
BackgroundFetchRegistrationId registration_id(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
for (size_t i = 0; i < requests.size() - 1; i++) {
SCOPED_TRACE(i);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
PopNextRequest(registration_id, &request_info);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
MarkRequestAsComplete(registration_id, request_info.get());
}
EXPECT_EQ(
GetRequestStats(sw_id),
(ResponseStateStats{1 /* pending_requests */, 0 /* active_requests */,
requests.size() - 1 /* completed_requests */}));
bool succeeded = false;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(registration_id,
requests[2] /* request_to_match */, &error,
&succeeded, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_EQ(settled_fetches.size(), 1u);
EXPECT_EQ(settled_fetches[0].response.response_type,
network::mojom::FetchResponseType::kError);
}
TEST_F(BackgroundFetchDataManagerTest, Cleanup) {
// Tests that the BackgroundFetchDataManager cleans up registrations
// marked for deletion.
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
namespace content {
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams(
base::Optional<ServiceWorkerFetchRequest> request_to_match,
blink::mojom::QueryParamsPtr cache_query_params)
: request_to_match_(std::move(request_to_match)),
cache_query_params_(std::move(cache_query_params)) {}
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams() =
default;
BackgroundFetchRequestMatchParams::~BackgroundFetchRequestMatchParams() =
default;
} // namespace content
\ No newline at end of file
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MATCH_PARAMS_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MATCH_PARAMS_H_
#include "base/optional.h"
#include "content/common/service_worker/service_worker_types.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
namespace content {
class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
public:
// TODO(crbug.com/863852): Add boolean to differentiate between match vs
// matchAll.
BackgroundFetchRequestMatchParams();
BackgroundFetchRequestMatchParams(
base::Optional<ServiceWorkerFetchRequest> request_to_match,
blink::mojom::QueryParamsPtr cache_query_params);
~BackgroundFetchRequestMatchParams();
bool FilterByRequest() const {
return request_to_match_.has_value();
}
// Only call this method if a valid request_to_match was previously provided.
const ServiceWorkerFetchRequest& request_to_match() const {
DCHECK(request_to_match_.has_value());
return request_to_match_.value();
}
blink::mojom::QueryParamsPtr cloned_cache_query_params() const {
if (!cache_query_params_)
return nullptr;
return cache_query_params_->Clone();
}
private:
// If |request_to_match| is present, we get response(s) only for this request.
// If not present, response(s) for all requests (contained in the fetch) will
// be returned.
base::Optional<ServiceWorkerFetchRequest> request_to_match_;
// When nullptr, this has no effect on the response(s) returned.
blink::mojom::QueryParamsPtr cache_query_params_;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRequestMatchParams);
};
} // namespace content
#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_REQUEST_MATCH_PARAMS_H_
......@@ -17,9 +17,11 @@ namespace background_fetch {
GetSettledFetchesTask::GetSettledFetchesTask(
DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
SettledFetchesCallback callback)
: DatabaseTask(host),
registration_id_(registration_id),
match_params_(std::move(match_params)),
settled_fetches_callback_(std::move(callback)),
weak_factory_(this) {}
......@@ -101,12 +103,39 @@ void GetSettledFetchesTask::GetResponses() {
return;
}
if (match_params_->FilterByRequest()) {
// Get a response only for the relevant fetch.
settled_fetches_.emplace_back();
settled_fetches_.back().request = match_params_->request_to_match();
for (const auto& completed_request : completed_requests_) {
if (completed_request.serialized_request() !=
match_params_->request_to_match().Serialize()) {
continue;
}
// A matching request!
FillResponse(&settled_fetches_.back(),
base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
// TODO(crbug.com/863852): Add support for matchAll();
return;
}
// No matching request found.
FillUncachedResponse(
&settled_fetches_.back(),
base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
return;
}
// Process all completed requests.
base::RepeatingClosure barrier_closure = base::BarrierClosure(
completed_requests_.size(),
base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
settled_fetches_.reserve(completed_requests_.size());
for (const auto& completed_request : completed_requests_) {
settled_fetches_.emplace_back();
......@@ -125,8 +154,8 @@ void GetSettledFetchesTask::FillResponse(
auto request =
std::make_unique<ServiceWorkerFetchRequest>(settled_fetch->request);
handle_.value()->Match(std::move(request), nullptr /* match_params */,
handle_.value()->Match(std::move(request),
match_params_->cloned_cache_query_params(),
base::BindOnce(&GetSettledFetchesTask::DidMatchRequest,
weak_factory_.GetWeakPtr(),
settled_fetch, std::move(callback)));
......@@ -143,6 +172,7 @@ void GetSettledFetchesTask::DidMatchRequest(
return;
}
settled_fetch->response = std::move(*cache_response);
std::move(callback).Run();
}
......
......@@ -8,6 +8,7 @@
#include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/background_fetch/storage/database_task.h"
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "storage/browser/blob/blob_data_handle.h"
......@@ -15,6 +16,8 @@
namespace content {
class BackgroundFetchRequestMatchParams;
namespace background_fetch {
class GetSettledFetchesTask : public DatabaseTask {
......@@ -25,8 +28,12 @@ class GetSettledFetchesTask : public DatabaseTask {
std::vector<BackgroundFetchSettledFetch>,
std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
GetSettledFetchesTask(DatabaseTaskHost* host,
// Gets settled fetches from cache storage, filtered according to
// |match_params|.
GetSettledFetchesTask(
DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
SettledFetchesCallback callback);
~GetSettledFetchesTask() override;
......@@ -59,6 +66,7 @@ class GetSettledFetchesTask : public DatabaseTask {
void FinishWithError(blink::mojom::BackgroundFetchError error) override;
BackgroundFetchRegistrationId registration_id_;
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params_;
SettledFetchesCallback settled_fetches_callback_;
// SettledFetchesCallback params.
......
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