Make it possible to not include IPC Messages headers in other headers
[WebKit-https.git] / Source / WebKit / UIProcess / Plugins / PluginProcessManager.cpp
1 /*
2  * Copyright (C) 2010-2017 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 "PluginProcessManager.h"
28
29 #if ENABLE(NETSCAPE_PLUGIN_API)
30
31 #include "PluginProcessProxy.h"
32 #include "WebProcessProxyMessages.h"
33 #include "WebsiteDataFetchOption.h"
34 #include <wtf/CryptographicallyRandomNumber.h>
35 #include <wtf/NeverDestroyed.h>
36 #include <wtf/StdLibExtras.h>
37 #include <wtf/text/WTFString.h>
38
39 namespace WebKit {
40
41 PluginProcessManager& PluginProcessManager::singleton()
42 {
43     static NeverDestroyed<PluginProcessManager> pluginProcessManager;
44     return pluginProcessManager;
45 }
46
47 PluginProcessManager::PluginProcessManager()
48 #if PLATFORM(COCOA)
49     : m_processSuppressionDisabledForPageCounter([this](RefCounterEvent event) { updateProcessSuppressionDisabled(event); })
50 #endif
51 {
52 }
53
54 uint64_t PluginProcessManager::pluginProcessToken(const PluginModuleInfo& pluginModuleInfo, PluginProcessType pluginProcessType, PluginProcessSandboxPolicy pluginProcessSandboxPolicy)
55 {
56     // See if we know this token already.
57     for (size_t i = 0; i < m_pluginProcessTokens.size(); ++i) {
58         const PluginProcessAttributes& attributes = m_pluginProcessTokens[i].first;
59
60         if (attributes.moduleInfo.path == pluginModuleInfo.path
61             && attributes.processType == pluginProcessType
62             && attributes.sandboxPolicy == pluginProcessSandboxPolicy)
63             return m_pluginProcessTokens[i].second;
64     }
65
66     uint64_t token;
67     while (true) {
68         cryptographicallyRandomValues(&token, sizeof(token));
69
70         if (m_knownTokens.isValidValue(token) && !m_knownTokens.contains(token))
71             break;
72     }
73
74     PluginProcessAttributes attributes;
75     attributes.moduleInfo = pluginModuleInfo;
76     attributes.processType = pluginProcessType;
77     attributes.sandboxPolicy = pluginProcessSandboxPolicy;
78
79     m_pluginProcessTokens.append(std::make_pair(WTFMove(attributes), token));
80     m_knownTokens.add(token);
81
82     return token;
83 }
84
85 void PluginProcessManager::getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply&& reply)
86 {
87     ASSERT(pluginProcessToken);
88
89     PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken);
90     pluginProcess->getPluginProcessConnection(WTFMove(reply));
91 }
92
93 void PluginProcessManager::removePluginProcessProxy(PluginProcessProxy* pluginProcessProxy)
94 {
95     size_t vectorIndex = m_pluginProcesses.find(pluginProcessProxy);
96     ASSERT(vectorIndex != notFound);
97
98     m_pluginProcesses.remove(vectorIndex);
99 }
100
101 void PluginProcessManager::fetchWebsiteData(const PluginModuleInfo& plugin, OptionSet<WebsiteDataFetchOption> fetchOptions, WTF::Function<void (Vector<String>)>&& completionHandler)
102 {
103     auto token = pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal);
104     auto pluginProcess = fetchOptions.contains(WebsiteDataFetchOption::DoNotCreateProcesses) ? getPluginProcess(token) : getOrCreatePluginProcess(token);
105     if (!pluginProcess) {
106         completionHandler({ });
107         return;
108     }
109
110     pluginProcess->fetchWebsiteData(WTFMove(completionHandler));
111 }
112
113 void PluginProcessManager::deleteWebsiteData(const PluginModuleInfo& plugin, WallTime modifiedSince, WTF::Function<void ()>&& completionHandler)
114 {
115     PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal));
116     pluginProcess->deleteWebsiteData(modifiedSince, WTFMove(completionHandler));
117 }
118
119 void PluginProcessManager::deleteWebsiteDataForHostNames(const PluginModuleInfo& plugin, const Vector<String>& hostNames,WTF::Function<void ()>&& completionHandler)
120 {
121     PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal));
122     pluginProcess->deleteWebsiteDataForHostNames(hostNames, WTFMove(completionHandler));
123 }
124
125 PluginProcessProxy* PluginProcessManager::getPluginProcess(uint64_t pluginProcessToken)
126 {
127     for (const auto& pluginProcess : m_pluginProcesses) {
128         if (pluginProcess->pluginProcessToken() == pluginProcessToken)
129             return pluginProcess.get();
130     }
131
132     return nullptr;
133 }
134
135 #if OS(LINUX)
136 void PluginProcessManager::sendMemoryPressureEvent(bool isCritical)
137 {
138     for (auto& pluginProcess : m_pluginProcesses)
139         pluginProcess->sendMemoryPressureEvent(isCritical);
140 }
141 #endif
142
143 PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t pluginProcessToken)
144 {
145     if (auto existingProcess = getPluginProcess(pluginProcessToken))
146         return existingProcess;
147
148     for (auto& attributesAndToken : m_pluginProcessTokens) {
149         if (attributesAndToken.second == pluginProcessToken) {
150             auto pluginProcess = PluginProcessProxy::create(this, attributesAndToken.first, attributesAndToken.second);
151             PluginProcessProxy* pluginProcessPtr = pluginProcess.ptr();
152             m_pluginProcesses.append(WTFMove(pluginProcess));
153             return pluginProcessPtr;
154         }
155     }
156
157     return nullptr;
158 }
159
160 } // namespace WebKit
161
162 #endif // ENABLE(NETSCAPE_PLUGIN_API)