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 |