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 = | |
please use gerrit instead
2017/06/08 21:34:11
Does this cause an exit time destructor? No reason
gogerald1
2017/06/09 14:23:24
It may be used multiple times when there are multi
| |
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 void PaymentInstrumentIconFetcher::start( | |
48 const GURL& scope, | |
49 const std::vector<payments::mojom::ImageObjectPtr>& image_objects, | |
50 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, | |
51 PaymentInstrumentIconFetcherCallback callback) { | |
52 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
53 | |
54 scope_ = scope; | |
55 DCHECK(scope_.is_valid()); | |
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_object->sizes = obj->sizes; | |
62 image_object->type = obj->type; | |
63 image_objects_.emplace_back(std::move(image_object)); | |
64 } | |
65 DCHECK_GT(image_objects_.size(), 0U); | |
66 | |
67 callback_ = std::move(callback); | |
68 | |
69 BrowserThread::PostTask( | |
70 BrowserThread::UI, FROM_HERE, | |
71 base::Bind(&PaymentInstrumentIconFetcher::StartFromUIThread, | |
72 base::Unretained(this), service_worker_context)); | |
73 } | |
74 | |
75 void PaymentInstrumentIconFetcher::StartFromUIThread( | |
76 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { | |
77 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
78 | |
79 url_request_context_getter_ = scoped_refptr<net::URLRequestContextGetter>( | |
80 service_worker_context->storage_partition()->GetURLRequestContext()); | |
81 if (url_request_context_getter_.get() == nullptr) { | |
82 PostCallbackToIOThread(""); | |
83 return; | |
84 } | |
85 | |
86 checking_image_object_index_ = 0; | |
87 FetchIcon(); | |
88 } | |
89 | |
90 void PaymentInstrumentIconFetcher::FetchIcon() { | |
91 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
92 | |
93 if (checking_image_object_index_ >= image_objects_.size()) { | |
94 PostCallbackToIOThread(""); | |
95 return; | |
96 } | |
97 | |
98 GURL icon_src_url(image_objects_[checking_image_object_index_]->src); | |
99 if (!icon_src_url.is_valid()) { | |
100 icon_src_url = | |
101 scope_.Resolve(image_objects_[checking_image_object_index_]->src); | |
102 } | |
103 | |
104 if (!icon_src_url.is_valid()) { | |
105 checking_image_object_index_++; | |
106 FetchIcon(); | |
107 return; | |
108 } | |
109 | |
110 fetcher_ = net::URLFetcher::Create(icon_src_url, net::URLFetcher::GET, this, | |
111 g_traffic_annotation); | |
112 fetcher_->SetRequestContext(url_request_context_getter_.get()); | |
113 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
114 net::LOAD_DO_NOT_SAVE_COOKIES); | |
115 fetcher_->SetStopOnRedirect(true); | |
116 fetcher_->Start(); | |
117 } | |
118 | |
119 void PaymentInstrumentIconFetcher::OnURLFetchComplete( | |
120 const net::URLFetcher* source) { | |
121 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
122 | |
123 DCHECK_EQ(fetcher_.get(), source); | |
124 std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | |
125 | |
126 std::string data; | |
127 if (!(source->GetStatus().is_success() && | |
128 source->GetResponseCode() == net::HTTP_OK && | |
129 source->GetResponseAsString(&data))) { | |
130 checking_image_object_index_++; | |
131 FetchIcon(); | |
132 return; | |
133 } | |
134 | |
135 service_manager::mojom::ConnectorRequest connector_request; | |
136 std::unique_ptr<service_manager::Connector> connector = | |
137 service_manager::Connector::Create(&connector_request); | |
138 content::ServiceManagerConnection::GetForProcess() | |
139 ->GetConnector() | |
140 ->BindConnectorRequest(std::move(connector_request)); | |
141 | |
142 std::vector<uint8_t> image_data(data.begin(), data.end()); | |
143 data_decoder::DecodeImage( | |
144 connector.get(), image_data, data_decoder::mojom::ImageCodec::DEFAULT, | |
145 false, data_decoder::kDefaultMaxSizeInBytes, gfx::Size(), | |
146 base::Bind(&PaymentInstrumentIconFetcher::DecodeImageCallback, | |
147 base::Unretained(this))); | |
148 } | |
149 | |
150 void PaymentInstrumentIconFetcher::DecodeImageCallback(const SkBitmap& bitmap) { | |
151 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
152 | |
153 if (bitmap.isNull() || bitmap.empty()) { | |
154 checking_image_object_index_++; | |
155 FetchIcon(); | |
156 return; | |
157 } | |
158 | |
159 gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(bitmap); | |
160 scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); | |
161 std::string base_64; | |
162 base::Base64Encode( | |
163 base::StringPiece(raw_data->front_as<char>(), raw_data->size()), | |
164 &base_64); | |
165 | |
166 PostCallbackToIOThread(base_64); | |
167 } | |
168 | |
169 void PaymentInstrumentIconFetcher::PostCallbackToIOThread( | |
170 const std::string& decoded_data) { | |
171 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
172 base::BindOnce(std::move(callback_), decoded_data)); | |
173 } | |
174 | |
175 } // namespace content | |
OLD | NEW |