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