• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GetSitesWithDataState(WebPluginSiteDataManager * webPluginSiteDataManager,uint64_t callbackID)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 
getSitesWithDataForNextPlugin()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 
didGetSitesWithDataForSinglePlugin(const Vector<String> & sites)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<PluginInfoStore::Plugin> m_plugins;
74     HashSet<String> m_sites;
75 };
76 
77 class WebPluginSiteDataManager::ClearSiteDataState {
78 public:
ClearSiteDataState(WebPluginSiteDataManager * webPluginSiteDataManager,const Vector<String> & sites,uint64_t flags,uint64_t maxAgeInSeconds,uint64_t callbackID)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 
clearSiteDataForNextPlugin()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 
didClearSiteDataForSinglePlugin()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<PluginInfoStore::Plugin> m_plugins;
112 };
113 #endif // ENABLE(PLUGIN_PROCESS)
114 
create(WebContext * webContext)115 PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext)
116 {
117     return adoptRef(new WebPluginSiteDataManager(webContext));
118 }
119 
WebPluginSiteDataManager(WebContext * webContext)120 WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext)
121     : m_webContext(webContext)
122 {
123 }
124 
~WebPluginSiteDataManager()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 
invalidate()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 
getSitesWithData(PassRefPtr<ArrayCallback> prpCallback)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<String> pluginPaths;
169     m_webContext->pluginInfoStore()->getPluginPaths(pluginPaths);
170 
171     // FIXME (Multi-WebProcess): When multi-process is enabled, we must always use a plug-in process for this,
172     // so this code should just be removed.
173     m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::GetSitesWithPluginData(pluginPaths, callbackID));
174 #endif
175 }
176 
didGetSitesWithData(const Vector<String> & sites,uint64_t callbackID)177 void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID)
178 {
179     RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID);
180     if (!callback) {
181         // FIXME: Log error or assert.
182         return;
183     }
184 
185     Vector<RefPtr<APIObject> > sitesWK(sites.size());
186 
187     for (size_t i = 0; i < sites.size(); ++i)
188         sitesWK[i] = WebString::create(sites[i]);
189 
190     RefPtr<ImmutableArray> resultArray = ImmutableArray::adopt(sitesWK);
191     callback->performCallbackWithReturnValue(resultArray.get());
192 }
193 
clearSiteData(ImmutableArray * sites,uint64_t flags,uint64_t maxAgeInSeconds,PassRefPtr<VoidCallback> prpCallback)194 void WebPluginSiteDataManager::clearSiteData(ImmutableArray* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback> prpCallback)
195 {
196     RefPtr<VoidCallback> callback = prpCallback;
197     if (!m_webContext) {
198         callback->invalidate();
199         return;
200     }
201 
202     Vector<String> sitesVector;
203 
204     // If the array is empty, don't do anything.
205     if (sites) {
206         if (!sites->size()) {
207             callback->performCallback();
208             return;
209         }
210 
211         for (size_t i = 0; i < sites->size(); ++i) {
212             if (WebString* site = sites->at<WebString>(i))
213                 sitesVector.append(site->string());
214         }
215     }
216 
217     uint64_t callbackID = callback->callbackID();
218     m_voidCallbacks.set(callbackID, callback.release());
219 
220 #if ENABLE(PLUGIN_PROCESS)
221     ASSERT(!m_pendingClearSiteData.contains(callbackID));
222 
223     ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID);
224     m_pendingClearSiteData.set(callbackID, state);
225     state->clearSiteDataForNextPlugin();
226 #else
227 
228     m_webContext->relaunchProcessIfNecessary();
229     Vector<String> pluginPaths;
230     m_webContext->pluginInfoStore()->getPluginPaths(pluginPaths);
231 
232     // FIXME (Multi-WebProcess): When multi-process is enabled, we must always use a plug-in process for this,
233     // so this code should just be removed.
234     m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::ClearPluginSiteData(pluginPaths, sitesVector, flags, maxAgeInSeconds, callbackID));
235 #endif
236 }
237 
didClearSiteData(uint64_t callbackID)238 void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID)
239 {
240     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
241     if (!callback) {
242         // FIXME: Log error or assert.
243         return;
244     }
245 
246     callback->performCallback();
247 }
248 
shouldTerminate(WebProcessProxy *) const249 bool WebPluginSiteDataManager::shouldTerminate(WebProcessProxy*) const
250 {
251 #if ENABLE(PLUGIN_PROCESS)
252     // When out of process plug-ins are enabled, the web process is not involved in fetching site data.
253     return true;
254 #else
255     return m_arrayCallbacks.isEmpty() && m_voidCallbacks.isEmpty();
256 #endif
257 }
258 
259 #if ENABLE(PLUGIN_PROCESS)
didGetSitesWithDataForSinglePlugin(const Vector<String> & sites,uint64_t callbackID)260 void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID)
261 {
262     GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID);
263     ASSERT(state);
264 
265     state->didGetSitesWithDataForSinglePlugin(sites);
266 }
267 
didGetSitesWithDataForAllPlugins(const Vector<String> & sites,uint64_t callbackID)268 void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID)
269 {
270     OwnPtr<GetSitesWithDataState> state = adoptPtr(m_pendingGetSitesWithData.take(callbackID));
271     ASSERT(state);
272 
273     didGetSitesWithData(sites, callbackID);
274 }
275 
didClearSiteDataForSinglePlugin(uint64_t callbackID)276 void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID)
277 {
278     ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID);
279     ASSERT(state);
280 
281     state->didClearSiteDataForSinglePlugin();
282 }
283 
didClearSiteDataForAllPlugins(uint64_t callbackID)284 void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID)
285 {
286     OwnPtr<ClearSiteDataState> state = adoptPtr(m_pendingClearSiteData.take(callbackID));
287     ASSERT(state);
288 
289     didClearSiteData(callbackID);
290 }
291 
292 #endif
293 
294 } // namespace WebKit
295 
296