2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebPluginSiteDataManager.h"
29 #include "ImmutableArray.h"
30 #include "PluginProcessManager.h"
31 #include "WebContext.h"
32 #include "WebProcessMessages.h"
34 using namespace WebCore;
38 #if ENABLE(PLUGIN_PROCESS)
39 class WebPluginSiteDataManager::GetSitesWithDataState {
41 explicit GetSitesWithDataState(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID)
42 : m_webPluginSiteDataManager(webPluginSiteDataManager)
43 , m_callbackID(callbackID)
44 , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins())
48 void getSitesWithDataForNextPlugin()
50 if (m_plugins.isEmpty()) {
52 copyToVector(m_sites, sites);
54 m_webPluginSiteDataManager->didGetSitesWithDataForAllPlugins(sites, m_callbackID);
58 PluginProcessManager::shared().getSitesWithData(m_plugins.last(), m_webPluginSiteDataManager, m_callbackID);
59 m_plugins.removeLast();
62 void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites)
64 for (size_t i = 0; i < sites.size(); ++i)
65 m_sites.add(sites[i]);
67 getSitesWithDataForNextPlugin();
71 WebPluginSiteDataManager* m_webPluginSiteDataManager;
72 uint64_t m_callbackID;
73 Vector<PluginModuleInfo> m_plugins;
74 HashSet<String> m_sites;
77 class WebPluginSiteDataManager::ClearSiteDataState {
79 explicit ClearSiteDataState(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
80 : m_webPluginSiteDataManager(webPluginSiteDataManager)
83 , m_maxAgeInSeconds(maxAgeInSeconds)
84 , m_callbackID(callbackID)
85 , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins())
89 void clearSiteDataForNextPlugin()
91 if (m_plugins.isEmpty()) {
92 m_webPluginSiteDataManager->didClearSiteDataForAllPlugins(m_callbackID);
96 PluginProcessManager::shared().clearSiteData(m_plugins.last(), m_webPluginSiteDataManager, m_sites, m_flags, m_maxAgeInSeconds, m_callbackID);
97 m_plugins.removeLast();
100 void didClearSiteDataForSinglePlugin()
102 clearSiteDataForNextPlugin();
106 WebPluginSiteDataManager* m_webPluginSiteDataManager;
107 Vector<String> m_sites;
109 uint64_t m_maxAgeInSeconds;
110 uint64_t m_callbackID;
111 Vector<PluginModuleInfo> m_plugins;
113 #endif // ENABLE(PLUGIN_PROCESS)
115 PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext)
117 return adoptRef(new WebPluginSiteDataManager(webContext));
120 WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext)
121 : m_webContext(webContext)
125 WebPluginSiteDataManager::~WebPluginSiteDataManager()
127 ASSERT(m_arrayCallbacks.isEmpty());
128 ASSERT(m_voidCallbacks.isEmpty());
129 #if ENABLE(PLUGIN_PROCESS)
130 ASSERT(m_pendingGetSitesWithData.isEmpty());
131 ASSERT(m_pendingClearSiteData.isEmpty());
135 void WebPluginSiteDataManager::invalidate()
137 invalidateCallbackMap(m_arrayCallbacks);
139 #if ENABLE(PLUGIN_PROCESS)
140 deleteAllValues(m_pendingGetSitesWithData);
141 m_pendingGetSitesWithData.clear();
142 deleteAllValues(m_pendingClearSiteData);
143 m_pendingClearSiteData.clear();
147 void WebPluginSiteDataManager::getSitesWithData(PassRefPtr<ArrayCallback> prpCallback)
149 RefPtr<ArrayCallback> callback = prpCallback;
152 callback->invalidate();
156 uint64_t callbackID = callback->callbackID();
157 m_arrayCallbacks.set(callbackID, callback.release());
159 #if ENABLE(PLUGIN_PROCESS)
160 ASSERT(!m_pendingGetSitesWithData.contains(callbackID));
162 GetSitesWithDataState* state = new GetSitesWithDataState(this, callbackID);
163 m_pendingGetSitesWithData.set(callbackID, state);
164 state->getSitesWithDataForNextPlugin();
166 m_webContext->relaunchProcessIfNecessary();
168 Vector<PluginModuleInfo> plugins = m_webContext->pluginInfoStore().plugins();
169 Vector<String> pluginPaths;
170 for (size_t i = 0; i < plugins.size(); ++i)
171 pluginPaths.append(plugins[i].path);
173 // FIXME (Multi-WebProcess): When multi-process is enabled, we must always use a plug-in process for this,
174 // so this code should just be removed.
175 m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::GetSitesWithPluginData(pluginPaths, callbackID));
179 void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID)
181 RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
183 // FIXME: Log error or assert.
187 Vector<RefPtr<APIObject> > sitesWK(sites.size());
189 for (size_t i = 0; i < sites.size(); ++i)
190 sitesWK[i] = WebString::create(sites[i]);
192 RefPtr<ImmutableArray> resultArray = ImmutableArray::adopt(sitesWK);
193 callback->performCallbackWithReturnValue(resultArray.get());
196 void WebPluginSiteDataManager::clearSiteData(ImmutableArray* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback> prpCallback)
198 RefPtr<VoidCallback> callback = prpCallback;
200 callback->invalidate();
204 Vector<String> sitesVector;
206 // If the array is empty, don't do anything.
208 if (!sites->size()) {
209 callback->performCallback();
213 for (size_t i = 0; i < sites->size(); ++i) {
214 if (WebString* site = sites->at<WebString>(i))
215 sitesVector.append(site->string());
219 uint64_t callbackID = callback->callbackID();
220 m_voidCallbacks.set(callbackID, callback.release());
222 #if ENABLE(PLUGIN_PROCESS)
223 ASSERT(!m_pendingClearSiteData.contains(callbackID));
225 ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID);
226 m_pendingClearSiteData.set(callbackID, state);
227 state->clearSiteDataForNextPlugin();
229 m_webContext->relaunchProcessIfNecessary();
231 Vector<PluginModuleInfo> plugins = m_webContext->pluginInfoStore().plugins();
232 Vector<String> pluginPaths;
233 for (size_t i = 0; i < plugins.size(); ++i)
234 pluginPaths.append(plugins[i].path);
236 // FIXME (Multi-WebProcess): When multi-process is enabled, we must always use a plug-in process for this,
237 // so this code should just be removed.
238 m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::ClearPluginSiteData(pluginPaths, sitesVector, flags, maxAgeInSeconds, callbackID));
242 void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID)
244 RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
246 // FIXME: Log error or assert.
250 callback->performCallback();
253 bool WebPluginSiteDataManager::shouldTerminate(WebProcessProxy*) const
255 #if ENABLE(PLUGIN_PROCESS)
256 // When out of process plug-ins are enabled, the web process is not involved in fetching site data.
259 return m_arrayCallbacks.isEmpty() && m_voidCallbacks.isEmpty();
263 #if ENABLE(PLUGIN_PROCESS)
264 void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID)
266 GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID);
269 state->didGetSitesWithDataForSinglePlugin(sites);
272 void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID)
274 OwnPtr<GetSitesWithDataState> state = adoptPtr(m_pendingGetSitesWithData.take(callbackID));
277 didGetSitesWithData(sites, callbackID);
280 void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID)
282 ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID);
285 state->didClearSiteDataForSinglePlugin();
288 void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID)
290 OwnPtr<ClearSiteDataState> state = adoptPtr(m_pendingClearSiteData.take(callbackID));
293 didClearSiteData(callbackID);
298 } // namespace WebKit