blob: d90170fc10e0cd00cb017d72014fa150bc67e796 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_PAYMENTS_IOS_PAYMENT_INSTRUMENT_FINDER_H_
#define IOS_CHROME_BROWSER_PAYMENTS_IOS_PAYMENT_INSTRUMENT_FINDER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h"
#include "components/payments/core/payment_manifest_downloader.h"
#include "url/gurl.h"
namespace image_fetcher {
class IOSImageDataFetcherWrapper;
} // namespace image_fetcher
namespace payments {
class IOSPaymentInstrument;
class PaymentManifestDownloader;
} // namespace payments
namespace network {
class SharedURLLoaderFactory;
} // namespace network
@protocol PaymentRequestUIDelegate;
namespace payments {
// Finds all iOS third party native apps for a vector of URL payment method
// identifiers requested by a given merchant and validated by the class. The
// class validates the requested url payment methods by filtering out methods
// that cannot be handled by an installed app on the user's device. This filter
// is done by using the payment method's corresponding URL scheme and the
// canOpenUrl function of UIApplication. This check also serves as a whitelist
// for allowed payment method identifiers such that only the URL schemes of
// listed payment method identifiers can be queried. If the identifier is not on
// this whitelist the validation check fails for that payment method.
//
// After validating the requested payment methods, the class downloads the
// payment method's manifest and web app manifest in order to collect the
// payment app's name, icon, and universal link. If this fails the payment app
// is not deemed to be valid. The manifests are located based on the payment
// method name, which is a URI that starts with "https://".
//
// Example valid web app manifest structure:
//
// {
// "short_name": "Bobpay",
// "icons": [{
// "src": "images/touch/homescreen32.png",
// "sizes": "32x32"
// }],
// "related_applications": [{
// "platform": "itunes",
// "url": "https://bobpay.xyz/pay"
// }]
// }
class IOSPaymentInstrumentFinder {
public:
// Callback for when we have tried to find an IOSPaymentInstrument for all
// requested payment methods. This contains a vector of IOSPaymentInstruments
// that have valid names, icons, universal links, and method names.
using IOSPaymentInstrumentsFoundCallback = base::OnceCallback<void(
std::vector<std::unique_ptr<IOSPaymentInstrument>>)>;
// Initializes an IOSPaymentInstrumentFinder with a |url_loader_factory| which
// is used for making URL requests. |payment_request_ui_delegate| is passed to
// the created IOSPaymentInstrument objects.
IOSPaymentInstrumentFinder(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
id<PaymentRequestUIDelegate> payment_request_ui_delegate);
~IOSPaymentInstrumentFinder();
// Initiates the process of finding all valid, installed third party native
// iOS apps and creating corresponding IOSPaymentInstrument representations
// for these apps. |methods| is a list of URL payment method identifiers
// requested by the merchant e.g, "https://bobpay.com." |callback| is the
// IOSPaymentInstrumentsFoundCallback that is run when this class has
// retrieved all applicable iOS payment instruments. This function returns a
// filtered version of |methods| which are the url methods that remain after
// calling FilterUnsupportedURLPaymentMethods.
std::vector<GURL> CreateIOSPaymentInstrumentsForMethods(
const std::vector<GURL>& methods,
IOSPaymentInstrumentsFoundCallback callback);
private:
friend class PaymentRequestIOSPaymentInstrumentFinderTest;
// Filters out |queried_url_payment_method_identifiers| for any invalid
// url payment method identifiers queried by the caller. An invalid url
// payment method identifier is one that doesn't have a corresponding
// "app-name:// scheme" or one that doesn't have a corresponding installed
// payment app.
virtual std::vector<GURL> FilterUnsupportedURLPaymentMethods(
const std::vector<GURL>& queried_url_payment_method_identifiers);
// Callback for when the payment method manifest is retrieved for a payment
// method identifier. |content| is the json encoded payment method manifest
// and |method| is the url payment method identifier that corresponds with
// this manifest.
void OnPaymentManifestDownloaded(const GURL& method,
const GURL& method_url_after_redirects,
const std::string& content);
// Parses a payment method manifest for its default applications and gets all
// the valid ones. |input| is the json encoded payment method manifest to
// parse. |out_web_app_manifest_urls| is a vector of the web app manifest
// URLs of valid payment apps if any exist.
bool GetWebAppManifestURLsFromPaymentManifest(
const std::string& input,
std::vector<GURL>* out_web_app_manifest_urls);
// Callback for when the web app manifest is retrieved for a payment method
// identifier. |content| is the json encoded web app manifest and |method| is
// the url payment method that corresponds with this manifest.
// |web_app_manifest_url| is the web app manifest url. This is passed to
// GetPaymentAppDetailsFromWebAppManifest for validating an icon source path.
void OnWebAppManifestDownloaded(
const GURL& method,
const GURL& web_app_manifest_url,
const GURL& web_app_manifest_url_after_redirects,
const std::string& content);
// Parses a web app manifest for its name, icon, and universal link. |input|
// is the json encoded web app manifest to parse. |web_app_manifest_url|
// is the web app manifest url which is needed for determining if the relative
// path to an icon image source is valid. |out_app_name|, |out_app_icon_url|,
// and |out_universal_link| are set to the name, icon url, and universal link
// of a payment app.
bool GetPaymentAppDetailsFromWebAppManifest(const std::string& input,
const GURL& web_app_manifest_url,
std::string* out_app_name,
GURL* out_app_icon_url,
GURL* out_universal_link);
// Creates an instance of IOSPaymentInstrument and appends it to
// |instruments_found_|.
void CreateIOSPaymentInstrument(const GURL& method_name,
std::string& app_name,
GURL& app_icon_url,
GURL& universal_link);
// Whenever the class attempts to find an instrument for a given method it
// will either succeed or fail; in either scenario this method will decrease
// the number of payment instruments that still need to be addressed which
// is tracked with |num_instruments_to_find_|. When this number reaches 0 the
// class calls the IOSPaymentInstrumentsFound callback.
void OnPaymentInstrumentProcessed();
PaymentManifestDownloader downloader_;
image_fetcher::IOSImageDataFetcherWrapper image_fetcher_;
__weak id<PaymentRequestUIDelegate> payment_request_ui_delegate_;
size_t num_instruments_to_find_;
std::vector<std::unique_ptr<IOSPaymentInstrument>> instruments_found_;
IOSPaymentInstrumentsFoundCallback callback_;
base::WeakPtrFactory<IOSPaymentInstrumentFinder> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(IOSPaymentInstrumentFinder);
};
} // namespace payments
#endif // IOS_CHROME_BROWSER_PAYMENTS_IOS_PAYMENT_INSTRUMENT_FINDER_H_