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_instrument_icon_fetcher.h" | |
6 | |
7 #include "base/base64.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "content/browser/storage_partition_impl.h" | |
10 #include "content/public/browser/browser_thread.h" | |
11 #include "content/public/common/service_manager_connection.h" | |
12 #include "net/base/load_flags.h" | |
13 #include "net/http/http_status_code.h" | |
14 #include "net/traffic_annotation/network_traffic_annotation.h" | |
15 #include "services/data_decoder/public/cpp/decode_image.h" | |
16 #include "services/service_manager/public/cpp/connector.h" | |
17 #include "ui/gfx/geometry/size.h" | |
18 #include "ui/gfx/image/image.h" | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 | |
24 net::NetworkTrafficAnnotationTag g_traffic_annotation = | |
25 net::DefineNetworkTrafficAnnotation("payment_instrument_icon_fetcher", R"( | |
26 semantics { | |
27 sender: "Web Payments" | |
28 description: | |
29 "Chromium downloads payment instrument icons when registering | |
30 payment instruments." | |
31 trigger: | |
32 "When user navigates to a website to register web payment apps." | |
33 data: | |
34 "URL of the required icon to fetch. No user information is sent." | |
35 destination: WEBSITE | |
36 } | |
37 policy { | |
38 cookies_allowed: false | |
39 setting: | |
40 "This feature cannot be disabled in settings. Users can refuse | |
41 to install web payment apps." | |
42 policy_exception_justification: "Not implemented." | |
43 })"); | |
44 | |
45 } // namespace | |
46 | |
47 PaymentInstrumentIconFetcher::PaymentInstrumentIconFetcher() | |
48 : checking_image_object_index_(0) {} | |
49 PaymentInstrumentIconFetcher::~PaymentInstrumentIconFetcher() {} | |
50 | |
51 void PaymentInstrumentIconFetcher::Start( | |
52 const std::vector<payments::mojom::ImageObjectPtr>& image_objects, | |
53 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, | |
54 PaymentInstrumentIconFetcherCallback callback) { | |
55 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
56 | |
57 for (const auto& obj : image_objects) { | |
58 payments::mojom::ImageObjectPtr image_object = | |
59 payments::mojom::ImageObject::New(); | |
60 image_object->src = obj->src; | |
61 image_objects_.emplace_back(std::move(image_object)); | |
dcheng
2017/06/10 00:37:10
Can this take |image_objects| by value, so we can
gogerald1
2017/06/12 16:19:43
Done.
| |
62 } | |
63 DCHECK_GT(image_objects_.size(), 0U); | |
64 | |
65 callback_ = std::move(callback); | |
66 | |
67 BrowserThread::PostTask( | |
68 BrowserThread::UI, FROM_HERE, | |
69 base::Bind(&PaymentInstrumentIconFetcher::StartFromUIThread, | |
dcheng
2017/06/10 00:37:10
Nit: might be nice to use base::BindOnce here, sin
gogerald1
2017/06/12 16:19:44
Done.
| |
70 base::Unretained(this), service_worker_context)); | |
dcheng
2017/06/10 00:37:10
Please document why Unretained is safe here.
dcheng
2017/06/10 00:37:10
Also, please use std::move(service_worker_context)
gogerald1
2017/06/12 16:19:43
Done.
gogerald1
2017/06/12 16:19:44
Done.
| |
71 } | |
72 | |
73 void PaymentInstrumentIconFetcher::StartFromUIThread( | |
74 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { | |
75 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
76 | |
77 url_request_context_getter_ = scoped_refptr<net::URLRequestContextGetter>( | |
dcheng
2017/06/10 00:37:10
It's pretty unusual to see this written out explic
gogerald1
2017/06/12 16:19:43
Done. scoped_refptr has no reset method, but I've
| |
78 service_worker_context->storage_partition()->GetURLRequestContext()); | |
79 if (url_request_context_getter_.get() == nullptr) { | |
dcheng
2017/06/10 00:37:10
Nit: just if (url_request_context_getter_) here
gogerald1
2017/06/12 16:19:43
Done.
| |
80 PostCallbackToIOThread(""); | |
81 return; | |
82 } | |
83 | |
84 FetchIcon(); | |
85 } | |
86 | |
87 void PaymentInstrumentIconFetcher::FetchIcon() { | |
88 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
89 | |
90 if (checking_image_object_index_ >= image_objects_.size()) { | |
91 PostCallbackToIOThread(""); | |
92 return; | |
93 } | |
94 | |
95 GURL* icon_src_url = &(image_objects_[checking_image_object_index_]->src); | |
96 if (!icon_src_url->is_valid()) { | |
97 checking_image_object_index_++; | |
98 FetchIcon(); | |
99 return; | |
100 } | |
101 | |
102 fetcher_ = net::URLFetcher::Create(*icon_src_url, net::URLFetcher::GET, this, | |
103 g_traffic_annotation); | |
104 fetcher_->SetRequestContext(url_request_context_getter_.get()); | |
105 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
106 net::LOAD_DO_NOT_SAVE_COOKIES); | |
107 fetcher_->SetStopOnRedirect(true); | |
108 fetcher_->Start(); | |
109 } | |
110 | |
111 void PaymentInstrumentIconFetcher::OnURLFetchComplete( | |
112 const net::URLFetcher* source) { | |
113 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
114 | |
115 DCHECK_EQ(fetcher_.get(), source); | |
116 std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | |
117 | |
118 std::string data; | |
119 if (!(source->GetStatus().is_success() && | |
120 source->GetResponseCode() == net::HTTP_OK && | |
121 source->GetResponseAsString(&data))) { | |
122 checking_image_object_index_++; | |
123 FetchIcon(); | |
124 return; | |
125 } | |
126 | |
127 service_manager::mojom::ConnectorRequest connector_request; | |
128 std::unique_ptr<service_manager::Connector> connector = | |
129 service_manager::Connector::Create(&connector_request); | |
130 content::ServiceManagerConnection::GetForProcess() | |
131 ->GetConnector() | |
132 ->BindConnectorRequest(std::move(connector_request)); | |
133 | |
134 std::vector<uint8_t> image_data(data.begin(), data.end()); | |
135 data_decoder::DecodeImage( | |
136 connector.get(), image_data, data_decoder::mojom::ImageCodec::DEFAULT, | |
137 false, data_decoder::kDefaultMaxSizeInBytes, gfx::Size(), | |
138 base::Bind(&PaymentInstrumentIconFetcher::DecodeImageCallback, | |
139 base::Unretained(this))); | |
140 } | |
141 | |
142 void PaymentInstrumentIconFetcher::DecodeImageCallback(const SkBitmap& bitmap) { | |
143 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
144 | |
145 if (bitmap.isNull() || bitmap.empty()) { | |
dcheng
2017/06/10 00:37:10
Use bitmap.drawsNothing(), which does both of thes
gogerald1
2017/06/12 16:19:43
Done.
| |
146 checking_image_object_index_++; | |
147 FetchIcon(); | |
148 return; | |
149 } | |
150 | |
151 gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(bitmap); | |
152 scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); | |
153 std::string base_64; | |
154 base::Base64Encode( | |
155 base::StringPiece(raw_data->front_as<char>(), raw_data->size()), | |
156 &base_64); | |
157 | |
158 PostCallbackToIOThread(base_64); | |
159 } | |
160 | |
161 void PaymentInstrumentIconFetcher::PostCallbackToIOThread( | |
162 const std::string& decoded_data) { | |
163 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
164 base::BindOnce(std::move(callback_), decoded_data)); | |
165 } | |
166 | |
167 } // namespace content | |
OLD | NEW |