Commit 90d1f5a1 authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[Background Fetch] Implement match and matchAll()

Implement these on BackgroundFetchRegistration, which is, in turn, exposed on
all Background Fetch events surfaced to the developers.

Bug: 863016
Change-Id: If6406b800b595df285d7304652948063c80ac45b
Reviewed-on: https://chromium-review.googlesource.com/1177394
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Reviewed-by: default avatarRayan Kanso <rayankans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584826}
parent fb13532c
...@@ -497,6 +497,34 @@ void BackgroundFetchContext::DispatchClickEvent(const std::string& unique_id) { ...@@ -497,6 +497,34 @@ void BackgroundFetchContext::DispatchClickEvent(const std::string& unique_id) {
blink::mojom::BackgroundFetchState::PENDING, base::DoNothing()); blink::mojom::BackgroundFetchState::PENDING, base::DoNothing());
} }
void BackgroundFetchContext::MatchRequests(
const BackgroundFetchRegistrationId& registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
data_manager_->GetSettledFetchesForRegistration(
registration_id, std::move(match_params),
base::BindOnce(&BackgroundFetchContext::DidGetMatchingRequests,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void BackgroundFetchContext::DidGetMatchingRequests(
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback,
blink::mojom::BackgroundFetchError error,
bool background_fetch_succeeded,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(crbug.com/863016): Update to 0u once we've stopped sending an
// uncached response.
if (error != blink::mojom::BackgroundFetchError::NONE)
DCHECK_EQ(settled_fetches.size(), 1u);
std::move(callback).Run(std::move(settled_fetches));
}
void BackgroundFetchContext::LastObserverGarbageCollected( void BackgroundFetchContext::LastObserverGarbageCollected(
const BackgroundFetchRegistrationId& registration_id) { const BackgroundFetchRegistrationId& registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
......
...@@ -35,6 +35,7 @@ class BackgroundFetchDataManager; ...@@ -35,6 +35,7 @@ class BackgroundFetchDataManager;
struct BackgroundFetchOptions; struct BackgroundFetchOptions;
class BackgroundFetchRegistrationId; class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier; class BackgroundFetchRegistrationNotifier;
class BackgroundFetchRequestMatchParams;
class BackgroundFetchRequestInfo; class BackgroundFetchRequestInfo;
class BackgroundFetchScheduler; class BackgroundFetchScheduler;
class BrowserContext; class BrowserContext;
...@@ -96,6 +97,12 @@ class CONTENT_EXPORT BackgroundFetchContext ...@@ -96,6 +97,12 @@ class CONTENT_EXPORT BackgroundFetchContext
blink::mojom::BackgroundFetchService::GetIconDisplaySizeCallback blink::mojom::BackgroundFetchService::GetIconDisplaySizeCallback
callback); callback);
// Matches Background Fetch requests from the cache and returns responses.
void MatchRequests(
const BackgroundFetchRegistrationId& registration_id,
std::unique_ptr<BackgroundFetchRequestMatchParams> match_params,
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback);
// Aborts the Background Fetch for the |registration_id|. The callback will be // Aborts the Background Fetch for the |registration_id|. The callback will be
// invoked with INVALID_ID if the registration has already completed or // invoked with INVALID_ID if the registration has already completed or
// aborted, STORAGE_ERROR if an I/O error occurs, or NONE for success. // aborted, STORAGE_ERROR if an I/O error occurs, or NONE for success.
...@@ -202,6 +209,16 @@ class CONTENT_EXPORT BackgroundFetchContext ...@@ -202,6 +209,16 @@ class CONTENT_EXPORT BackgroundFetchContext
std::vector<BackgroundFetchSettledFetch> settled_fetches, std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles); std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
// Called when the sequence of matching settled fetches have been received
// from storage, and |callback| can be invoked to pass these on to the
// renderer.
void DidGetMatchingRequests(
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback,
blink::mojom::BackgroundFetchError error,
bool background_fetch_succeeded,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
// Called when the notification UI for the background fetch job associated // Called when the notification UI for the background fetch job associated
// with |unique_id| is activated. // with |unique_id| is activated.
void DispatchClickEvent(const std::string& unique_id); void DispatchClickEvent(const std::string& unique_id);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h" #include "content/browser/service_worker/service_worker_version.h"
#include "content/common/background_fetch/background_fetch_types.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
namespace content { namespace content {
......
...@@ -8,9 +8,11 @@ namespace content { ...@@ -8,9 +8,11 @@ namespace content {
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams( BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams(
base::Optional<ServiceWorkerFetchRequest> request_to_match, base::Optional<ServiceWorkerFetchRequest> request_to_match,
blink::mojom::QueryParamsPtr cache_query_params) blink::mojom::QueryParamsPtr cache_query_params,
bool match_all)
: request_to_match_(std::move(request_to_match)), : request_to_match_(std::move(request_to_match)),
cache_query_params_(std::move(cache_query_params)) {} cache_query_params_(std::move(cache_query_params)),
match_all_(match_all) {}
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams() = BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams() =
default; default;
......
...@@ -13,12 +13,11 @@ namespace content { ...@@ -13,12 +13,11 @@ namespace content {
class CONTENT_EXPORT BackgroundFetchRequestMatchParams { class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
public: public:
// TODO(crbug.com/863852): Add boolean to differentiate between match vs
// matchAll.
BackgroundFetchRequestMatchParams(); BackgroundFetchRequestMatchParams();
BackgroundFetchRequestMatchParams( BackgroundFetchRequestMatchParams(
base::Optional<ServiceWorkerFetchRequest> request_to_match, base::Optional<ServiceWorkerFetchRequest> request_to_match,
blink::mojom::QueryParamsPtr cache_query_params); blink::mojom::QueryParamsPtr cache_query_params,
bool match_all);
~BackgroundFetchRequestMatchParams(); ~BackgroundFetchRequestMatchParams();
bool FilterByRequest() const { bool FilterByRequest() const {
...@@ -37,6 +36,8 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams { ...@@ -37,6 +36,8 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
return cache_query_params_->Clone(); return cache_query_params_->Clone();
} }
bool match_all() const { return match_all_; }
private: private:
// If |request_to_match| is present, we get response(s) only for this request. // 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 // If not present, response(s) for all requests (contained in the fetch) will
...@@ -46,6 +47,9 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams { ...@@ -46,6 +47,9 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
// When nullptr, this has no effect on the response(s) returned. // When nullptr, this has no effect on the response(s) returned.
blink::mojom::QueryParamsPtr cache_query_params_; blink::mojom::QueryParamsPtr cache_query_params_;
// Whether to return all matching responses from the cache storage.
bool match_all_ = false;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRequestMatchParams); DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRequestMatchParams);
}; };
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
#include <memory> #include <memory>
#include "base/guid.h" #include "base/guid.h"
#include "base/optional.h"
#include "content/browser/background_fetch/background_fetch_context.h" #include "content/browser/background_fetch/background_fetch_context.h"
#include "content/browser/background_fetch/background_fetch_metrics.h" #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_id.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/bad_message.h" #include "content/browser/bad_message.h"
#include "content/browser/storage_partition_impl.h" #include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_types.h"
...@@ -130,6 +132,27 @@ void BackgroundFetchServiceImpl::GetIconDisplaySize( ...@@ -130,6 +132,27 @@ void BackgroundFetchServiceImpl::GetIconDisplaySize(
background_fetch_context_->GetIconDisplaySize(std::move(callback)); background_fetch_context_->GetIconDisplaySize(std::move(callback));
} }
void BackgroundFetchServiceImpl::MatchRequests(
int64_t service_worker_registration_id,
const std::string& developer_id,
const std::string& unique_id,
const base::Optional<ServiceWorkerFetchRequest>& request_to_match,
blink::mojom::QueryParamsPtr cache_query_params,
bool match_all,
MatchRequestsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BackgroundFetchRegistrationId registration_id(
service_worker_registration_id, origin_, developer_id, unique_id);
// Create BackgroundFetchMatchRequestParams.
auto match_params = std::make_unique<BackgroundFetchRequestMatchParams>(
request_to_match, std::move(cache_query_params), match_all);
background_fetch_context_->MatchRequests(
registration_id, std::move(match_params), std::move(callback));
}
void BackgroundFetchServiceImpl::UpdateUI( void BackgroundFetchServiceImpl::UpdateUI(
int64_t service_worker_registration_id, int64_t service_worker_registration_id,
const std::string& developer_id, const std::string& developer_id,
......
...@@ -52,6 +52,14 @@ class CONTENT_EXPORT BackgroundFetchServiceImpl ...@@ -52,6 +52,14 @@ class CONTENT_EXPORT BackgroundFetchServiceImpl
const SkBitmap& icon, const SkBitmap& icon,
FetchCallback callback) override; FetchCallback callback) override;
void GetIconDisplaySize(GetIconDisplaySizeCallback callback) override; void GetIconDisplaySize(GetIconDisplaySizeCallback callback) override;
void MatchRequests(
int64_t service_worker_registration_id,
const std::string& developer_id,
const std::string& unique_id,
const base::Optional<ServiceWorkerFetchRequest>& request_to_match,
blink::mojom::QueryParamsPtr cache_query_params,
bool match_all,
MatchRequestsCallback callback) override;
void UpdateUI(int64_t service_worker_registration_id, void UpdateUI(int64_t service_worker_registration_id,
const std::string& developer_id, const std::string& developer_id,
const std::string& unique_id, const std::string& unique_id,
......
...@@ -106,46 +106,42 @@ void GetSettledFetchesTask::GetResponses() { ...@@ -106,46 +106,42 @@ void GetSettledFetchesTask::GetResponses() {
return; return;
} }
if (match_params_->FilterByRequest()) { if (!match_params_->FilterByRequest()) {
// Get a response only for the relevant fetch. // No request to match against has been specified. Process all completed
settled_fetches_.emplace_back(); // requests.
settled_fetches_.back().request = match_params_->request_to_match(); // TODO(crbug.com/863016): Process all requests here, not just the
for (const auto& completed_request : completed_requests_) { // completed ones.
if (completed_request.serialized_request() != base::RepeatingClosure barrier_closure = base::BarrierClosure(
match_params_->request_to_match().Serialize()) { completed_requests_.size(),
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, base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(), weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE)); blink::mojom::BackgroundFetchError::NONE));
settled_fetches_.reserve(completed_requests_.size());
for (const auto& completed_request : completed_requests_) {
settled_fetches_.emplace_back();
settled_fetches_.back().request =
std::move(ServiceWorkerFetchRequest::ParseFromString(
completed_request.serialized_request()));
FillResponse(&settled_fetches_.back(), barrier_closure);
}
return; return;
} }
// Process all completed requests. // Get response(s) only for the relevant fetch.
base::RepeatingClosure barrier_closure = base::BarrierClosure( settled_fetches_.emplace_back();
completed_requests_.size(), settled_fetches_.back().request = match_params_->request_to_match();
base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(), if (match_params_->match_all()) {
blink::mojom::BackgroundFetchError::NONE)); FillResponses(base::BindOnce(&GetSettledFetchesTask::FinishWithError,
settled_fetches_.reserve(completed_requests_.size()); weak_factory_.GetWeakPtr(),
for (const auto& completed_request : completed_requests_) { blink::mojom::BackgroundFetchError::NONE));
settled_fetches_.emplace_back(); return;
settled_fetches_.back().request = } else {
std::move(ServiceWorkerFetchRequest::ParseFromString( FillResponse(&settled_fetches_.back(),
completed_request.serialized_request())); base::BindOnce(&GetSettledFetchesTask::FinishWithError,
FillResponse(&settled_fetches_.back(), barrier_closure); weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
return;
} }
} }
...@@ -164,6 +160,22 @@ void GetSettledFetchesTask::FillResponse( ...@@ -164,6 +160,22 @@ void GetSettledFetchesTask::FillResponse(
settled_fetch, std::move(callback))); settled_fetch, std::move(callback)));
} }
void GetSettledFetchesTask::FillResponses(base::OnceClosure callback) {
DCHECK(match_params_->match_all());
DCHECK(match_params_->FilterByRequest());
DCHECK(!settled_fetches_.empty());
DCHECK(handle_.value());
// Make a copy.
auto request = std::make_unique<ServiceWorkerFetchRequest>(
match_params_->request_to_match());
handle_.value()->MatchAll(
std::move(request), match_params_->cloned_cache_query_params(),
base::BindOnce(&GetSettledFetchesTask::DidMatchAllResponsesForRequest,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void GetSettledFetchesTask::DidMatchRequest( void GetSettledFetchesTask::DidMatchRequest(
BackgroundFetchSettledFetch* settled_fetch, BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback, base::OnceClosure callback,
...@@ -173,8 +185,13 @@ void GetSettledFetchesTask::DidMatchRequest( ...@@ -173,8 +185,13 @@ void GetSettledFetchesTask::DidMatchRequest(
// Handle error cases. // Handle error cases.
if (error == blink::mojom::CacheStorageError::kErrorNotFound) { if (error == blink::mojom::CacheStorageError::kErrorNotFound) {
// If we are matching everything then we expect to find all responses // This is currently being called once a fetch finishes, or when match() is
// in the cache. // called.
// In the first case, not finding a response is an error state. In the
// second case, it just means the developer passed a non-matching request.
// The if condition below picks the first one.
// TODO(crbug.com/863016): Once we stop sending settled_fetches with
// BackgroundFetch events, this won't be a storage error.
if (!match_params_->FilterByRequest()) if (!match_params_->FilterByRequest())
SetStorageError(BackgroundFetchStorageError::kCacheStorageError); SetStorageError(BackgroundFetchStorageError::kCacheStorageError);
} else if (error != blink::mojom::CacheStorageError::kSuccess) { } else if (error != blink::mojom::CacheStorageError::kSuccess) {
...@@ -189,6 +206,32 @@ void GetSettledFetchesTask::DidMatchRequest( ...@@ -189,6 +206,32 @@ void GetSettledFetchesTask::DidMatchRequest(
std::move(callback).Run(); std::move(callback).Run();
} }
void GetSettledFetchesTask::DidMatchAllResponsesForRequest(
base::OnceClosure callback,
blink::mojom::CacheStorageError error,
std::vector<blink::mojom::FetchAPIResponsePtr> cache_responses) {
if (error != blink::mojom::CacheStorageError::kSuccess &&
error != blink::mojom::CacheStorageError::kErrorNotFound) {
SetStorageError(BackgroundFetchStorageError::kCacheStorageError);
}
if (error != blink::mojom::CacheStorageError::kSuccess) {
DCHECK(!settled_fetches_.empty());
FillUncachedResponse(&settled_fetches_.back(), std::move(callback));
return;
}
settled_fetches_.clear();
settled_fetches_.reserve(cache_responses.size());
for (size_t i = 0; i < cache_responses.size(); ++i) {
settled_fetches_.emplace_back();
settled_fetches_.back().request = match_params_->request_to_match();
settled_fetches_.back().response = std::move(cache_responses[i]);
}
std::move(callback).Run();
}
// TODO(crbug.com/863016): Get rid of this method.
void GetSettledFetchesTask::FillUncachedResponse( void GetSettledFetchesTask::FillUncachedResponse(
BackgroundFetchSettledFetch* settled_fetch, BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback) { base::OnceClosure callback) {
......
...@@ -22,6 +22,7 @@ namespace background_fetch { ...@@ -22,6 +22,7 @@ namespace background_fetch {
class GetSettledFetchesTask : public DatabaseTask { class GetSettledFetchesTask : public DatabaseTask {
public: public:
// TODO(nator): Remove BlobDataHandle since we're not using them.
using SettledFetchesCallback = base::OnceCallback<void( using SettledFetchesCallback = base::OnceCallback<void(
blink::mojom::BackgroundFetchError, blink::mojom::BackgroundFetchError,
bool, bool,
...@@ -58,11 +59,18 @@ class GetSettledFetchesTask : public DatabaseTask { ...@@ -58,11 +59,18 @@ class GetSettledFetchesTask : public DatabaseTask {
void FillResponse(BackgroundFetchSettledFetch* settled_fetch, void FillResponse(BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback); base::OnceClosure callback);
void FillResponses(base::OnceClosure callback);
void DidMatchRequest(BackgroundFetchSettledFetch* settled_fetch, void DidMatchRequest(BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback, base::OnceClosure callback,
blink::mojom::CacheStorageError error, blink::mojom::CacheStorageError error,
blink::mojom::FetchAPIResponsePtr cache_response); blink::mojom::FetchAPIResponsePtr cache_response);
void DidMatchAllResponsesForRequest(
base::OnceClosure callback,
blink::mojom::CacheStorageError error,
std::vector<blink::mojom::FetchAPIResponsePtr> cache_responses);
void FinishWithError(blink::mojom::BackgroundFetchError error) override; void FinishWithError(blink::mojom::BackgroundFetchError error) override;
std::string HistogramName() const override; std::string HistogramName() const override;
......
...@@ -43,9 +43,9 @@ bool StructTraits<blink::mojom::BackgroundFetchRegistrationDataView, ...@@ -43,9 +43,9 @@ bool StructTraits<blink::mojom::BackgroundFetchRegistrationDataView,
} }
// static // static
bool StructTraits<content::mojom::BackgroundFetchSettledFetchDataView, bool StructTraits<blink::mojom::BackgroundFetchSettledFetchDataView,
content::BackgroundFetchSettledFetch>:: content::BackgroundFetchSettledFetch>::
Read(content::mojom::BackgroundFetchSettledFetchDataView data, Read(blink::mojom::BackgroundFetchSettledFetchDataView data,
content::BackgroundFetchSettledFetch* fetch) { content::BackgroundFetchSettledFetch* fetch) {
return data.ReadRequest(&fetch->request) && return data.ReadRequest(&fetch->request) &&
data.ReadResponse(&fetch->response); data.ReadResponse(&fetch->response);
......
...@@ -14,12 +14,6 @@ ...@@ -14,12 +14,6 @@
#include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h" #include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
namespace mojom {
class BackgroundFetchSettledFetchDataView;
}
}
namespace mojo { namespace mojo {
template <> template <>
...@@ -77,7 +71,7 @@ struct CONTENT_EXPORT ...@@ -77,7 +71,7 @@ struct CONTENT_EXPORT
template <> template <>
struct CONTENT_EXPORT struct CONTENT_EXPORT
StructTraits<content::mojom::BackgroundFetchSettledFetchDataView, StructTraits<blink::mojom::BackgroundFetchSettledFetchDataView,
content::BackgroundFetchSettledFetch> { content::BackgroundFetchSettledFetch> {
static const content::ServiceWorkerFetchRequest& request( static const content::ServiceWorkerFetchRequest& request(
const content::BackgroundFetchSettledFetch& fetch) { const content::BackgroundFetchSettledFetch& fetch) {
...@@ -89,7 +83,7 @@ struct CONTENT_EXPORT ...@@ -89,7 +83,7 @@ struct CONTENT_EXPORT
fetch.response); fetch.response);
} }
static bool Read(content::mojom::BackgroundFetchSettledFetchDataView data, static bool Read(blink::mojom::BackgroundFetchSettledFetchDataView data,
content::BackgroundFetchSettledFetch* definition); content::BackgroundFetchSettledFetch* definition);
}; };
......
...@@ -14,5 +14,5 @@ deps = [ ...@@ -14,5 +14,5 @@ deps = [
type_mappings = [ type_mappings = [
"blink.mojom.BackgroundFetchOptions=content::BackgroundFetchOptions", "blink.mojom.BackgroundFetchOptions=content::BackgroundFetchOptions",
"blink.mojom.BackgroundFetchRegistration=content::BackgroundFetchRegistration", "blink.mojom.BackgroundFetchRegistration=content::BackgroundFetchRegistration",
"content.mojom.BackgroundFetchSettledFetch=::content::BackgroundFetchSettledFetch", "blink.mojom.BackgroundFetchSettledFetch=::content::BackgroundFetchSettledFetch",
] ]
...@@ -23,12 +23,6 @@ import "third_party/blink/public/mojom/service_worker/service_worker_registratio ...@@ -23,12 +23,6 @@ import "third_party/blink/public/mojom/service_worker/service_worker_registratio
import "url/mojom/origin.mojom"; import "url/mojom/origin.mojom";
import "url/mojom/url.mojom"; import "url/mojom/url.mojom";
// TODO(peter): Move this to Blink.
struct BackgroundFetchSettledFetch {
blink.mojom.FetchAPIRequest request;
blink.mojom.FetchAPIResponse? response;
};
struct ExtendableMessageEvent { struct ExtendableMessageEvent {
blink.mojom.TransferableMessage message; blink.mojom.TransferableMessage message;
url.mojom.Origin source_origin; url.mojom.Origin source_origin;
...@@ -105,14 +99,14 @@ interface ServiceWorker { ...@@ -105,14 +99,14 @@ interface ServiceWorker {
DispatchBackgroundFetchFailEvent(string developer_id, DispatchBackgroundFetchFailEvent(string developer_id,
string unique_id, string unique_id,
blink.mojom.BackgroundFetchState state, blink.mojom.BackgroundFetchState state,
array<BackgroundFetchSettledFetch> fetches) array<blink.mojom.BackgroundFetchSettledFetch> fetches)
=> (blink.mojom.ServiceWorkerEventStatus status, => (blink.mojom.ServiceWorkerEventStatus status,
mojo_base.mojom.Time dispatch_event_time); mojo_base.mojom.Time dispatch_event_time);
DispatchBackgroundFetchSuccessEvent( DispatchBackgroundFetchSuccessEvent(
string developer_id, string developer_id,
string unique_id, string unique_id,
blink.mojom.BackgroundFetchState state, blink.mojom.BackgroundFetchState state,
array<BackgroundFetchSettledFetch> fetches) array<blink.mojom.BackgroundFetchSettledFetch> fetches)
=> (blink.mojom.ServiceWorkerEventStatus status, => (blink.mojom.ServiceWorkerEventStatus status,
mojo_base.mojom.Time dispatch_event_time); mojo_base.mojom.Time dispatch_event_time);
......
...@@ -44,6 +44,8 @@ interface BackgroundFetchRegistration : EventTarget ...@@ -44,6 +44,8 @@ interface BackgroundFetchRegistration : EventTarget
getter uploaded getter uploaded
method abort method abort
method constructor method constructor
method match
method matchAll
setter onprogress setter onprogress
interface BackgroundFetchSettledFetch : BackgroundFetchFetch interface BackgroundFetchSettledFetch : BackgroundFetchFetch
attribute @@toStringTag attribute @@toStringTag
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
module blink.mojom; module blink.mojom;
import "skia/public/interfaces/bitmap.mojom"; import "skia/public/interfaces/bitmap.mojom";
import "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom";
import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom"; import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
import "third_party/blink/public/mojom/manifest/manifest.mojom"; import "third_party/blink/public/mojom/manifest/manifest.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom";
...@@ -19,6 +21,13 @@ enum BackgroundFetchError { ...@@ -19,6 +21,13 @@ enum BackgroundFetchError {
QUOTA_EXCEEDED QUOTA_EXCEEDED
}; };
// Struct representing completed Background Fetch requests, along with their
// responses.
struct BackgroundFetchSettledFetch {
FetchAPIRequest request;
FetchAPIResponse? response;
};
enum BackgroundFetchState { enum BackgroundFetchState {
PENDING, PENDING,
FAILURE, FAILURE,
...@@ -108,6 +117,18 @@ interface BackgroundFetchService { ...@@ -108,6 +117,18 @@ interface BackgroundFetchService {
GetIconDisplaySize() GetIconDisplaySize()
=> (gfx.mojom.Size icon_size_pixels); => (gfx.mojom.Size icon_size_pixels);
// Gets matching {request, response} pairs for the completed fetches associated
// with |service_worker_registration_id|, |developer_id|, and |unique_id|.
// TODO(crbug.com/866874): Create a mojo interface for
// BackgroundFetchRegistrationId, so we can avoid having to pass the first
// three arguments in multiple methods.
MatchRequests(int64 service_worker_registration_id,
string developer_id,
string unique_id,
FetchAPIRequest? request_to_match,
QueryParams cache_query_params,
bool match_all) => (array<BackgroundFetchSettledFetch> fetches);
// Registers the |observer| to receive events for the given registration // Registers the |observer| to receive events for the given registration
// that is identified by the |unique_id|. // that is identified by the |unique_id|.
AddRegistrationObserver(string unique_id, AddRegistrationObserver(string unique_id,
......
...@@ -46,6 +46,19 @@ void BackgroundFetchBridge::GetIconDisplaySize( ...@@ -46,6 +46,19 @@ void BackgroundFetchBridge::GetIconDisplaySize(
GetService()->GetIconDisplaySize(std::move(callback)); GetService()->GetIconDisplaySize(std::move(callback));
} }
void BackgroundFetchBridge::MatchRequests(
const String& developer_id,
const String& unique_id,
base::Optional<WebServiceWorkerRequest> request_to_match,
mojom::blink::QueryParamsPtr cache_query_params,
bool match_all,
mojom::blink::BackgroundFetchService::MatchRequestsCallback callback) {
GetService()->MatchRequests(
GetSupplementable()->WebRegistration()->RegistrationId(), developer_id,
unique_id, std::move(request_to_match), std::move(cache_query_params),
match_all, std::move(callback));
}
void BackgroundFetchBridge::Fetch( void BackgroundFetchBridge::Fetch(
const String& developer_id, const String& developer_id,
Vector<WebServiceWorkerRequest> requests, Vector<WebServiceWorkerRequest> requests,
......
...@@ -59,6 +59,20 @@ class BackgroundFetchBridge final ...@@ -59,6 +59,20 @@ class BackgroundFetchBridge final
// Gets the size of the icon to be displayed in Background Fetch UI. // Gets the size of the icon to be displayed in Background Fetch UI.
void GetIconDisplaySize(GetIconDisplaySizeCallback callback); void GetIconDisplaySize(GetIconDisplaySizeCallback callback);
// Matches completed requests for the fetch associated with the |developer_id|
// and |unique_id| and returns the {request, response} pairs based on the rest
// of the arguments. If |filter_by_request| is true, only response(s) for
// |request_to_match| are returned. |cache_query_params| are options for the
// query to the cache storage. |match_all|, when true, returns all responses
// from the result set, and when false, returns only the first one.
void MatchRequests(
const String& developer_id,
const String& unique_id,
base::Optional<WebServiceWorkerRequest> request_to_match,
mojom::blink::QueryParamsPtr cache_query_params,
bool match_all,
mojom::blink::BackgroundFetchService::MatchRequestsCallback callback);
// Updates the user interface for the Background Fetch identified by // Updates the user interface for the Background Fetch identified by
// |unique_id| with the updated |title| or |icon|. Will invoke the |callback| // |unique_id| with the updated |title| or |icon|. Will invoke the |callback|
// when the interface has been requested to update. // when the interface has been requested to update.
......
...@@ -4,9 +4,17 @@ ...@@ -4,9 +4,17 @@
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "base/optional.h"
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_record.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h"
#include "third_party/blink/renderer/modules/cache_storage/cache.h"
#include "third_party/blink/renderer/modules/cache_storage/cache_query_options.h"
#include "third_party/blink/renderer/modules/event_target_modules_names.h" #include "third_party/blink/renderer/modules/event_target_modules_names.h"
#include "third_party/blink/renderer/modules/manifest/image_resource.h" #include "third_party/blink/renderer/modules/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
...@@ -106,15 +114,109 @@ ScriptPromise BackgroundFetchRegistration::abort(ScriptState* script_state) { ...@@ -106,15 +114,109 @@ ScriptPromise BackgroundFetchRegistration::abort(ScriptState* script_state) {
return promise; return promise;
} }
ScriptPromise BackgroundFetchRegistration::match(
ScriptState* script_state,
const RequestOrUSVString& request,
const CacheQueryOptions& options,
ExceptionState& exception_state) {
return MatchImpl(
script_state, base::make_optional<RequestOrUSVString>(request),
Cache::ToQueryParams(options), exception_state, /* match_all = */ false);
}
ScriptPromise BackgroundFetchRegistration::matchAll(
ScriptState* script_state,
ExceptionState& exception_state) {
return MatchImpl(script_state, /* request = */ base::nullopt,
/* cache_query_options = */ nullptr, exception_state,
/* match_all = */ true);
}
ScriptPromise BackgroundFetchRegistration::matchAll(
ScriptState* script_state,
const RequestOrUSVString& request,
const CacheQueryOptions& options,
ExceptionState& exception_state) {
return MatchImpl(
script_state, base::make_optional<RequestOrUSVString>(request),
Cache::ToQueryParams(options), exception_state, /* match_all = */ true);
}
ScriptPromise BackgroundFetchRegistration::MatchImpl(
ScriptState* script_state,
base::Optional<RequestOrUSVString> request,
mojom::blink::QueryParamsPtr cache_query_params,
ExceptionState& exception_state,
bool match_all) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
// Convert |request| to WebServiceWorkerRequest.
base::Optional<WebServiceWorkerRequest> request_to_match;
if (request.has_value()) {
if (request->IsRequest()) {
request->GetAsRequest()->PopulateWebServiceWorkerRequest(
request_to_match.value());
} else {
Request* new_request = Request::Create(
script_state, request->GetAsUSVString(), exception_state);
if (exception_state.HadException())
return ScriptPromise();
new_request->PopulateWebServiceWorkerRequest(request_to_match.value());
}
}
DCHECK(registration_);
BackgroundFetchBridge::From(registration_)
->MatchRequests(
developer_id_, unique_id_, request_to_match,
std::move(cache_query_params), match_all,
WTF::Bind(&BackgroundFetchRegistration::DidGetMatchingRequests,
WrapPersistent(this), WrapPersistent(resolver), match_all));
return promise;
}
void BackgroundFetchRegistration::DidGetMatchingRequests(
ScriptPromiseResolver* resolver,
bool return_all,
Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches) {
ScriptState* script_state = resolver->GetScriptState();
// Do not remove this, |scope| is needed for calling ToV8()
ScriptState::Scope scope(script_state);
HeapVector<Member<BackgroundFetchRecord>> to_return;
to_return.ReserveInitialCapacity(settled_fetches.size());
for (const auto& fetch : settled_fetches) {
if (fetch->response->response_type ==
network::mojom::FetchResponseType::kError) {
// Resolve with undefined.
resolver->Resolve();
return;
}
BackgroundFetchRecord* record = new BackgroundFetchRecord(
Request::Create(script_state, fetch->request),
Response::Create(script_state, *fetch->response));
to_return.push_back(record);
}
if (!return_all) {
DCHECK_EQ(settled_fetches.size(), 1u);
DCHECK_EQ(to_return.size(), 1u);
resolver->Resolve(to_return[0]);
return;
}
resolver->Resolve(to_return);
}
void BackgroundFetchRegistration::DidAbort( void BackgroundFetchRegistration::DidAbort(
ScriptPromiseResolver* resolver, ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error) { mojom::blink::BackgroundFetchError error) {
switch (error) { switch (error) {
case mojom::blink::BackgroundFetchError::NONE: case mojom::blink::BackgroundFetchError::NONE:
resolver->Resolve(true /* success */); resolver->Resolve(/* success = */ true);
return; return;
case mojom::blink::BackgroundFetchError::INVALID_ID: case mojom::blink::BackgroundFetchError::INVALID_ID:
resolver->Resolve(false /* success */); resolver->Resolve(/* success = */ false);
return; return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR: case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
resolver->Reject(DOMException::Create( resolver->Reject(DOMException::Create(
......
...@@ -16,9 +16,11 @@ ...@@ -16,9 +16,11 @@
namespace blink { namespace blink {
class CacheQueryOptions;
class ScriptPromiseResolver; class ScriptPromiseResolver;
class ScriptState; class ScriptState;
class ServiceWorkerRegistration; class ServiceWorkerRegistration;
class RequestOrUSVString;
// Represents an individual Background Fetch registration. Gives developers // Represents an individual Background Fetch registration. Gives developers
// access to its properties, options, and enables them to abort the fetch. // access to its properties, options, and enables them to abort the fetch.
...@@ -52,6 +54,16 @@ class BackgroundFetchRegistration final ...@@ -52,6 +54,16 @@ class BackgroundFetchRegistration final
// Web Exposed attribute defined in the IDL file. Corresponds to the // Web Exposed attribute defined in the IDL file. Corresponds to the
// |developer_id| used elsewhere in the codebase. // |developer_id| used elsewhere in the codebase.
String id() const; String id() const;
ScriptPromise match(ScriptState* script_state,
const RequestOrUSVString& request,
const CacheQueryOptions& options,
ExceptionState& exception_state);
ScriptPromise matchAll(ScriptState* scrip_state,
ExceptionState& exception_state);
ScriptPromise matchAll(ScriptState* script_state,
const RequestOrUSVString& request,
const CacheQueryOptions& options,
ExceptionState& exception_state);
unsigned long long uploadTotal() const; unsigned long long uploadTotal() const;
unsigned long long uploaded() const; unsigned long long uploaded() const;
...@@ -76,6 +88,15 @@ class BackgroundFetchRegistration final ...@@ -76,6 +88,15 @@ class BackgroundFetchRegistration final
private: private:
void DidAbort(ScriptPromiseResolver* resolver, void DidAbort(ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error); mojom::blink::BackgroundFetchError error);
ScriptPromise MatchImpl(ScriptState* script_state,
base::Optional<RequestOrUSVString> request,
mojom::blink::QueryParamsPtr cache_query_params,
ExceptionState& exception_state,
bool match_all);
void DidGetMatchingRequests(
ScriptPromiseResolver* resolver,
bool return_all,
Vector<mojom::blink::BackgroundFetchSettledFetchPtr> settled_fetches);
Member<ServiceWorkerRegistration> registration_; Member<ServiceWorkerRegistration> registration_;
......
...@@ -15,10 +15,13 @@ enum BackgroundFetchState { "pending", "success", "failure" }; ...@@ -15,10 +15,13 @@ enum BackgroundFetchState { "pending", "success", "failure" };
readonly attribute unsigned long long downloadTotal; readonly attribute unsigned long long downloadTotal;
readonly attribute unsigned long long downloaded; readonly attribute unsigned long long downloaded;
readonly attribute BackgroundFetchState state; readonly attribute BackgroundFetchState state;
// TODO(crbug.com/699957): Implement the `activeFetches` attribute.
attribute EventHandler onprogress; attribute EventHandler onprogress;
[CallWith=ScriptState] Promise<boolean> abort(); [CallWith=ScriptState] Promise<boolean> abort();
// TODO(crbug.com/863016): Add match() and matchAll().
}; // TODO(crbug.com/875201): Change to (Window,Worker) once we support
\ No newline at end of file // match() and matchAll() for active fetches.
[CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<BackgroundFetchRecord> match(RequestInfo request, optional CacheQueryOptions options);
[CallWith=ScriptState, Exposed=ServiceWorker, RaisesException] Promise<sequence<BackgroundFetchRecord>> matchAll(optional RequestInfo request, optional CacheQueryOptions options);
};
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