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) {
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(
const BackgroundFetchRegistrationId& registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
......
......@@ -35,6 +35,7 @@ class BackgroundFetchDataManager;
struct BackgroundFetchOptions;
class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier;
class BackgroundFetchRequestMatchParams;
class BackgroundFetchRequestInfo;
class BackgroundFetchScheduler;
class BrowserContext;
......@@ -96,6 +97,12 @@ class CONTENT_EXPORT BackgroundFetchContext
blink::mojom::BackgroundFetchService::GetIconDisplaySizeCallback
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
// invoked with INVALID_ID if the registration has already completed or
// aborted, STORAGE_ERROR if an I/O error occurs, or NONE for success.
......@@ -202,6 +209,16 @@ class CONTENT_EXPORT BackgroundFetchContext
std::vector<BackgroundFetchSettledFetch> settled_fetches,
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
// with |unique_id| is activated.
void DispatchClickEvent(const std::string& unique_id);
......
......@@ -12,6 +12,7 @@
#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_version.h"
#include "content/common/background_fetch/background_fetch_types.h"
#include "content/public/browser/browser_thread.h"
namespace content {
......
......@@ -8,9 +8,11 @@ namespace content {
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams(
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)),
cache_query_params_(std::move(cache_query_params)) {}
cache_query_params_(std::move(cache_query_params)),
match_all_(match_all) {}
BackgroundFetchRequestMatchParams::BackgroundFetchRequestMatchParams() =
default;
......
......@@ -13,12 +13,11 @@ 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);
blink::mojom::QueryParamsPtr cache_query_params,
bool match_all);
~BackgroundFetchRequestMatchParams();
bool FilterByRequest() const {
......@@ -37,6 +36,8 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
return cache_query_params_->Clone();
}
bool match_all() const { return match_all_; }
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
......@@ -46,6 +47,9 @@ class CONTENT_EXPORT BackgroundFetchRequestMatchParams {
// When nullptr, this has no effect on the response(s) returned.
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);
};
......
......@@ -7,9 +7,11 @@
#include <memory>
#include "base/guid.h"
#include "base/optional.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_registration_id.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/browser/bad_message.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_types.h"
......@@ -130,6 +132,27 @@ void BackgroundFetchServiceImpl::GetIconDisplaySize(
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(
int64_t service_worker_registration_id,
const std::string& developer_id,
......
......@@ -52,6 +52,14 @@ class CONTENT_EXPORT BackgroundFetchServiceImpl
const SkBitmap& icon,
FetchCallback 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,
const std::string& developer_id,
const std::string& unique_id,
......
......@@ -106,46 +106,42 @@ 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(),
if (!match_params_->FilterByRequest()) {
// No request to match against has been specified. Process all completed
// requests.
// TODO(crbug.com/863016): Process all requests here, not just the
// completed ones.
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();
settled_fetches_.back().request =
std::move(ServiceWorkerFetchRequest::ParseFromString(
completed_request.serialized_request()));
FillResponse(&settled_fetches_.back(), barrier_closure);
}
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();
settled_fetches_.back().request =
std::move(ServiceWorkerFetchRequest::ParseFromString(
completed_request.serialized_request()));
FillResponse(&settled_fetches_.back(), barrier_closure);
// Get response(s) only for the relevant fetch.
settled_fetches_.emplace_back();
settled_fetches_.back().request = match_params_->request_to_match();
if (match_params_->match_all()) {
FillResponses(base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
return;
} else {
FillResponse(&settled_fetches_.back(),
base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
return;
}
}
......@@ -164,6 +160,22 @@ void GetSettledFetchesTask::FillResponse(
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(
BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback,
......@@ -173,8 +185,13 @@ void GetSettledFetchesTask::DidMatchRequest(
// Handle error cases.
if (error == blink::mojom::CacheStorageError::kErrorNotFound) {
// If we are matching everything then we expect to find all responses
// in the cache.
// This is currently being called once a fetch finishes, or when match() is
// 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())
SetStorageError(BackgroundFetchStorageError::kCacheStorageError);
} else if (error != blink::mojom::CacheStorageError::kSuccess) {
......@@ -189,6 +206,32 @@ void GetSettledFetchesTask::DidMatchRequest(
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(
BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback) {
......
......@@ -22,6 +22,7 @@ namespace background_fetch {
class GetSettledFetchesTask : public DatabaseTask {
public:
// TODO(nator): Remove BlobDataHandle since we're not using them.
using SettledFetchesCallback = base::OnceCallback<void(
blink::mojom::BackgroundFetchError,
bool,
......@@ -58,11 +59,18 @@ class GetSettledFetchesTask : public DatabaseTask {
void FillResponse(BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback);
void FillResponses(base::OnceClosure callback);
void DidMatchRequest(BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback,
blink::mojom::CacheStorageError error,
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;
std::string HistogramName() const override;
......
......@@ -43,9 +43,9 @@ bool StructTraits<blink::mojom::BackgroundFetchRegistrationDataView,
}
// static
bool StructTraits<content::mojom::BackgroundFetchSettledFetchDataView,
bool StructTraits<blink::mojom::BackgroundFetchSettledFetchDataView,
content::BackgroundFetchSettledFetch>::
Read(content::mojom::BackgroundFetchSettledFetchDataView data,
Read(blink::mojom::BackgroundFetchSettledFetchDataView data,
content::BackgroundFetchSettledFetch* fetch) {
return data.ReadRequest(&fetch->request) &&
data.ReadResponse(&fetch->response);
......
......@@ -14,12 +14,6 @@
#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
namespace mojom {
class BackgroundFetchSettledFetchDataView;
}
}
namespace mojo {
template <>
......@@ -77,7 +71,7 @@ struct CONTENT_EXPORT
template <>
struct CONTENT_EXPORT
StructTraits<content::mojom::BackgroundFetchSettledFetchDataView,
StructTraits<blink::mojom::BackgroundFetchSettledFetchDataView,
content::BackgroundFetchSettledFetch> {
static const content::ServiceWorkerFetchRequest& request(
const content::BackgroundFetchSettledFetch& fetch) {
......@@ -89,7 +83,7 @@ struct CONTENT_EXPORT
fetch.response);
}
static bool Read(content::mojom::BackgroundFetchSettledFetchDataView data,
static bool Read(blink::mojom::BackgroundFetchSettledFetchDataView data,
content::BackgroundFetchSettledFetch* definition);
};
......
......@@ -14,5 +14,5 @@ deps = [
type_mappings = [
"blink.mojom.BackgroundFetchOptions=content::BackgroundFetchOptions",
"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
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
// TODO(peter): Move this to Blink.
struct BackgroundFetchSettledFetch {
blink.mojom.FetchAPIRequest request;
blink.mojom.FetchAPIResponse? response;
};
struct ExtendableMessageEvent {
blink.mojom.TransferableMessage message;
url.mojom.Origin source_origin;
......@@ -105,14 +99,14 @@ interface ServiceWorker {
DispatchBackgroundFetchFailEvent(string developer_id,
string unique_id,
blink.mojom.BackgroundFetchState state,
array<BackgroundFetchSettledFetch> fetches)
array<blink.mojom.BackgroundFetchSettledFetch> fetches)
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo_base.mojom.Time dispatch_event_time);
DispatchBackgroundFetchSuccessEvent(
string developer_id,
string unique_id,
blink.mojom.BackgroundFetchState state,
array<BackgroundFetchSettledFetch> fetches)
array<blink.mojom.BackgroundFetchSettledFetch> fetches)
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo_base.mojom.Time dispatch_event_time);
......
......@@ -44,6 +44,8 @@ interface BackgroundFetchRegistration : EventTarget
getter uploaded
method abort
method constructor
method match
method matchAll
setter onprogress
interface BackgroundFetchSettledFetch : BackgroundFetchFetch
attribute @@toStringTag
......
......@@ -5,7 +5,9 @@
module blink.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/mojom/fetch/fetch_api_response.mojom";
import "third_party/blink/public/mojom/manifest/manifest.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
......@@ -19,6 +21,13 @@ enum BackgroundFetchError {
QUOTA_EXCEEDED
};
// Struct representing completed Background Fetch requests, along with their
// responses.
struct BackgroundFetchSettledFetch {
FetchAPIRequest request;
FetchAPIResponse? response;
};
enum BackgroundFetchState {
PENDING,
FAILURE,
......@@ -108,6 +117,18 @@ interface BackgroundFetchService {
GetIconDisplaySize()
=> (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
// that is identified by the |unique_id|.
AddRegistrationObserver(string unique_id,
......
......@@ -46,6 +46,19 @@ void BackgroundFetchBridge::GetIconDisplaySize(
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(
const String& developer_id,
Vector<WebServiceWorkerRequest> requests,
......
......@@ -59,6 +59,20 @@ class BackgroundFetchBridge final
// Gets the size of the icon to be displayed in Background Fetch UI.
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
// |unique_id| with the updated |title| or |icon|. Will invoke the |callback|
// when the interface has been requested to update.
......
......@@ -4,9 +4,17 @@
#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/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_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/manifest/image_resource.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
......@@ -106,15 +114,109 @@ ScriptPromise BackgroundFetchRegistration::abort(ScriptState* script_state) {
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(
ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error) {
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
resolver->Resolve(true /* success */);
resolver->Resolve(/* success = */ true);
return;
case mojom::blink::BackgroundFetchError::INVALID_ID:
resolver->Resolve(false /* success */);
resolver->Resolve(/* success = */ false);
return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
resolver->Reject(DOMException::Create(
......
......@@ -16,9 +16,11 @@
namespace blink {
class CacheQueryOptions;
class ScriptPromiseResolver;
class ScriptState;
class ServiceWorkerRegistration;
class RequestOrUSVString;
// Represents an individual Background Fetch registration. Gives developers
// access to its properties, options, and enables them to abort the fetch.
......@@ -52,6 +54,16 @@ class BackgroundFetchRegistration final
// Web Exposed attribute defined in the IDL file. Corresponds to the
// |developer_id| used elsewhere in the codebase.
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 uploaded() const;
......@@ -76,6 +88,15 @@ class BackgroundFetchRegistration final
private:
void DidAbort(ScriptPromiseResolver* resolver,
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_;
......
......@@ -15,10 +15,13 @@ enum BackgroundFetchState { "pending", "success", "failure" };
readonly attribute unsigned long long downloadTotal;
readonly attribute unsigned long long downloaded;
readonly attribute BackgroundFetchState state;
// TODO(crbug.com/699957): Implement the `activeFetches` attribute.
attribute EventHandler onprogress;
[CallWith=ScriptState] Promise<boolean> abort();
// TODO(crbug.com/863016): Add match() and matchAll().
};
\ No newline at end of file
// TODO(crbug.com/875201): Change to (Window,Worker) once we support
// 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