WeakPtrFactory should populate m_ref lazily.
[WebKit-https.git] / Source / WebKit / UIProcess / ApplePay / mac / WebPaymentCoordinatorProxyMac.mm
1 /*
2  * Copyright (C) 2016 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 "WebPageProxy.h"
32 #import "WebPaymentCoordinatorProxyCocoa.h"
33 #import <pal/spi/cocoa/PassKitSPI.h>
34 #import <wtf/BlockPtr.h>
35 #import <wtf/SoftLinking.h>
36
37 SOFT_LINK_PRIVATE_FRAMEWORK(PassKit)
38
39 SOFT_LINK_CLASS(PassKit, PKPaymentAuthorizationViewController);
40 SOFT_LINK_CONSTANT(PassKit, PKExtensionPaymentAuthorizationUIExtensionPointName, NSString *);
41
42 namespace WebKit {
43
44 void WebPaymentCoordinatorProxy::platformShowPaymentUI(const WebCore::URL& originatingURL, const Vector<WebCore::URL>& linkIconURLStrings, const WebCore::ApplePaySessionPaymentRequest& request, WTF::Function<void (bool)>&& completionHandler)
45 {
46     auto paymentRequest = toPKPaymentRequest(m_webPageProxy, originatingURL, linkIconURLStrings, request);
47
48     auto showPaymentUIRequestSeed = m_showPaymentUIRequestSeed;
49     auto weakThis = m_weakPtrFactory.createWeakPtr(*this);
50     [getPKPaymentAuthorizationViewControllerClass() requestViewControllerWithPaymentRequest:paymentRequest.get() completion:BlockPtr<void (PKPaymentAuthorizationViewController *, NSError *)>::fromCallable([paymentRequest, showPaymentUIRequestSeed, weakThis, completionHandler = WTFMove(completionHandler)](PKPaymentAuthorizationViewController *viewController, NSError *error) {
51         auto paymentCoordinatorProxy = weakThis.get();
52         if (!paymentCoordinatorProxy)
53             return;
54
55         if (error) {
56             LOG_ERROR("+[PKPaymentAuthorizationViewController requestViewControllerWithPaymentRequest:completion:] error %@", error);
57
58             completionHandler(false);
59             return;
60         }
61
62         if (showPaymentUIRequestSeed != paymentCoordinatorProxy->m_showPaymentUIRequestSeed) {
63             // We've already been asked to hide the payment UI. Don't attempt to show it.
64             return;
65         }
66
67         ASSERT(viewController);
68
69         paymentCoordinatorProxy->m_paymentAuthorizationViewControllerDelegate = adoptNS([[WKPaymentAuthorizationViewControllerDelegate alloc] initWithPaymentCoordinatorProxy:*paymentCoordinatorProxy]);
70         paymentCoordinatorProxy->m_paymentAuthorizationViewControllerDelegate->_paymentSummaryItems = [paymentRequest paymentSummaryItems];
71         paymentCoordinatorProxy->m_paymentAuthorizationViewControllerDelegate->_shippingMethods = [paymentRequest shippingMethods];
72         paymentCoordinatorProxy->m_paymentAuthorizationViewController = viewController;
73         [paymentCoordinatorProxy->m_paymentAuthorizationViewController setDelegate:paymentCoordinatorProxy->m_paymentAuthorizationViewControllerDelegate.get()];
74         [paymentCoordinatorProxy->m_paymentAuthorizationViewController setPrivateDelegate:paymentCoordinatorProxy->m_paymentAuthorizationViewControllerDelegate.get()];
75
76         ASSERT(!paymentCoordinatorProxy->m_sheetWindow);
77         paymentCoordinatorProxy->m_sheetWindow = [NSWindow windowWithContentViewController:viewController];
78
79         paymentCoordinatorProxy->m_sheetWindowWillCloseObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillCloseNotification object:paymentCoordinatorProxy->m_sheetWindow.get() queue:nil usingBlock:[paymentCoordinatorProxy](NSNotification *) {
80             paymentCoordinatorProxy->hidePaymentUI();
81             paymentCoordinatorProxy->didReachFinalState();
82         }];
83
84         [paymentCoordinatorProxy->m_webPageProxy.platformWindow() beginSheet:paymentCoordinatorProxy->m_sheetWindow.get() completionHandler:nullptr];
85
86         completionHandler(true);
87     }).get()];
88 }
89
90 void WebPaymentCoordinatorProxy::hidePaymentUI()
91 {
92     if (m_state == State::Activating) {
93         ++m_showPaymentUIRequestSeed;
94
95         ASSERT(!m_paymentAuthorizationViewController);
96         ASSERT(!m_paymentAuthorizationViewControllerDelegate);
97         ASSERT(!m_sheetWindow);
98         return;
99     }
100
101     ASSERT(m_paymentAuthorizationViewController);
102     ASSERT(m_paymentAuthorizationViewControllerDelegate);
103     ASSERT(m_sheetWindow);
104
105     [[NSNotificationCenter defaultCenter] removeObserver:m_sheetWindowWillCloseObserver.get()];
106     m_sheetWindowWillCloseObserver = nullptr;
107
108     [[m_sheetWindow sheetParent] endSheet:m_sheetWindow.get()];
109     [m_paymentAuthorizationViewController setDelegate:nil];
110     [m_paymentAuthorizationViewController setPrivateDelegate:nil];
111     m_paymentAuthorizationViewController = nullptr;
112
113     [m_paymentAuthorizationViewControllerDelegate invalidate];
114     m_paymentAuthorizationViewControllerDelegate = nullptr;
115
116     m_sheetWindow = nullptr;
117 }
118
119 }
120
121 #endif