Commit 34c5fc97 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

Make GetRegistration work with persistent storage

Add a new GetRegistrationTask to be used by BackgroundFetchDataManager
when the persistent storage flag is enabled.

Adds the origin to the proto stored in the database and check it
matches when retrieving a registration, otherwise trigger a storage
error.

Make BackgroundFetchDataManagerTest parameterized by persistence, which
turns on the command line flag. Now all tests run (and pass) with or
without persistence although the Cleanup test doesn't test much yet
since there's no way yet to interact with a non-active fetch.

Bug: 757760
Change-Id: I3aa29e17f9112f282f5672366e52522e549f32d0
Reviewed-on: https://chromium-review.googlesource.com/758762Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#515498}
parent 6db6ef42
......@@ -415,6 +415,8 @@ source_set("browser") {
"background_fetch/storage/database_task.h",
"background_fetch/storage/delete_registration_task.cc",
"background_fetch/storage/delete_registration_task.h",
"background_fetch/storage/get_registration_task.cc",
"background_fetch/storage/get_registration_task.h",
"background_fetch/storage/mark_registration_for_deletion_task.cc",
"background_fetch/storage/mark_registration_for_deletion_task.h",
"background_sync/background_sync_context.cc",
......
......@@ -10,7 +10,7 @@ package content.proto;
// Stores per-registration (as opposed to per-request) data.
//
// Next tag: 4
// Next tag: 5
message BackgroundFetchRegistration {
// See definition of |unique_id| in BackgroundFetchRegistrationId.
optional string unique_id = 1;
......@@ -18,5 +18,7 @@ message BackgroundFetchRegistration {
// See definition of |developer_id| in BackgroundFetchRegistrationId.
optional bytes developer_id = 2;
optional int64 creation_microseconds_since_unix_epoch = 3;
}
\ No newline at end of file
optional string origin = 3;
optional int64 creation_microseconds_since_unix_epoch = 4;
}
......@@ -17,6 +17,7 @@
#include "content/browser/background_fetch/storage/create_registration_task.h"
#include "content/browser/background_fetch/storage/database_task.h"
#include "content/browser/background_fetch/storage/delete_registration_task.h"
#include "content/browser/background_fetch/storage/get_registration_task.h"
#include "content/browser/background_fetch/storage/mark_registration_for_deletion_task.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
......@@ -245,6 +246,14 @@ void BackgroundFetchDataManager::GetRegistration(
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableBackgroundFetchPersistence)) {
AddDatabaseTask(std::make_unique<background_fetch::GetRegistrationTask>(
this, service_worker_registration_id, origin, developer_id,
std::move(callback)));
return;
}
auto developer_id_tuple =
std::make_tuple(service_worker_registration_id, origin, developer_id);
......
......@@ -70,19 +70,35 @@ void CreateRegistrationTask::DidGetUniqueId(
}
void CreateRegistrationTask::StoreRegistration() {
DCHECK(!registration_);
DCHECK(!registration_id_.origin().unique());
int64_t registration_creation_microseconds_since_unix_epoch =
(base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds();
registration_ = std::make_unique<BackgroundFetchRegistration>();
registration_->developer_id = registration_id_.developer_id();
registration_->unique_id = registration_id_.unique_id();
registration_->icons = options_.icons;
registration_->title = options_.title;
// TODO(crbug.com/774054): Uploads are not yet supported.
registration_->upload_total = 0;
registration_->uploaded = 0;
registration_->download_total = options_.download_total;
registration_->downloaded = 0;
std::vector<std::pair<std::string, std::string>> entries;
entries.reserve(requests_.size() * 2 + 1);
// First serialize per-registration (as opposed to per-request) data.
// TODO(crbug.com/757760): Serialize BackgroundFetchOptions as part of this.
proto::BackgroundFetchRegistration registration_proto;
registration_proto.set_unique_id(registration_id_.unique_id());
registration_proto.set_developer_id(registration_id_.developer_id());
registration_proto.set_unique_id(registration_->unique_id);
registration_proto.set_developer_id(registration_->developer_id);
registration_proto.set_origin(registration_id_.origin().Serialize());
registration_proto.set_creation_microseconds_since_unix_epoch(
registration_creation_microseconds_since_unix_epoch);
// TODO(delphick): Write options to the proto.
std::string serialized_registration_proto;
if (!registration_proto.SerializeToString(&serialized_registration_proto)) {
// TODO(crbug.com/780025): Log failures to UMA.
......@@ -117,6 +133,8 @@ void CreateRegistrationTask::StoreRegistration() {
void CreateRegistrationTask::DidStoreRegistration(
ServiceWorkerStatusCode status) {
DCHECK(registration_);
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
......@@ -129,19 +147,8 @@ void CreateRegistrationTask::DidStoreRegistration(
return;
}
auto registration = std::make_unique<BackgroundFetchRegistration>();
registration->developer_id = registration_id_.developer_id();
registration->unique_id = registration_id_.unique_id();
registration->icons = options_.icons;
registration->title = options_.title;
// TODO(crbug.com/774054): Uploads are not yet supported.
registration->upload_total = 0;
registration->uploaded = 0;
registration->download_total = options_.download_total;
registration->downloaded = 0;
std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
std::move(registration));
std::move(registration_));
Finished(); // Destroys |this|.
}
} // namespace background_fetch
......
......@@ -48,6 +48,8 @@ class CreateRegistrationTask : public DatabaseTask {
BackgroundFetchOptions options_;
CreateRegistrationCallback callback_;
std::unique_ptr<BackgroundFetchRegistration> registration_;
base::WeakPtrFactory<CreateRegistrationTask> weak_factory_; // Keep as last.
DISALLOW_COPY_AND_ASSIGN(CreateRegistrationTask);
......
// Copyright 2017 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/storage/get_registration_task.h"
#include <utility>
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "url/gurl.h"
namespace content {
namespace background_fetch {
GetRegistrationTask::GetRegistrationTask(
BackgroundFetchDataManager* data_manager,
int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
GetRegistrationCallback callback)
: DatabaseTask(data_manager),
service_worker_registration_id_(service_worker_registration_id),
origin_(origin),
developer_id_(developer_id),
callback_(std::move(callback)),
weak_factory_(this) {}
GetRegistrationTask::~GetRegistrationTask() = default;
void GetRegistrationTask::Start() {
service_worker_context()->GetRegistrationUserData(
service_worker_registration_id_,
{ActiveRegistrationUniqueIdKey(developer_id_)},
base::Bind(&GetRegistrationTask::DidGetUniqueId,
weak_factory_.GetWeakPtr()));
}
void GetRegistrationTask::DidGetUniqueId(const std::vector<std::string>& data,
ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID,
nullptr /* registration */);
Finished(); // Destroys |this|.
return;
case DatabaseStatus::kOk:
DCHECK_EQ(1u, data.size());
service_worker_context()->GetRegistrationUserData(
service_worker_registration_id_, {RegistrationKey(data[0])},
base::Bind(&GetRegistrationTask::DidGetRegistration,
weak_factory_.GetWeakPtr()));
return;
case DatabaseStatus::kFailed:
std::move(callback_).Run(
blink::mojom::BackgroundFetchError::STORAGE_ERROR,
nullptr /* registration */);
Finished(); // Destroys |this|.
return;
}
}
void GetRegistrationTask::DidGetRegistration(
const std::vector<std::string>& data,
ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
// The database is corrupt as there's no registration data despite there
// being an active developer_id pointing to it.
std::move(callback_).Run(
blink::mojom::BackgroundFetchError::STORAGE_ERROR,
nullptr /* registration */);
Finished(); // Destroys |this|.
return;
case DatabaseStatus::kOk:
DCHECK_EQ(1u, data.size());
CreateRegistration(data[0]);
return;
case DatabaseStatus::kFailed:
std::move(callback_).Run(
blink::mojom::BackgroundFetchError::STORAGE_ERROR,
nullptr /* registration */);
Finished(); // Destroys |this|.
return;
}
}
void GetRegistrationTask::CreateRegistration(
const std::string& registration_data) {
proto::BackgroundFetchRegistration registration_proto;
if (!registration_proto.ParseFromString(registration_data)) {
std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
nullptr /* registration */);
Finished();
return;
}
auto registration = std::make_unique<BackgroundFetchRegistration>();
if (registration_proto.developer_id() != developer_id_ ||
!origin_.IsSameOriginWith(
url::Origin::Create(GURL(registration_proto.origin())))) {
std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
nullptr /* registration */);
Finished();
return;
}
registration->developer_id = registration_proto.developer_id();
registration->unique_id = registration_proto.unique_id();
// TODO(delphick): Initialize all the other parts of the registration once
// they're persisted.
std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
std::move(registration));
Finished();
}
} // namespace background_fetch
} // namespace content
// Copyright 2017 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_STORAGE_GET_REGISTRATION_TASK_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_REGISTRATION_TASK_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "content/browser/background_fetch/storage/database_task.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "url/origin.h"
namespace content {
namespace background_fetch {
// Gets an active Background Fetch registration entry from the database.
class GetRegistrationTask : public DatabaseTask {
public:
using GetRegistrationCallback =
base::OnceCallback<void(blink::mojom::BackgroundFetchError,
std::unique_ptr<BackgroundFetchRegistration>)>;
GetRegistrationTask(BackgroundFetchDataManager* data_manager,
int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
GetRegistrationCallback callback);
~GetRegistrationTask() override;
// DatabaseTask implementation:
void Start() override;
private:
void DidGetUniqueId(const std::vector<std::string>& data,
ServiceWorkerStatusCode status);
void DidGetRegistration(const std::vector<std::string>& data,
ServiceWorkerStatusCode status);
void CreateRegistration(const std::string& registration_data);
int64_t service_worker_registration_id_;
url::Origin origin_;
std::string developer_id_;
GetRegistrationCallback callback_;
base::WeakPtrFactory<GetRegistrationTask> weak_factory_; // Keep as last.
DISALLOW_COPY_AND_ASSIGN(GetRegistrationTask);
};
} // namespace background_fetch
} // namespace content
#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_REGISTRATION_TASK_H_
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