Commit 7c5880c5 authored by Sahel Sharify's avatar Sahel Sharify Committed by Commit Bot

[Payment] Write the refetched missing icon into payment app database.

In https://chromium-review.googlesource.com/c/chromium/src/+/2264860
Chrome crawls to refetch missing icons of already installed PHs. In this
cl the new icon is written to database.

Screencast of the fix is added to the bug:
https://bugs.chromium.org/p/chromium/issues/detail?id=1069010#c21

Bug: 1069010
Change-Id: I4c10a8fa6c96155e17189555151db2239b985170
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2268644Reviewed-by: default avatarDanyao Wang <danyao@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Commit-Queue: Sahel Sharify <sahel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#783826}
parent a7fa8d30
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
namespace payments { namespace payments {
RefetchedIcon::RefetchedIcon() = default;
RefetchedIcon::~RefetchedIcon() = default;
// TODO(crbug.com/782270): Use cache to accelerate crawling procedure. // TODO(crbug.com/782270): Use cache to accelerate crawling procedure.
InstallablePaymentAppCrawler::InstallablePaymentAppCrawler( InstallablePaymentAppCrawler::InstallablePaymentAppCrawler(
const url::Origin& merchant_origin, const url::Origin& merchant_origin,
...@@ -514,8 +517,11 @@ void InstallablePaymentAppCrawler::OnPaymentWebAppIconDownloadAndDecoded( ...@@ -514,8 +517,11 @@ void InstallablePaymentAppCrawler::OnPaymentWebAppIconDownloadAndDecoded(
"\" for payment handler manifest \"" + "\" for payment handler manifest \"" +
method_manifest_url.spec() + "\"."); method_manifest_url.spec() + "\".");
} else { } else {
refetched_icons_.insert(std::pair<GURL, std::unique_ptr<SkBitmap>>( auto refetched_icon = std::make_unique<RefetchedIcon>();
web_app_manifest_url, std::make_unique<SkBitmap>(icon))); refetched_icon->method_name = method_manifest_url.spec();
refetched_icon->icon = std::make_unique<SkBitmap>(icon);
refetched_icons_.insert(
std::make_pair(web_app_manifest_url, std::move(refetched_icon)));
} }
} }
......
...@@ -33,6 +33,13 @@ class WebContents; ...@@ -33,6 +33,13 @@ class WebContents;
namespace payments { namespace payments {
struct RefetchedIcon {
RefetchedIcon();
~RefetchedIcon();
std::string method_name;
std::unique_ptr<SkBitmap> icon;
};
// Crawls installable web payment apps. First, fetches and parses the payment // Crawls installable web payment apps. First, fetches and parses the payment
// method manifests to get 'default_applications' manifest urls. Then, fetches // method manifests to get 'default_applications' manifest urls. Then, fetches
// and parses the web app manifests to get the installable payment apps' info. // and parses the web app manifests to get the installable payment apps' info.
...@@ -40,7 +47,7 @@ class InstallablePaymentAppCrawler : public content::WebContentsObserver { ...@@ -40,7 +47,7 @@ class InstallablePaymentAppCrawler : public content::WebContentsObserver {
public: public:
using FinishedCrawlingCallback = base::OnceCallback<void( using FinishedCrawlingCallback = base::OnceCallback<void(
std::map<GURL, std::unique_ptr<WebAppInstallationInfo>>, std::map<GURL, std::unique_ptr<WebAppInstallationInfo>>,
std::map<GURL, std::unique_ptr<SkBitmap>>, std::map<GURL, std::unique_ptr<RefetchedIcon>>,
const std::string& error_message)>; const std::string& error_message)>;
enum class CrawlingMode { enum class CrawlingMode {
...@@ -138,7 +145,7 @@ class InstallablePaymentAppCrawler : public content::WebContentsObserver { ...@@ -138,7 +145,7 @@ class InstallablePaymentAppCrawler : public content::WebContentsObserver {
size_t number_of_web_app_icons_to_download_and_decode_; size_t number_of_web_app_icons_to_download_and_decode_;
std::set<GURL> downloaded_web_app_manifests_; std::set<GURL> downloaded_web_app_manifests_;
std::map<GURL, std::unique_ptr<WebAppInstallationInfo>> installable_apps_; std::map<GURL, std::unique_ptr<WebAppInstallationInfo>> installable_apps_;
std::map<GURL, std::unique_ptr<SkBitmap>> refetched_icons_; std::map<GURL, std::unique_ptr<RefetchedIcon>> refetched_icons_;
std::set<GURL> method_manifest_urls_for_icon_refetch_; std::set<GURL> method_manifest_urls_for_icon_refetch_;
// The first error message (if any) to be forwarded to the merchant when // The first error message (if any) to be forwarded to the merchant when
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "base/base64.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/check.h" #include "base/check.h"
...@@ -25,11 +26,13 @@ ...@@ -25,11 +26,13 @@
#include "components/payments/core/url_util.h" #include "components/payments/core/url_util.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/payment_app_provider.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h" #include "content/public/browser/storage_partition.h"
#include "content/public/browser/stored_payment_app.h" #include "content/public/browser/stored_payment_app.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "ui/gfx/image/image.h"
#include "url/url_canon.h" #include "url/url_canon.h"
namespace payments { namespace payments {
...@@ -270,13 +273,14 @@ class SelfDeletingServiceWorkerPaymentAppFinder ...@@ -270,13 +273,14 @@ class SelfDeletingServiceWorkerPaymentAppFinder
void OnPaymentAppsCrawled( void OnPaymentAppsCrawled(
std::map<GURL, std::unique_ptr<WebAppInstallationInfo>> apps_info, std::map<GURL, std::unique_ptr<WebAppInstallationInfo>> apps_info,
std::map<GURL, std::unique_ptr<SkBitmap>> refetched_icons, std::map<GURL, std::unique_ptr<RefetchedIcon>> refetched_icons,
const std::string& error_message) { const std::string& error_message) {
if (first_error_message_.empty()) if (first_error_message_.empty())
first_error_message_ = error_message; first_error_message_ = error_message;
for (auto& refetched_icon : refetched_icons) { for (auto& refetched_icon : refetched_icons) {
GURL web_app_manifest_url = refetched_icon.first; GURL web_app_manifest_url = refetched_icon.first;
RefetchedIcon* data = refetched_icon.second.get();
for (auto& app : installed_apps_) { for (auto& app : installed_apps_) {
// It is possible (unlikely) to have multiple apps with same origins. // It is possible (unlikely) to have multiple apps with same origins.
// The proper validation is to store web_app_manifest_url in // The proper validation is to store web_app_manifest_url in
...@@ -284,9 +288,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder ...@@ -284,9 +288,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder
// web_app_manifest_url from which icon is fetched. // web_app_manifest_url from which icon is fetched.
if (crawler_->IsSameOriginWith(GURL(app.second->scope), if (crawler_->IsSameOriginWith(GURL(app.second->scope),
web_app_manifest_url)) { web_app_manifest_url)) {
// TODO(crbug.com/1069010): Update the payment app database with the UpdatePaymentAppIcon(app.second, data->icon, data->method_name);
// new icon. app.second->icon = std::move(data->icon);
app.second->icon = std::move(refetched_icon.second);
break; break;
} }
} }
...@@ -295,6 +298,38 @@ class SelfDeletingServiceWorkerPaymentAppFinder ...@@ -295,6 +298,38 @@ class SelfDeletingServiceWorkerPaymentAppFinder
first_error_message_); first_error_message_);
} }
void UpdatePaymentAppIcon(
const std::unique_ptr<content::StoredPaymentApp>& app,
const std::unique_ptr<SkBitmap>& icon,
const std::string& method_name) {
number_of_app_icons_to_update_++;
DCHECK(!icon->empty());
std::string string_encoded_icon;
gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(*(icon));
scoped_refptr<base::RefCountedMemory> raw_data =
decoded_image.As1xPNGBytes();
base::Base64Encode(
base::StringPiece(raw_data->front_as<char>(), raw_data->size()),
&string_encoded_icon);
auto* browser_context =
static_cast<content::WebContents*>(owner_)->GetBrowserContext();
content::PaymentAppProvider::GetInstance()->UpdatePaymentAppIcon(
browser_context, app->registration_id, app->scope.spec(), app->name,
string_encoded_icon, method_name, app->supported_delegations,
base::BindOnce(
&SelfDeletingServiceWorkerPaymentAppFinder::OnUpdatePaymentAppIcon,
weak_ptr_factory_.GetWeakPtr()));
}
void OnUpdatePaymentAppIcon(payments::mojom::PaymentHandlerStatus status) {
DCHECK(number_of_app_icons_to_update_ > 0);
number_of_app_icons_to_update_--;
if (number_of_app_icons_to_update_ == 0)
FinishUsingResourcesIfReady();
}
void OnPaymentAppsCrawlerFinishedUsingResources() { void OnPaymentAppsCrawlerFinishedUsingResources() {
crawler_.reset(); crawler_.reset();
...@@ -312,7 +347,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder ...@@ -312,7 +347,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder
void FinishUsingResourcesIfReady() { void FinishUsingResourcesIfReady() {
if (is_payment_verifier_finished_using_resources_ && if (is_payment_verifier_finished_using_resources_ &&
is_payment_app_crawler_finished_using_resources_ && is_payment_app_crawler_finished_using_resources_ &&
!finished_using_resources_callback_.is_null()) { !finished_using_resources_callback_.is_null() &&
number_of_app_icons_to_update_ == 0) {
downloader_.reset(); downloader_.reset();
parser_.reset(); parser_.reset();
std::move(finished_using_resources_callback_).Run(); std::move(finished_using_resources_callback_).Run();
...@@ -348,6 +384,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder ...@@ -348,6 +384,8 @@ class SelfDeletingServiceWorkerPaymentAppFinder
content::PaymentAppProvider::PaymentApps installed_apps_; content::PaymentAppProvider::PaymentApps installed_apps_;
size_t number_of_app_icons_to_update_ = 0;
base::WeakPtrFactory<SelfDeletingServiceWorkerPaymentAppFinder> base::WeakPtrFactory<SelfDeletingServiceWorkerPaymentAppFinder>
weak_ptr_factory_{this}; weak_ptr_factory_{this};
}; };
......
...@@ -417,6 +417,31 @@ void GetAllPaymentAppsOnCoreThread( ...@@ -417,6 +417,31 @@ void GetAllPaymentAppsOnCoreThread(
base::BindOnce(&DidGetAllPaymentAppsOnCoreThread, std::move(callback))); base::BindOnce(&DidGetAllPaymentAppsOnCoreThread, std::move(callback)));
} }
void DidUpdatePaymentAppIconOnCoreThread(
PaymentAppProvider::UpdatePaymentAppIconCallback callback,
payments::mojom::PaymentHandlerStatus status) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), status));
}
void UpdatePaymentAppIconOnCoreThread(
scoped_refptr<PaymentAppContextImpl> payment_app_context,
int64_t registration_id,
const std::string& instrument_key,
const std::string& name,
const std::string& string_encoded_icon,
const std::string& method_name,
const SupportedDelegations& supported_delegations,
PaymentAppProvider::UpdatePaymentAppIconCallback callback) {
DCHECK_CURRENTLY_ON(content::ServiceWorkerContext::GetCoreThreadId());
payment_app_context->payment_app_database()
->SetPaymentAppInfoForRegisteredServiceWorker(
registration_id, instrument_key, name, string_encoded_icon,
method_name, supported_delegations,
base::BindOnce(&DidUpdatePaymentAppIconOnCoreThread,
std::move(callback)));
}
void DispatchAbortPaymentEvent( void DispatchAbortPaymentEvent(
BrowserContext* browser_context, BrowserContext* browser_context,
PaymentAppProvider::AbortCallback callback, PaymentAppProvider::AbortCallback callback,
...@@ -891,6 +916,27 @@ void PaymentAppProviderImpl::InstallAndInvokePaymentApp( ...@@ -891,6 +916,27 @@ void PaymentAppProviderImpl::InstallAndInvokePaymentApp(
std::move(callback))); std::move(callback)));
} }
void PaymentAppProviderImpl::UpdatePaymentAppIcon(
BrowserContext* browser_context,
int64_t registration_id,
const std::string& instrument_key,
const std::string& name,
const std::string& string_encoded_icon,
const std::string& method_name,
const SupportedDelegations& supported_delegations,
PaymentAppProvider::UpdatePaymentAppIconCallback callback) {
StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(browser_context));
scoped_refptr<PaymentAppContextImpl> payment_app_context =
partition->GetPaymentAppContext();
RunOrPostTaskOnThread(
FROM_HERE, content::ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&UpdatePaymentAppIconOnCoreThread, payment_app_context,
registration_id, instrument_key, name, string_encoded_icon,
method_name, supported_delegations, std::move(callback)));
}
void PaymentAppProviderImpl::CanMakePayment( void PaymentAppProviderImpl::CanMakePayment(
WebContents* web_contents, WebContents* web_contents,
int64_t registration_id, int64_t registration_id,
......
...@@ -42,6 +42,14 @@ class CONTENT_EXPORT PaymentAppProviderImpl : public PaymentAppProvider { ...@@ -42,6 +42,14 @@ class CONTENT_EXPORT PaymentAppProviderImpl : public PaymentAppProvider {
const SupportedDelegations& supported_delegations, const SupportedDelegations& supported_delegations,
RegistrationIdCallback registration_id_callback, RegistrationIdCallback registration_id_callback,
InvokePaymentAppCallback callback) override; InvokePaymentAppCallback callback) override;
void UpdatePaymentAppIcon(BrowserContext* browser_context,
int64_t registration_id,
const std::string& instrument_key,
const std::string& name,
const std::string& string_encoded_icon,
const std::string& method_name,
const SupportedDelegations& supported_delegations,
UpdatePaymentAppIconCallback callback) override;
void CanMakePayment(WebContents* web_contents, void CanMakePayment(WebContents* web_contents,
int64_t registration_id, int64_t registration_id,
const url::Origin& sw_origin, const url::Origin& sw_origin,
......
...@@ -49,6 +49,8 @@ class CONTENT_EXPORT PaymentAppProvider { ...@@ -49,6 +49,8 @@ class CONTENT_EXPORT PaymentAppProvider {
using CanMakePaymentCallback = using CanMakePaymentCallback =
base::OnceCallback<void(payments::mojom::CanMakePaymentResponsePtr)>; base::OnceCallback<void(payments::mojom::CanMakePaymentResponsePtr)>;
using AbortCallback = base::OnceCallback<void(bool)>; using AbortCallback = base::OnceCallback<void(bool)>;
using UpdatePaymentAppIconCallback =
base::OnceCallback<void(payments::mojom::PaymentHandlerStatus status)>;
// Should be accessed only on the UI thread. // Should be accessed only on the UI thread.
virtual void GetAllPaymentApps(BrowserContext* browser_context, virtual void GetAllPaymentApps(BrowserContext* browser_context,
...@@ -71,6 +73,15 @@ class CONTENT_EXPORT PaymentAppProvider { ...@@ -71,6 +73,15 @@ class CONTENT_EXPORT PaymentAppProvider {
const SupportedDelegations& supported_delegations, const SupportedDelegations& supported_delegations,
RegistrationIdCallback registration_id_callback, RegistrationIdCallback registration_id_callback,
InvokePaymentAppCallback callback) = 0; InvokePaymentAppCallback callback) = 0;
virtual void UpdatePaymentAppIcon(
BrowserContext* browser_context,
int64_t registration_id,
const std::string& instrument_key,
const std::string& name,
const std::string& string_encoded_icon,
const std::string& method_name,
const SupportedDelegations& supported_delegations,
UpdatePaymentAppIconCallback callback) = 0;
virtual void CanMakePayment( virtual void CanMakePayment(
WebContents* web_contents, WebContents* web_contents,
int64_t registration_id, int64_t registration_id,
......
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