[Apple Pay] Call +canMakePayments on a work queue
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Mar 2019 20:23:43 +0000 (20:23 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Mar 2019 20:23:43 +0000 (20:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196179
<rdar://problem/45388749>

Reviewed by Brady Eidson.

Calling +canMakePayments on either PKPaymentAuthorizationController or
PKPaymentAuthorizationViewController results in synchronous IPC and is therefore very
expensive to call on the main thread. On iOS, these calls are made in the network process,
and on Mac in the UI process.

Call these methods on a work queue to avoid main thread spins.

* Shared/ApplePay/WebPaymentCoordinatorProxy.cpp:
(WebKit::WebPaymentCoordinatorProxy::canMakePayments):
* Shared/ApplePay/WebPaymentCoordinatorProxy.h:
* Shared/ApplePay/ios/WebPaymentCoordinatorProxyIOS.mm:
(WebKit::WebPaymentCoordinatorProxy::platformCanMakePayments):
* Shared/ApplePay/mac/WebPaymentCoordinatorProxyMac.mm:
(WebKit::WebPaymentCoordinatorProxy::platformCanMakePayments):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243447 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Shared/ApplePay/WebPaymentCoordinatorProxy.cpp
Source/WebKit/Shared/ApplePay/WebPaymentCoordinatorProxy.h
Source/WebKit/Shared/ApplePay/ios/WebPaymentCoordinatorProxyIOS.mm
Source/WebKit/Shared/ApplePay/mac/WebPaymentCoordinatorProxyMac.mm

index bb560c4..5cf2ed5 100644 (file)
@@ -1,5 +1,28 @@
 2019-03-25  Andy Estes  <aestes@apple.com>
 
+        [Apple Pay] Call +canMakePayments on a work queue
+        https://bugs.webkit.org/show_bug.cgi?id=196179
+        <rdar://problem/45388749>
+
+        Reviewed by Brady Eidson.
+
+        Calling +canMakePayments on either PKPaymentAuthorizationController or
+        PKPaymentAuthorizationViewController results in synchronous IPC and is therefore very
+        expensive to call on the main thread. On iOS, these calls are made in the network process,
+        and on Mac in the UI process.
+
+        Call these methods on a work queue to avoid main thread spins.
+
+        * Shared/ApplePay/WebPaymentCoordinatorProxy.cpp:
+        (WebKit::WebPaymentCoordinatorProxy::canMakePayments):
+        * Shared/ApplePay/WebPaymentCoordinatorProxy.h:
+        * Shared/ApplePay/ios/WebPaymentCoordinatorProxyIOS.mm:
+        (WebKit::WebPaymentCoordinatorProxy::platformCanMakePayments):
+        * Shared/ApplePay/mac/WebPaymentCoordinatorProxyMac.mm:
+        (WebKit::WebPaymentCoordinatorProxy::platformCanMakePayments):
+
+2019-03-25  Andy Estes  <aestes@apple.com>
+
         [Apple Pay] Remove the AvailablePaymentNetworks synchronous message
         https://bugs.webkit.org/show_bug.cgi?id=196180
 
index 115ab64..eb8a0b6 100644 (file)
@@ -45,6 +45,7 @@ static WeakPtr<WebPaymentCoordinatorProxy>& activePaymentCoordinatorProxy()
 
 WebPaymentCoordinatorProxy::WebPaymentCoordinatorProxy(WebPaymentCoordinatorProxy::Client& client)
     : m_client { client }
+    , m_canMakePaymentsQueue { WorkQueue::create("com.apple.WebKit.CanMakePayments") }
 {
     m_client.paymentCoordinatorAddMessageReceiver(*this, Messages::WebPaymentCoordinatorProxy::messageReceiverName(), *this);
     finishConstruction(*this);
@@ -70,7 +71,7 @@ uint64_t WebPaymentCoordinatorProxy::messageSenderDestinationID() const
 
 void WebPaymentCoordinatorProxy::canMakePayments(CompletionHandler<void(bool)>&& reply)
 {
-    reply(platformCanMakePayments());
+    platformCanMakePayments(WTFMove(reply));
 }
 
 void WebPaymentCoordinatorProxy::canMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, PAL::SessionID sessionID, CompletionHandler<void(bool)>&& completionHandler)
index 0b9737d..d237eab 100644 (file)
@@ -34,6 +34,7 @@
 #include <wtf/Forward.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/WeakPtr.h>
+#include <wtf/WorkQueue.h>
 
 #if USE(APPLE_INTERNAL_SDK)
 #include <WebKitAdditions/WebPaymentCoordinatorProxyAdditions.h>
@@ -132,7 +133,7 @@ private:
     void didReachFinalState();
     void hidePaymentUI();
 
-    bool platformCanMakePayments();
+    void platformCanMakePayments(CompletionHandler<void(bool)>&&);
     void platformCanMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, PAL::SessionID, WTF::Function<void(bool)>&& completionHandler);
     void platformOpenPaymentSetup(const String& merchantIdentifier, const String& domainName, WTF::Function<void(bool)>&& completionHandler);
     void platformShowPaymentUI(const URL& originatingURL, const Vector<URL>& linkIconURLs, PAL::SessionID, const WebCore::ApplePaySessionPaymentRequest&, CompletionHandler<void(bool)>&&);
@@ -183,6 +184,7 @@ private:
     } m_merchantValidationState { MerchantValidationState::Idle };
 
     std::unique_ptr<PaymentAuthorizationPresenter> m_authorizationPresenter;
+    Ref<WorkQueue> m_canMakePaymentsQueue;
 
 #if PLATFORM(MAC)
     uint64_t m_showPaymentUIRequestSeed { 0 };
index f25d6c4..51641ad 100644 (file)
 
 namespace WebKit {
 
-bool WebPaymentCoordinatorProxy::platformCanMakePayments()
+void WebPaymentCoordinatorProxy::platformCanMakePayments(CompletionHandler<void(bool)>&& completionHandler)
 {
-    return [PAL::getPKPaymentAuthorizationControllerClass() canMakePayments];
+    m_canMakePaymentsQueue->dispatch([theClass = retainPtr(PAL::getPKPaymentAuthorizationControllerClass()), completionHandler = WTFMove(completionHandler)]() mutable {
+        RunLoop::main().dispatch([canMakePayments = [theClass canMakePayments], completionHandler = WTFMove(completionHandler)]() mutable {
+            completionHandler(canMakePayments);
+        });
+    });
 }
 
 void WebPaymentCoordinatorProxy::platformShowPaymentUI(const URL& originatingURL, const Vector<URL>& linkIconURLStrings, PAL::SessionID sessionID, const WebCore::ApplePaySessionPaymentRequest& request, CompletionHandler<void(bool)>&& completionHandler)
index 8ece6ed..7ad3331 100644 (file)
 
 namespace WebKit {
 
-bool WebPaymentCoordinatorProxy::platformCanMakePayments()
+void WebPaymentCoordinatorProxy::platformCanMakePayments(CompletionHandler<void(bool)>&& completionHandler)
 {
     if (!PAL::isPassKitFrameworkAvailable())
-        return false;
+        return completionHandler(false);
 
-    return [PAL::getPKPaymentAuthorizationViewControllerClass() canMakePayments];
+    m_canMakePaymentsQueue->dispatch([theClass = retainPtr(PAL::getPKPaymentAuthorizationViewControllerClass()), completionHandler = WTFMove(completionHandler)]() mutable {
+        RunLoop::main().dispatch([canMakePayments = [theClass canMakePayments], completionHandler = WTFMove(completionHandler)]() mutable {
+            completionHandler(canMakePayments);
+        });
+    });
 }
 
 void WebPaymentCoordinatorProxy::platformShowPaymentUI(const URL& originatingURL, const Vector<URL>& linkIconURLStrings, PAL::SessionID sessionID, const WebCore::ApplePaySessionPaymentRequest& request, CompletionHandler<void(bool)>&& completionHandler)