initial import
[vuplus_webkit] / Source / WebKit2 / UIProcess / Plugins / WebPluginSiteDataManager.cpp
1 /*
2  * Copyright (C) 2011 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 "WebPluginSiteDataManager.h"
28
29 #include "ImmutableArray.h"
30 #include "PluginProcessManager.h"
31 #include "WebContext.h"
32 #include "WebProcessMessages.h"
33
34 using namespace WebCore;
35
36 namespace WebKit {
37
38 #if ENABLE(PLUGIN_PROCESS)
39 class WebPluginSiteDataManager::GetSitesWithDataState {
40 public:
41     explicit GetSitesWithDataState(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID)
42         : m_webPluginSiteDataManager(webPluginSiteDataManager)
43         , m_callbackID(callbackID)
44         , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins())
45     {
46     }
47
48     void getSitesWithDataForNextPlugin()
49     {
50         if (m_plugins.isEmpty()) {
51             Vector<String> sites;
52             copyToVector(m_sites, sites);
53
54             m_webPluginSiteDataManager->didGetSitesWithDataForAllPlugins(sites, m_callbackID);
55             return;
56         }
57
58         PluginProcessManager::shared().getSitesWithData(m_plugins.last(), m_webPluginSiteDataManager, m_callbackID);
59         m_plugins.removeLast();
60     }
61
62     void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites)
63     {
64         for (size_t i = 0; i < sites.size(); ++i)
65             m_sites.add(sites[i]);
66
67         getSitesWithDataForNextPlugin();
68     }
69     
70 private:
71     WebPluginSiteDataManager* m_webPluginSiteDataManager;
72     uint64_t m_callbackID;
73     Vector<PluginModuleInfo> m_plugins;
74     HashSet<String> m_sites;
75 };
76
77 class WebPluginSiteDataManager::ClearSiteDataState {
78 public:
79     explicit ClearSiteDataState(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
80         : m_webPluginSiteDataManager(webPluginSiteDataManager)
81         , m_sites(sites)
82         , m_flags(flags)
83         , m_maxAgeInSeconds(maxAgeInSeconds)
84         , m_callbackID(callbackID)
85         , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins())
86     {
87     }
88
89     void clearSiteDataForNextPlugin()
90     {
91         if (m_plugins.isEmpty()) {
92             m_webPluginSiteDataManager->didClearSiteDataForAllPlugins(m_callbackID);
93             return;
94         }
95
96         PluginProcessManager::shared().clearSiteData(m_plugins.last(), m_webPluginSiteDataManager, m_sites, m_flags, m_maxAgeInSeconds, m_callbackID);
97         m_plugins.removeLast();
98     }
99
100     void didClearSiteDataForSinglePlugin()
101     {
102         clearSiteDataForNextPlugin();
103     }
104     
105 private:
106     WebPluginSiteDataManager* m_webPluginSiteDataManager;
107     Vector<String> m_sites;
108     uint64_t m_flags;
109     uint64_t m_maxAgeInSeconds;
110     uint64_t m_callbackID;
111     Vector<PluginModuleInfo> m_plugins;
112 };
113 #endif // ENABLE(PLUGIN_PROCESS)
114
115 PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext)
116 {
117     return adoptRef(new WebPluginSiteDataManager(webContext));
118 }
119
120 WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext)
121     : m_webContext(webContext)
122 {
123 }
124
125 WebPluginSiteDataManager::~WebPluginSiteDataManager()
126 {
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());
132 #endif
133 }
134
135 void WebPluginSiteDataManager::invalidate()
136 {
137     invalidateCallbackMap(m_arrayCallbacks);
138
139 #if ENABLE(PLUGIN_PROCESS)
140     deleteAllValues(m_pendingGetSitesWithData);
141     m_pendingGetSitesWithData.clear();
142     deleteAllValues(m_pendingClearSiteData);
143     m_pendingClearSiteData.clear();
144 #endif
145 }
146
147 void WebPluginSiteDataManager::getSitesWithData(PassRefPtr<ArrayCallback> prpCallback)
148 {
149     RefPtr<ArrayCallback> callback = prpCallback;
150
151     if (!m_webContext) {
152         callback->invalidate();
153         return;
154     }
155
156     uint64_t callbackID = callback->callbackID();
157     m_arrayCallbacks.set(callbackID, callback.release());
158
159 #if ENABLE(PLUGIN_PROCESS)
160     ASSERT(!m_pendingGetSitesWithData.contains(callbackID));
161
162     GetSitesWithDataState* state = new GetSitesWithDataState(this, callbackID);
163     m_pendingGetSitesWithData.set(callbackID, state);
164     state->getSitesWithDataForNextPlugin();
165 #else
166     m_webContext->relaunchProcessIfNecessary();
167
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);
172
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));
176 #endif
177 }
178
179 void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID)
180 {
181     RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
182     if (!callback) {
183         // FIXME: Log error or assert.
184         return;
185     }
186
187     Vector<RefPtr<APIObject> > sitesWK(sites.size());
188
189     for (size_t i = 0; i < sites.size(); ++i)
190         sitesWK[i] = WebString::create(sites[i]);
191
192     RefPtr<ImmutableArray> resultArray = ImmutableArray::adopt(sitesWK);
193     callback->performCallbackWithReturnValue(resultArray.get());
194 }
195
196 void WebPluginSiteDataManager::clearSiteData(ImmutableArray* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback> prpCallback)
197 {
198     RefPtr<VoidCallback> callback = prpCallback;
199     if (!m_webContext) {
200         callback->invalidate();
201         return;
202     }
203
204     Vector<String> sitesVector;
205
206     // If the array is empty, don't do anything.
207     if (sites) {
208         if (!sites->size()) {
209             callback->performCallback();
210             return;
211         }
212
213         for (size_t i = 0; i < sites->size(); ++i) {
214             if (WebString* site = sites->at<WebString>(i))
215                 sitesVector.append(site->string());
216         }
217     }
218
219     uint64_t callbackID = callback->callbackID();
220     m_voidCallbacks.set(callbackID, callback.release());
221
222 #if ENABLE(PLUGIN_PROCESS)
223     ASSERT(!m_pendingClearSiteData.contains(callbackID));
224
225     ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID);
226     m_pendingClearSiteData.set(callbackID, state);
227     state->clearSiteDataForNextPlugin();
228 #else
229     m_webContext->relaunchProcessIfNecessary();
230
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);
235
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));
239 #endif
240 }
241
242 void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID)
243 {
244     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
245     if (!callback) {
246         // FIXME: Log error or assert.
247         return;
248     }
249
250     callback->performCallback();
251 }
252
253 bool WebPluginSiteDataManager::shouldTerminate(WebProcessProxy*) const
254 {
255 #if ENABLE(PLUGIN_PROCESS)
256     // When out of process plug-ins are enabled, the web process is not involved in fetching site data.
257     return true;
258 #else
259     return m_arrayCallbacks.isEmpty() && m_voidCallbacks.isEmpty();
260 #endif
261 }
262
263 #if ENABLE(PLUGIN_PROCESS)
264 void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID)
265 {
266     GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID);
267     ASSERT(state);
268
269     state->didGetSitesWithDataForSinglePlugin(sites);
270 }
271
272 void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID)
273 {
274     OwnPtr<GetSitesWithDataState> state = adoptPtr(m_pendingGetSitesWithData.take(callbackID));
275     ASSERT(state);
276
277     didGetSitesWithData(sites, callbackID);
278 }
279
280 void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID)
281 {
282     ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID);
283     ASSERT(state);
284     
285     state->didClearSiteDataForSinglePlugin();
286 }
287
288 void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID)
289 {
290     OwnPtr<ClearSiteDataState> state = adoptPtr(m_pendingClearSiteData.take(callbackID));
291     ASSERT(state);
292
293     didClearSiteData(callbackID);
294 }
295
296 #endif
297
298 } // namespace WebKit
299