1/*
2 * Copyright (C) 2010 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 "PluginProcessConnection.h"
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "NPObjectMessageReceiverMessages.h"
32#include "NPRemoteObjectMap.h"
33#include "NPRuntimeObjectMap.h"
34#include "PluginProcessConnectionManager.h"
35#include "PluginProxy.h"
36#include "WebProcess.h"
37#include "WebProcessProxyMessages.h"
38#include <WebCore/FileSystem.h>
39#include <runtime/JSObject.h>
40
41using namespace WebCore;
42
43namespace WebKit {
44
45PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, uint64_t pluginProcessToken, IPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization)
46    : m_pluginProcessConnectionManager(pluginProcessConnectionManager)
47    , m_pluginProcessToken(pluginProcessToken)
48    , m_supportsAsynchronousPluginInitialization(supportsAsynchronousPluginInitialization)
49    , m_audioHardwareActivity(WebCore::AudioHardwareActivityType::Unknown)
50{
51    m_connection = IPC::Connection::createClientConnection(connectionIdentifier, this, RunLoop::main());
52
53    m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get());
54
55    m_connection->open();
56}
57
58PluginProcessConnection::~PluginProcessConnection()
59{
60    ASSERT(!m_connection);
61    ASSERT(!m_npRemoteObjectMap);
62}
63
64void PluginProcessConnection::addPluginProxy(PluginProxy* plugin)
65{
66    ASSERT(!m_plugins.contains(plugin->pluginInstanceID()));
67    m_plugins.set(plugin->pluginInstanceID(), plugin);
68}
69
70void PluginProcessConnection::removePluginProxy(PluginProxy* plugin)
71{
72    ASSERT(m_plugins.contains(plugin->pluginInstanceID()));
73    m_plugins.remove(plugin->pluginInstanceID());
74
75    // Invalidate all objects related to this plug-in.
76    m_npRemoteObjectMap->pluginDestroyed(plugin);
77
78    if (!m_plugins.isEmpty())
79        return;
80
81    m_npRemoteObjectMap = nullptr;
82
83    // We have no more plug-ins, invalidate the connection to the plug-in process.
84    ASSERT(m_connection);
85    m_connection->invalidate();
86    m_connection = nullptr;
87
88    // This will cause us to be deleted.
89    m_pluginProcessConnectionManager->removePluginProcessConnection(this);
90}
91
92void PluginProcessConnection::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)
93{
94    if (!decoder.destinationID()) {
95        didReceivePluginProcessConnectionMessage(connection, decoder);
96        return;
97    }
98
99    ASSERT(decoder.destinationID());
100
101    PluginProxy* pluginProxy = m_plugins.get(decoder.destinationID());
102    if (!pluginProxy)
103        return;
104
105    pluginProxy->didReceivePluginProxyMessage(connection, decoder);
106}
107
108void PluginProcessConnection::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
109{
110    if (decoder.messageReceiverName() == Messages::NPObjectMessageReceiver::messageReceiverName()) {
111        m_npRemoteObjectMap->didReceiveSyncMessage(connection, decoder, replyEncoder);
112        return;
113    }
114
115    uint64_t destinationID = decoder.destinationID();
116
117    if (!destinationID) {
118        didReceiveSyncPluginProcessConnectionMessage(connection, decoder, replyEncoder);
119        return;
120    }
121
122    PluginProxy* pluginProxy = m_plugins.get(destinationID);
123    if (!pluginProxy)
124        return;
125
126    pluginProxy->didReceiveSyncPluginProxyMessage(connection, decoder, replyEncoder);
127}
128
129void PluginProcessConnection::didClose(IPC::Connection*)
130{
131    // The plug-in process must have crashed.
132    for (HashMap<uint64_t, PluginProxy*>::const_iterator::Values it = m_plugins.begin().values(), end = m_plugins.end().values(); it != end; ++it) {
133        PluginProxy* pluginProxy = (*it);
134
135        pluginProxy->pluginProcessCrashed();
136    }
137}
138
139void PluginProcessConnection::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference)
140{
141}
142
143void PluginProcessConnection::setException(const String& exceptionString)
144{
145    NPRuntimeObjectMap::setGlobalException(exceptionString);
146}
147
148void PluginProcessConnection::audioHardwareDidBecomeActive()
149{
150    m_audioHardwareActivity = WebCore::AudioHardwareActivityType::IsActive;
151}
152
153void PluginProcessConnection::audioHardwareDidBecomeInactive()
154{
155    m_audioHardwareActivity = WebCore::AudioHardwareActivityType::IsInactive;
156}
157
158} // namespace WebKit
159
160#endif // ENABLE(NETSCAPE_PLUGIN_API)
161