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( | |
zino
2017/06/09 20:29:48
nit: s/start/Start
gogerald1
2017/06/09 22:25:02
Done.
| |
52 const GURL& scope, | |
53 const std::vector<payments::mojom::ImageObjectPtr>& image_objects, | |
54 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context, | |
55 PaymentInstrumentIconFetcherCallback callback) { | |
56 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
57 | |
58 scope_ = scope; | |
59 DCHECK(scope_.is_valid()); | |
60 | |
61 for (const auto& obj : image_objects) { | |
zino
2017/06/09 20:29:48
If my understanding is correct, the current implem
gogerald1
2017/06/09 22:25:03
Yes, I added a TODO for start interface, plan to u
| |
62 payments::mojom::ImageObjectPtr image_object = | |
63 payments::mojom::ImageObject::New(); | |
64 image_object->src = obj->src; | |
65 image_objects_.emplace_back(std::move(image_object)); | |
66 } | |
67 DCHECK_GT(image_objects_.size(), 0U); | |
68 | |
69 callback_ = std::move(callback); | |
70 | |
71 BrowserThread::PostTask( | |
72 BrowserThread::UI, FROM_HERE, | |
73 base::Bind(&PaymentInstrumentIconFetcher::StartFromUIThread, | |
74 base::Unretained(this), service_worker_context)); | |
75 } | |
76 | |
77 void PaymentInstrumentIconFetcher::StartFromUIThread( | |
78 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { | |
79 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
80 | |
81 url_request_context_getter_ = scoped_refptr<net::URLRequestContextGetter>( | |
82 service_worker_context->storage_partition()->GetURLRequestContext()); | |
83 if (url_request_context_getter_.get() == nullptr) { | |
84 PostCallbackToIOThread(""); | |
85 return; | |
86 } | |
87 | |
88 FetchIcon(); | |
89 } | |
90 | |
91 void PaymentInstrumentIconFetcher::FetchIcon() { | |
92 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
93 | |
94 if (checking_image_object_index_ >= image_objects_.size()) { | |
95 PostCallbackToIOThread(""); | |
96 return; | |
97 } | |
98 | |
99 GURL icon_src_url(image_objects_[checking_image_object_index_]->src); | |
100 if (!icon_src_url.is_valid()) { | |
101 icon_src_url = | |
102 scope_.Resolve(image_objects_[checking_image_object_index_]->src); | |
103 } | |
104 | |
105 if (!icon_src_url.is_valid()) { | |
106 checking_image_object_index_++; | |
107 FetchIcon(); | |
108 return; | |
109 } | |
110 | |
111 fetcher_ = net::URLFetcher::Create(icon_src_url, net::URLFetcher::GET, this, | |
112 g_traffic_annotation); | |
113 fetcher_->SetRequestContext(url_request_context_getter_.get()); | |
114 fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
115 net::LOAD_DO_NOT_SAVE_COOKIES); | |
116 fetcher_->SetStopOnRedirect(true); | |
117 fetcher_->Start(); | |
118 } | |
119 | |
120 void PaymentInstrumentIconFetcher::OnURLFetchComplete( | |
121 const net::URLFetcher* source) { | |
122 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
123 | |
124 DCHECK_EQ(fetcher_.get(), source); | |
125 std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | |
126 | |
127 std::string data; | |
128 if (!(source->GetStatus().is_success() && | |
129 source->GetResponseCode() == net::HTTP_OK && | |
130 source->GetResponseAsString(&data))) { | |
131 checking_image_object_index_++; | |
132 FetchIcon(); | |
133 return; | |
134 } | |
135 | |
136 service_manager::mojom::ConnectorRequest connector_request; | |
137 std::unique_ptr<service_manager::Connector> connector = | |
138 service_manager::Connector::Create(&connector_request); | |
139 content::ServiceManagerConnection::GetForProcess() | |
140 ->GetConnector() | |
141 ->BindConnectorRequest(std::move(connector_request)); | |
142 | |
143 std::vector<uint8_t> image_data(data.begin(), data.end()); | |
144 data_decoder::DecodeImage( | |
145 connector.get(), image_data, data_decoder::mojom::ImageCodec::DEFAULT, | |
146 false, data_decoder::kDefaultMaxSizeInBytes, gfx::Size(), | |
147 base::Bind(&PaymentInstrumentIconFetcher::DecodeImageCallback, | |
148 base::Unretained(this))); | |
149 } | |
150 | |
151 void PaymentInstrumentIconFetcher::DecodeImageCallback(const SkBitmap& bitmap) { | |
152 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
153 | |
154 if (bitmap.isNull() || bitmap.empty()) { | |
155 checking_image_object_index_++; | |
156 FetchIcon(); | |
157 return; | |
158 } | |
159 | |
160 gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(bitmap); | |
161 scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); | |
162 std::string base_64; | |
163 base::Base64Encode( | |
164 base::StringPiece(raw_data->front_as<char>(), raw_data->size()), | |
165 &base_64); | |
166 | |
167 PostCallbackToIOThread(base_64); | |
168 } | |
169 | |
170 void PaymentInstrumentIconFetcher::PostCallbackToIOThread( | |
171 const std::string& decoded_data) { | |
172 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
173 base::BindOnce(std::move(callback_), decoded_data)); | |
174 } | |
175 | |
176 } // namespace content | |
OLD | NEW |