OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/browser/payments/payment_app_info_fetcher.h" |
| 6 |
| 7 #include "base/base64.h" |
| 8 #include "base/bind_helpers.h" |
| 9 #include "content/browser/frame_host/render_frame_host_impl.h" |
| 10 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 11 #include "content/browser/web_contents/web_contents_impl.h" |
| 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/browser/manifest_icon_downloader.h" |
| 14 #include "content/public/browser/manifest_icon_selector.h" |
| 15 #include "ui/gfx/image/image.h" |
| 16 |
| 17 namespace content { |
| 18 |
| 19 namespace { |
| 20 |
| 21 // TODO(gogerald): Choose appropriate icon size dynamically on different |
| 22 // platforms. |
| 23 const int kPaymentAppIdealIconSize = 64; |
| 24 const int kPaymentAppMinimumIconSize = 0; |
| 25 |
| 26 } // namespace |
| 27 |
| 28 PaymentAppInfoFetcher::PaymentAppInfoFetcher() |
| 29 : context_process_id_(-1), context_frame_id_(-1) {} |
| 30 PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {} |
| 31 |
| 32 void PaymentAppInfoFetcher::Start( |
| 33 const GURL& context_url, |
| 34 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, |
| 35 PaymentAppInfoFetchCallback callback) { |
| 36 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 37 |
| 38 context_url_ = context_url; |
| 39 callback_ = std::move(callback); |
| 40 |
| 41 std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts = |
| 42 service_worker_context->GetProviderHostIds(context_url.GetOrigin()); |
| 43 |
| 44 BrowserThread::PostTask( |
| 45 BrowserThread::UI, FROM_HERE, |
| 46 base::BindOnce(&PaymentAppInfoFetcher::StartFromUIThread, this, |
| 47 std::move(provider_hosts))); |
| 48 } |
| 49 |
| 50 void PaymentAppInfoFetcher::StartFromUIThread( |
| 51 const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts) { |
| 52 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 53 |
| 54 if (provider_hosts->size() == 0U) { |
| 55 PostPaymentAppInfoFetchResultToIOThread(); |
| 56 return; |
| 57 } |
| 58 |
| 59 for (const auto& frame : *provider_hosts) { |
| 60 RenderFrameHostImpl* render_frame_host = |
| 61 RenderFrameHostImpl::FromID(frame.first, frame.second); |
| 62 if (!render_frame_host) |
| 63 continue; |
| 64 |
| 65 WebContentsImpl* web_content = static_cast<WebContentsImpl*>( |
| 66 WebContents::FromRenderFrameHost(render_frame_host)); |
| 67 if (!web_content || web_content->IsHidden() || |
| 68 context_url_.spec().compare( |
| 69 web_content->GetLastCommittedURL().spec()) != 0) { |
| 70 continue; |
| 71 } |
| 72 |
| 73 context_process_id_ = frame.first; |
| 74 context_frame_id_ = frame.second; |
| 75 |
| 76 web_content->GetManifest(base::Bind( |
| 77 &PaymentAppInfoFetcher::FetchPaymentAppManifestCallback, this)); |
| 78 return; |
| 79 } |
| 80 |
| 81 PostPaymentAppInfoFetchResultToIOThread(); |
| 82 } |
| 83 |
| 84 void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback( |
| 85 const GURL& url, |
| 86 const Manifest& manifest) { |
| 87 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 88 |
| 89 if (url.is_empty() || manifest.IsEmpty()) { |
| 90 PostPaymentAppInfoFetchResultToIOThread(); |
| 91 return; |
| 92 } |
| 93 |
| 94 if (manifest.name.is_null() || |
| 95 !base::UTF16ToUTF8(manifest.name.string().c_str(), |
| 96 manifest.name.string().length(), |
| 97 &fetched_payment_app_name_)) { |
| 98 PostPaymentAppInfoFetchResultToIOThread(); |
| 99 return; |
| 100 } |
| 101 |
| 102 GURL icon_url = ManifestIconSelector::FindBestMatchingIcon( |
| 103 manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize, |
| 104 Manifest::Icon::ANY); |
| 105 if (!icon_url.is_valid()) { |
| 106 PostPaymentAppInfoFetchResultToIOThread(); |
| 107 return; |
| 108 } |
| 109 |
| 110 RenderFrameHostImpl* render_frame_host = |
| 111 RenderFrameHostImpl::FromID(context_process_id_, context_frame_id_); |
| 112 if (!render_frame_host) { |
| 113 PostPaymentAppInfoFetchResultToIOThread(); |
| 114 return; |
| 115 } |
| 116 |
| 117 WebContents* web_content = |
| 118 WebContents::FromRenderFrameHost(render_frame_host); |
| 119 if (!web_content) { |
| 120 PostPaymentAppInfoFetchResultToIOThread(); |
| 121 return; |
| 122 } |
| 123 |
| 124 if (!content::ManifestIconDownloader::Download( |
| 125 web_content, icon_url, kPaymentAppIdealIconSize, |
| 126 kPaymentAppMinimumIconSize, |
| 127 base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this))) { |
| 128 PostPaymentAppInfoFetchResultToIOThread(); |
| 129 } |
| 130 } |
| 131 |
| 132 void PaymentAppInfoFetcher::OnIconFetched(const SkBitmap& icon) { |
| 133 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 134 |
| 135 if (icon.drawsNothing()) { |
| 136 PostPaymentAppInfoFetchResultToIOThread(); |
| 137 return; |
| 138 } |
| 139 |
| 140 gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(icon); |
| 141 scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); |
| 142 base::Base64Encode( |
| 143 base::StringPiece(raw_data->front_as<char>(), raw_data->size()), |
| 144 &fetched_payment_app_icon_); |
| 145 PostPaymentAppInfoFetchResultToIOThread(); |
| 146 } |
| 147 |
| 148 void PaymentAppInfoFetcher::PostPaymentAppInfoFetchResultToIOThread() { |
| 149 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 150 |
| 151 BrowserThread::PostTask( |
| 152 BrowserThread::IO, FROM_HERE, |
| 153 base::BindOnce(std::move(callback_), fetched_payment_app_name_, |
| 154 fetched_payment_app_icon_)); |
| 155 } |
| 156 |
| 157 } // namespace content |
OLD | NEW |