| Index: content/browser/payments/payment_app_info_fetcher.cc
|
| diff --git a/content/browser/payments/payment_app_info_fetcher.cc b/content/browser/payments/payment_app_info_fetcher.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f4d68e87d696e6587138409d3daf4b4ec1f5939c
|
| --- /dev/null
|
| +++ b/content/browser/payments/payment_app_info_fetcher.cc
|
| @@ -0,0 +1,157 @@
|
| +// 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/payments/payment_app_info_fetcher.h"
|
| +
|
| +#include "base/base64.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "content/browser/frame_host/render_frame_host_impl.h"
|
| +#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
| +#include "content/browser/web_contents/web_contents_impl.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/manifest_icon_downloader.h"
|
| +#include "content/public/browser/manifest_icon_selector.h"
|
| +#include "ui/gfx/image/image.h"
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +// TODO(gogerald): Choose appropriate icon size dynamically on different
|
| +// platforms.
|
| +const int kPaymentAppIdealIconSize = 64;
|
| +const int kPaymentAppMinimumIconSize = 0;
|
| +
|
| +} // namespace
|
| +
|
| +PaymentAppInfoFetcher::PaymentAppInfoFetcher()
|
| + : context_process_id_(-1), context_frame_id_(-1) {}
|
| +PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {}
|
| +
|
| +void PaymentAppInfoFetcher::Start(
|
| + const GURL& context_url,
|
| + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
|
| + PaymentAppInfoFetchCallback callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| +
|
| + context_url_ = context_url;
|
| + callback_ = std::move(callback);
|
| +
|
| + std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts =
|
| + service_worker_context->GetProviderHostIds(context_url.GetOrigin());
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::BindOnce(&PaymentAppInfoFetcher::StartFromUIThread, this,
|
| + std::move(provider_hosts)));
|
| +}
|
| +
|
| +void PaymentAppInfoFetcher::StartFromUIThread(
|
| + const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + if (provider_hosts->size() == 0U) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + for (const auto& frame : *provider_hosts) {
|
| + RenderFrameHostImpl* render_frame_host =
|
| + RenderFrameHostImpl::FromID(frame.first, frame.second);
|
| + if (!render_frame_host)
|
| + continue;
|
| +
|
| + WebContentsImpl* web_content = static_cast<WebContentsImpl*>(
|
| + WebContents::FromRenderFrameHost(render_frame_host));
|
| + if (!web_content || web_content->IsHidden() ||
|
| + context_url_.spec().compare(
|
| + web_content->GetLastCommittedURL().spec()) != 0) {
|
| + continue;
|
| + }
|
| +
|
| + context_process_id_ = frame.first;
|
| + context_frame_id_ = frame.second;
|
| +
|
| + web_content->GetManifest(base::Bind(
|
| + &PaymentAppInfoFetcher::FetchPaymentAppManifestCallback, this));
|
| + return;
|
| + }
|
| +
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| +}
|
| +
|
| +void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback(
|
| + const GURL& url,
|
| + const Manifest& manifest) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + if (url.is_empty() || manifest.IsEmpty()) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + if (manifest.name.is_null() ||
|
| + !base::UTF16ToUTF8(manifest.name.string().c_str(),
|
| + manifest.name.string().length(),
|
| + &fetched_payment_app_name_)) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + GURL icon_url = ManifestIconSelector::FindBestMatchingIcon(
|
| + manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize,
|
| + Manifest::Icon::ANY);
|
| + if (!icon_url.is_valid()) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + RenderFrameHostImpl* render_frame_host =
|
| + RenderFrameHostImpl::FromID(context_process_id_, context_frame_id_);
|
| + if (!render_frame_host) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + WebContents* web_content =
|
| + WebContents::FromRenderFrameHost(render_frame_host);
|
| + if (!web_content) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + if (!content::ManifestIconDownloader::Download(
|
| + web_content, icon_url, kPaymentAppIdealIconSize,
|
| + kPaymentAppMinimumIconSize,
|
| + base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this))) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + }
|
| +}
|
| +
|
| +void PaymentAppInfoFetcher::OnIconFetched(const SkBitmap& icon) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + if (icon.drawsNothing()) {
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| + return;
|
| + }
|
| +
|
| + 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()),
|
| + &fetched_payment_app_icon_);
|
| + PostPaymentAppInfoFetchResultToIOThread();
|
| +}
|
| +
|
| +void PaymentAppInfoFetcher::PostPaymentAppInfoFetchResultToIOThread() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| +
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::BindOnce(std::move(callback_), fetched_payment_app_name_,
|
| + fetched_payment_app_icon_));
|
| +}
|
| +
|
| +} // namespace content
|
|
|