Chromium Code Reviews| 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 // TODO(gogerald): Choose appropriate icon size dynamically on different | |
| 18 // platforms. | |
| 19 #define PAYMENT_APP_IDEAL_ICON_SIZE 64 | |
| 20 #define PAYMENT_APP_MINIMUM_ICON_SIZE 0 | |
|
please use gerrit instead
2017/06/29 21:15:39
Use constants instead of #define.
gogerald1
2017/06/30 02:55:22
Done.
| |
| 21 | |
| 22 namespace content { | |
| 23 | |
| 24 PaymentAppInfoFetcher::PaymentAppInfoFetcher() | |
| 25 : context_process_id_(-1), context_frame_id_(-1) {} | |
| 26 PaymentAppInfoFetcher::~PaymentAppInfoFetcher() {} | |
| 27 | |
| 28 void PaymentAppInfoFetcher::Start( | |
| 29 const GURL& context_url, | |
| 30 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, | |
| 31 PaymentAppInfoFetchCallback callback) { | |
| 32 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 33 | |
| 34 context_url_ = context_url; | |
| 35 callback_ = std::move(callback); | |
| 36 | |
| 37 std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts = | |
| 38 GetProviderHostIds(service_worker_context.get(), context_url.GetOrigin()); | |
| 39 DCHECK_GT(provider_hosts->size(), 0U); | |
| 40 | |
| 41 BrowserThread::PostTask( | |
| 42 BrowserThread::UI, FROM_HERE, | |
| 43 base::BindOnce(&PaymentAppInfoFetcher::StartFromUIThread, this, | |
| 44 std::move(provider_hosts))); | |
| 45 } | |
| 46 | |
| 47 void PaymentAppInfoFetcher::StartFromUIThread( | |
| 48 const std::unique_ptr<std::vector<std::pair<int, int>>>& provider_hosts) { | |
| 49 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 50 | |
| 51 for (const auto& frame : *provider_hosts) { | |
| 52 RenderFrameHostImpl* render_frame_host = | |
| 53 RenderFrameHostImpl::FromID(frame.first, frame.second); | |
| 54 if (!render_frame_host) | |
| 55 continue; | |
| 56 | |
| 57 WebContentsImpl* web_content = static_cast<WebContentsImpl*>( | |
| 58 WebContents::FromRenderFrameHost(render_frame_host)); | |
| 59 if (!web_content || web_content->IsHidden() || | |
| 60 context_url_.spec().compare( | |
| 61 web_content->GetLastCommittedURL().spec()) != 0) { | |
| 62 continue; | |
| 63 } | |
| 64 | |
| 65 context_process_id_ = frame.first; | |
| 66 context_frame_id_ = frame.second; | |
| 67 | |
| 68 web_content->GetManifest(base::Bind( | |
| 69 &PaymentAppInfoFetcher::FetchPaymentAppManifestCallback, this)); | |
| 70 return; | |
| 71 } | |
| 72 | |
| 73 PostPaymentAppInfoFetchResultToIOThread(); | |
| 74 } | |
| 75 | |
| 76 void PaymentAppInfoFetcher::FetchPaymentAppManifestCallback( | |
| 77 const GURL& url, | |
| 78 const Manifest& manifest) { | |
| 79 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 80 | |
| 81 if (url.is_empty() || manifest.IsEmpty()) { | |
| 82 PostPaymentAppInfoFetchResultToIOThread(); | |
| 83 return; | |
| 84 } | |
| 85 | |
| 86 if (manifest.name.is_null() || | |
| 87 !base::UTF16ToUTF8(manifest.name.string().c_str(), | |
| 88 manifest.name.string().length(), | |
| 89 &fetched_payment_app_name_)) { | |
| 90 PostPaymentAppInfoFetchResultToIOThread(); | |
| 91 return; | |
| 92 } | |
| 93 | |
| 94 GURL icon_url = ManifestIconSelector::FindBestMatchingIcon( | |
| 95 manifest.icons, PAYMENT_APP_IDEAL_ICON_SIZE, | |
| 96 PAYMENT_APP_MINIMUM_ICON_SIZE, Manifest::Icon::ANY); | |
| 97 if (!icon_url.is_valid()) { | |
| 98 PostPaymentAppInfoFetchResultToIOThread(); | |
| 99 return; | |
| 100 } | |
| 101 | |
| 102 RenderFrameHostImpl* render_frame_host = | |
| 103 RenderFrameHostImpl::FromID(context_process_id_, context_frame_id_); | |
| 104 if (!render_frame_host) { | |
| 105 PostPaymentAppInfoFetchResultToIOThread(); | |
| 106 return; | |
| 107 } | |
| 108 | |
| 109 WebContents* web_content = | |
| 110 WebContents::FromRenderFrameHost(render_frame_host); | |
| 111 if (!web_content) { | |
| 112 PostPaymentAppInfoFetchResultToIOThread(); | |
| 113 return; | |
| 114 } | |
| 115 | |
| 116 if (!content::ManifestIconDownloader::Download( | |
| 117 web_content, icon_url, PAYMENT_APP_IDEAL_ICON_SIZE, | |
| 118 PAYMENT_APP_MINIMUM_ICON_SIZE, | |
| 119 base::Bind(&PaymentAppInfoFetcher::OnIconFetched, this))) { | |
| 120 PostPaymentAppInfoFetchResultToIOThread(); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 void PaymentAppInfoFetcher::OnIconFetched(const SkBitmap& icon) { | |
| 125 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 126 | |
| 127 if (icon.drawsNothing()) { | |
| 128 PostPaymentAppInfoFetchResultToIOThread(); | |
| 129 return; | |
| 130 } | |
| 131 | |
| 132 gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(icon); | |
| 133 scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); | |
| 134 base::Base64Encode( | |
| 135 base::StringPiece(raw_data->front_as<char>(), raw_data->size()), | |
| 136 &fetched_payment_app_icon_); | |
| 137 PostPaymentAppInfoFetchResultToIOThread(); | |
| 138 } | |
| 139 | |
| 140 void PaymentAppInfoFetcher::PostPaymentAppInfoFetchResultToIOThread() { | |
| 141 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 142 | |
| 143 BrowserThread::PostTask( | |
| 144 BrowserThread::IO, FROM_HERE, | |
| 145 base::BindOnce(std::move(callback_), fetched_payment_app_name_, | |
| 146 fetched_payment_app_icon_)); | |
| 147 } | |
| 148 | |
| 149 std::unique_ptr<std::vector<std::pair<int, int>>> | |
| 150 PaymentAppInfoFetcher::GetProviderHostIds( | |
| 151 ServiceWorkerContextWrapper* service_worker_context, | |
| 152 const GURL& origin) { | |
| 153 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 154 | |
| 155 std::unique_ptr<std::vector<std::pair<int, int>>> render_frames( | |
| 156 new std::vector<std::pair<int, int>>()); | |
| 157 | |
| 158 for (std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
| 159 service_worker_context->context()->GetClientProviderHostIterator( | |
| 160 origin); | |
| 161 !it->IsAtEnd(); it->Advance()) { | |
| 162 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); | |
| 163 render_frames->push_back( | |
| 164 std::make_pair(provider_host->process_id(), provider_host->frame_id())); | |
| 165 } | |
| 166 | |
| 167 return render_frames; | |
| 168 } | |
| 169 | |
| 170 } // namespace content | |
| OLD | NEW |