blob: 1809cc398d9fa3abf405902f41b5b7e637e78e55 [file] [log] [blame]
// Copyright 2016 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/payments/payment_app_database.h"
#include <utility>
#include "base/bind.h"
#include "base/optional.h"
#include "content/browser/payments/payment_app.pb.h"
#include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/public/browser/browser_thread.h"
namespace content {
namespace {
const char kPaymentAppManifestDataKey[] = "PaymentAppManifestData";
payments::mojom::PaymentAppManifestPtr DeserializePaymentAppManifest(
const std::string& input) {
PaymentAppManifestProto manifest_proto;
if (!manifest_proto.ParseFromString(input))
return nullptr;
payments::mojom::PaymentAppManifestPtr manifest =
payments::mojom::PaymentAppManifest::New();
manifest->name = manifest_proto.name();
if (manifest_proto.has_icon())
manifest->icon = manifest_proto.icon();
for (const auto& option_proto : manifest_proto.options()) {
payments::mojom::PaymentAppOptionPtr option =
payments::mojom::PaymentAppOption::New();
option->name = option_proto.name();
if (option_proto.has_icon())
option->icon = option_proto.icon();
option->id = option_proto.id();
for (const auto& method : option_proto.enabled_methods())
option->enabled_methods.push_back(method);
manifest->options.push_back(std::move(option));
}
return manifest;
}
} // namespace
PaymentAppDatabase::PaymentAppDatabase(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
: service_worker_context_(service_worker_context), weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
PaymentAppDatabase::~PaymentAppDatabase() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
void PaymentAppDatabase::WriteManifest(
const GURL& scope,
payments::mojom::PaymentAppManifestPtr manifest,
const WriteManifestCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->FindReadyRegistrationForPattern(
scope, base::Bind(&PaymentAppDatabase::DidFindRegistrationToWriteManifest,
weak_ptr_factory_.GetWeakPtr(),
base::Passed(std::move(manifest)), callback));
}
void PaymentAppDatabase::ReadManifest(const GURL& scope,
const ReadManifestCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->FindReadyRegistrationForPattern(
scope, base::Bind(&PaymentAppDatabase::DidFindRegistrationToReadManifest,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void PaymentAppDatabase::ReadAllManifests(
const ReadAllManifestsCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->GetUserDataForAllRegistrations(
kPaymentAppManifestDataKey,
base::Bind(&PaymentAppDatabase::DidReadAllManifests,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void PaymentAppDatabase::DidFindRegistrationToWriteManifest(
payments::mojom::PaymentAppManifestPtr manifest,
const WriteManifestCallback& callback,
ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK) {
callback.Run(payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
return;
}
PaymentAppManifestProto manifest_proto;
manifest_proto.set_name(manifest->name);
if (manifest->icon)
manifest_proto.set_icon(manifest->icon.value());
for (const auto& option : manifest->options) {
PaymentAppOptionProto* option_proto = manifest_proto.add_options();
option_proto->set_name(option->name);
if (option->icon)
option_proto->set_icon(option->icon.value());
option_proto->set_id(option->id);
for (const auto& method : option->enabled_methods) {
option_proto->add_enabled_methods(method);
}
}
std::string serialized;
bool success = manifest_proto.SerializeToString(&serialized);
DCHECK(success);
service_worker_context_->StoreRegistrationUserData(
registration->id(), registration->pattern().GetOrigin(),
{{kPaymentAppManifestDataKey, serialized}},
base::Bind(&PaymentAppDatabase::DidWriteManifest,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void PaymentAppDatabase::DidWriteManifest(const WriteManifestCallback& callback,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return callback.Run(status == SERVICE_WORKER_OK
? payments::mojom::PaymentAppManifestError::NONE
: payments::mojom::PaymentAppManifestError::
MANIFEST_STORAGE_OPERATION_FAILED);
}
void PaymentAppDatabase::DidFindRegistrationToReadManifest(
const ReadManifestCallback& callback,
ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK) {
callback.Run(payments::mojom::PaymentAppManifest::New(),
payments::mojom::PaymentAppManifestError::NO_ACTIVE_WORKER);
return;
}
service_worker_context_->GetRegistrationUserData(
registration->id(), {kPaymentAppManifestDataKey},
base::Bind(&PaymentAppDatabase::DidReadManifest,
weak_ptr_factory_.GetWeakPtr(), callback));
}
void PaymentAppDatabase::DidReadManifest(const ReadManifestCallback& callback,
const std::vector<std::string>& data,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK || data.size() != 1) {
callback.Run(payments::mojom::PaymentAppManifest::New(),
payments::mojom::PaymentAppManifestError::
MANIFEST_STORAGE_OPERATION_FAILED);
return;
}
payments::mojom::PaymentAppManifestPtr manifest =
DeserializePaymentAppManifest(data[0]);
if (!manifest) {
callback.Run(payments::mojom::PaymentAppManifest::New(),
payments::mojom::PaymentAppManifestError::
MANIFEST_STORAGE_OPERATION_FAILED);
return;
}
callback.Run(std::move(manifest),
payments::mojom::PaymentAppManifestError::NONE);
}
void PaymentAppDatabase::DidReadAllManifests(
const ReadAllManifestsCallback& callback,
const std::vector<std::pair<int64_t, std::string>>& raw_data,
ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (status != SERVICE_WORKER_OK) {
callback.Run(Manifests());
return;
}
Manifests manifests;
for (const auto& item_of_raw_data : raw_data) {
payments::mojom::PaymentAppManifestPtr manifest =
DeserializePaymentAppManifest(item_of_raw_data.second);
if (!manifest)
continue;
manifests.push_back(
ManifestWithID(item_of_raw_data.first, std::move(manifest)));
}
callback.Run(std::move(manifests));
}
} // namespace content