Make it possible for apps that use both WK1 and WK2 to use MessagePorts.
[WebKit-https.git] / Source / WebCore / dom / messageports / MessagePortChannelProviderImpl.cpp
1 /*
2  * Copyright (C) 2018 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 #include "config.h"
27 #include "MessagePortChannelProviderImpl.h"
28
29 #include "MessagePort.h"
30 #include <wtf/CompletionHandler.h>
31 #include <wtf/MainThread.h>
32 #include <wtf/RunLoop.h>
33
34 namespace WebCore {
35
36 MessagePortChannelProviderImpl::MessagePortChannelProviderImpl()
37     : m_registry(*this)
38 {
39 }
40
41 MessagePortChannelProviderImpl::~MessagePortChannelProviderImpl()
42 {
43     ASSERT_NOT_REACHED();
44 }
45
46 void MessagePortChannelProviderImpl::performActionOnMainThread(Function<void()>&& action)
47 {
48     if (isMainThread())
49         action();
50     else
51         callOnMainThread(WTFMove(action));
52 }
53
54 void MessagePortChannelProviderImpl::createNewMessagePortChannel(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
55 {
56     performActionOnMainThread([registry = &m_registry, local, remote] {
57         registry->didCreateMessagePortChannel(local, remote);
58     });
59 }
60
61 void MessagePortChannelProviderImpl::entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
62 {
63     performActionOnMainThread([registry = &m_registry, local, remote] {
64         registry->didEntangleLocalToRemote(local, remote, Process::identifier());
65     });
66 }
67
68 void MessagePortChannelProviderImpl::messagePortDisentangled(const MessagePortIdentifier& local)
69 {
70     performActionOnMainThread([registry = &m_registry, local] {
71         registry->didDisentangleMessagePort(local);
72     });
73 }
74
75 void MessagePortChannelProviderImpl::messagePortClosed(const MessagePortIdentifier& local)
76 {
77     performActionOnMainThread([registry = &m_registry, local] {
78         registry->didCloseMessagePort(local);
79     });
80 }
81
82 void MessagePortChannelProviderImpl::postMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
83 {
84     performActionOnMainThread([registry = &m_registry, message = WTFMove(message), remoteTarget]() mutable {
85         bool wasFirstMessageInQueue = registry->didPostMessageToRemote(WTFMove(message), remoteTarget);
86         if (wasFirstMessageInQueue) {
87             if (auto remotePort = MessagePort::existingMessagePortForIdentifier(remoteTarget))
88                 remotePort->messageAvailable();
89         }
90     });
91 }
92
93 void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIdentifier& port, Function<void(Vector<MessageWithMessagePorts>&&, Function<void()>&&)>&& outerCallback)
94 {
95     // It is the responsibility of outerCallback to get itself to the appropriate thread (e.g. WebWorker thread)
96     auto callback = [outerCallback = WTFMove(outerCallback)](Vector<MessageWithMessagePorts>&& messages, Function<void()>&& messageDeliveryCallback) {
97         ASSERT(isMainThread());
98         outerCallback(WTFMove(messages), WTFMove(messageDeliveryCallback));
99     };
100
101     performActionOnMainThread([registry = &m_registry, port, callback = WTFMove(callback)]() mutable {
102         registry->takeAllMessagesForPort(port, WTFMove(callback));
103     });
104 }
105
106 void MessagePortChannelProviderImpl::checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(HasActivity)>&& outerCallback)
107 {
108     auto callback = CompletionHandler<void(HasActivity)> { [outerCallback = WTFMove(outerCallback)](HasActivity hasActivity) {
109         ASSERT(isMainThread());
110         outerCallback(hasActivity);
111     } };
112
113     performActionOnMainThread([registry = &m_registry, remoteTarget, callback = WTFMove(callback)]() mutable {
114         registry->checkRemotePortForActivity(remoteTarget, WTFMove(callback));
115     });
116 }
117
118 void MessagePortChannelProviderImpl::checkProcessLocalPortForActivity(const MessagePortIdentifier& identifier, ProcessIdentifier, CompletionHandler<void(HasActivity)>&& callback)
119 {
120     ASSERT(isMainThread());
121
122     auto port = MessagePort::existingMessagePortForIdentifier(identifier);
123     if (!port) {
124         callback(MessagePortChannelProvider::HasActivity::No);
125         return;
126     }
127
128     callback(port->isLocallyReachable() ? HasActivity::Yes : HasActivity::No);
129 }
130
131
132 } // namespace WebCore