| 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     image_objects_.emplace_back(payments::mojom::ImageObject::New(obj->src)); | 
|  | 59   } | 
|  | 60   DCHECK_GT(image_objects_.size(), 0U); | 
|  | 61 | 
|  | 62   callback_ = std::move(callback); | 
|  | 63 | 
|  | 64   BrowserThread::PostTask( | 
|  | 65       BrowserThread::UI, FROM_HERE, | 
|  | 66       base::BindOnce(&PaymentInstrumentIconFetcher::StartFromUIThread, this, | 
|  | 67                      std::move(service_worker_context))); | 
|  | 68 } | 
|  | 69 | 
|  | 70 void PaymentInstrumentIconFetcher::StartFromUIThread( | 
|  | 71     scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { | 
|  | 72   DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
|  | 73 | 
|  | 74   url_request_context_getter_ = | 
|  | 75       service_worker_context->storage_partition()->GetURLRequestContext(); | 
|  | 76   if (!url_request_context_getter_) { | 
|  | 77     PostCallbackToIOThread(std::string()); | 
|  | 78     return; | 
|  | 79   } | 
|  | 80 | 
|  | 81   FetchIcon(); | 
|  | 82 } | 
|  | 83 | 
|  | 84 void PaymentInstrumentIconFetcher::FetchIcon() { | 
|  | 85   DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
|  | 86 | 
|  | 87   if (checking_image_object_index_ >= image_objects_.size()) { | 
|  | 88     PostCallbackToIOThread(std::string()); | 
|  | 89     return; | 
|  | 90   } | 
|  | 91 | 
|  | 92   GURL* icon_src_url = &(image_objects_[checking_image_object_index_]->src); | 
|  | 93   if (!icon_src_url->is_valid()) { | 
|  | 94     checking_image_object_index_++; | 
|  | 95     FetchIcon(); | 
|  | 96     return; | 
|  | 97   } | 
|  | 98 | 
|  | 99   fetcher_ = net::URLFetcher::Create(*icon_src_url, net::URLFetcher::GET, this, | 
|  | 100                                      g_traffic_annotation); | 
|  | 101   fetcher_->SetRequestContext(url_request_context_getter_.get()); | 
|  | 102   fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 
|  | 103                          net::LOAD_DO_NOT_SAVE_COOKIES); | 
|  | 104   fetcher_->SetStopOnRedirect(true); | 
|  | 105   fetcher_->Start(); | 
|  | 106 } | 
|  | 107 | 
|  | 108 void PaymentInstrumentIconFetcher::OnURLFetchComplete( | 
|  | 109     const net::URLFetcher* source) { | 
|  | 110   DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
|  | 111 | 
|  | 112   DCHECK_EQ(fetcher_.get(), source); | 
|  | 113   std::unique_ptr<net::URLFetcher> free_fetcher = std::move(fetcher_); | 
|  | 114 | 
|  | 115   std::string data; | 
|  | 116   if (!(source->GetStatus().is_success() && | 
|  | 117         source->GetResponseCode() == net::HTTP_OK && | 
|  | 118         source->GetResponseAsString(&data))) { | 
|  | 119     checking_image_object_index_++; | 
|  | 120     FetchIcon(); | 
|  | 121     return; | 
|  | 122   } | 
|  | 123 | 
|  | 124   service_manager::mojom::ConnectorRequest connector_request; | 
|  | 125   std::unique_ptr<service_manager::Connector> connector = | 
|  | 126       service_manager::Connector::Create(&connector_request); | 
|  | 127   content::ServiceManagerConnection::GetForProcess() | 
|  | 128       ->GetConnector() | 
|  | 129       ->BindConnectorRequest(std::move(connector_request)); | 
|  | 130 | 
|  | 131   std::vector<uint8_t> image_data(data.begin(), data.end()); | 
|  | 132   data_decoder::DecodeImage( | 
|  | 133       connector.get(), image_data, data_decoder::mojom::ImageCodec::DEFAULT, | 
|  | 134       false, data_decoder::kDefaultMaxSizeInBytes, gfx::Size(), | 
|  | 135       base::Bind(&PaymentInstrumentIconFetcher::DecodeImageCallback, this)); | 
|  | 136 } | 
|  | 137 | 
|  | 138 void PaymentInstrumentIconFetcher::DecodeImageCallback(const SkBitmap& bitmap) { | 
|  | 139   DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
|  | 140 | 
|  | 141   if (bitmap.drawsNothing()) { | 
|  | 142     checking_image_object_index_++; | 
|  | 143     FetchIcon(); | 
|  | 144     return; | 
|  | 145   } | 
|  | 146 | 
|  | 147   gfx::Image decoded_image = gfx::Image::CreateFrom1xBitmap(bitmap); | 
|  | 148   scoped_refptr<base::RefCountedMemory> raw_data = decoded_image.As1xPNGBytes(); | 
|  | 149   std::string base_64; | 
|  | 150   base::Base64Encode( | 
|  | 151       base::StringPiece(raw_data->front_as<char>(), raw_data->size()), | 
|  | 152       &base_64); | 
|  | 153 | 
|  | 154   PostCallbackToIOThread(base_64); | 
|  | 155 } | 
|  | 156 | 
|  | 157 void PaymentInstrumentIconFetcher::PostCallbackToIOThread( | 
|  | 158     const std::string& decoded_data) { | 
|  | 159   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 
|  | 160                           base::BindOnce(std::move(callback_), decoded_data)); | 
|  | 161 } | 
|  | 162 | 
|  | 163 }  // namespace content | 
| OLD | NEW | 
|---|