80fc12c4e388c9e5b8dba680a1ea0619de57e1ce
[WebKit-https.git] / Source / WebKit / Shared / ApplePay / mac / WebPaymentCoordinatorProxyMac.mm
1 /*
2  * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebPaymentCoordinatorProxy.h"
28
29 #if PLATFORM(MAC) && ENABLE(APPLE_PAY)
30
31 #import "PaymentAuthorizationViewController.h"
32 #import "WebPageProxy.h"
33 #import <pal/cocoa/PassKitSoftLink.h>
34 #import <wtf/BlockPtr.h>
35
36 namespace WebKit {
37
38 void WebPaymentCoordinatorProxy::platformShowPaymentUI(const URL& originatingURL, const Vector<URL>& linkIconURLStrings, PAL::SessionID sessionID, const WebCore::ApplePaySessionPaymentRequest& request, CompletionHandler<void(bool)>&& completionHandler)
39 {
40     auto paymentRequest = platformPaymentRequest(originatingURL, linkIconURLStrings, sessionID, request);
41
42     auto showPaymentUIRequestSeed = m_showPaymentUIRequestSeed;
43     auto weakThis = makeWeakPtr(*this);
44     [PAL::getPKPaymentAuthorizationViewControllerClass() requestViewControllerWithPaymentRequest:paymentRequest.get() completion:makeBlockPtr([paymentRequest, showPaymentUIRequestSeed, weakThis, completionHandler = WTFMove(completionHandler)](PKPaymentAuthorizationViewController *viewController, NSError *error) mutable {
45         auto paymentCoordinatorProxy = weakThis.get();
46         if (!paymentCoordinatorProxy)
47             return completionHandler(false);
48
49         if (error) {
50             LOG_ERROR("+[PKPaymentAuthorizationViewController requestViewControllerWithPaymentRequest:completion:] error %@", error);
51
52             completionHandler(false);
53             return;
54         }
55
56         if (showPaymentUIRequestSeed != paymentCoordinatorProxy->m_showPaymentUIRequestSeed) {
57             // We've already been asked to hide the payment UI. Don't attempt to show it.
58             return completionHandler(false);
59         }
60
61         NSWindow *presentingWindow = paymentCoordinatorProxy->m_client.paymentCoordinatorPresentingWindow(*paymentCoordinatorProxy);
62         if (!presentingWindow)
63             return completionHandler(false);
64
65         ASSERT(viewController);
66
67         paymentCoordinatorProxy->m_authorizationPresenter = std::make_unique<PaymentAuthorizationViewController>(*paymentCoordinatorProxy, paymentRequest.get(), viewController);
68
69         ASSERT(!paymentCoordinatorProxy->m_sheetWindow);
70         paymentCoordinatorProxy->m_sheetWindow = [NSWindow windowWithContentViewController:viewController];
71
72         paymentCoordinatorProxy->m_sheetWindowWillCloseObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:paymentCoordinatorProxy->m_sheetWindow.get() queue:nil usingBlock:[paymentCoordinatorProxy](NSNotification *) {
73             paymentCoordinatorProxy->hidePaymentUI();
74             paymentCoordinatorProxy->didReachFinalState();
75         }];
76
77         [presentingWindow beginSheet:paymentCoordinatorProxy->m_sheetWindow.get() completionHandler:nullptr];
78
79         completionHandler(true);
80     }).get()];
81 }
82
83 void WebPaymentCoordinatorProxy::hidePaymentUI()
84 {
85     if (m_state == State::Activating) {
86         ++m_showPaymentUIRequestSeed;
87
88         ASSERT(!m_authorizationPresenter);
89         ASSERT(!m_sheetWindow);
90         return;
91     }
92
93     ASSERT(m_authorizationPresenter);
94     ASSERT(m_sheetWindow);
95
96     [[NSNotificationCenter defaultCenter] removeObserver:m_sheetWindowWillCloseObserver.get()];
97     m_sheetWindowWillCloseObserver = nullptr;
98
99     [[m_sheetWindow sheetParent] endSheet:m_sheetWindow.get()];
100
101     if (m_authorizationPresenter)
102         m_authorizationPresenter->dismiss();
103     m_authorizationPresenter = nullptr;
104
105     m_sheetWindow = nullptr;
106 }
107
108 }
109
110 #endif