Move plug-in enumeration back to the main thread
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebPlatformStrategies.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2012 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 "WebPlatformStrategies.h"
28
29 #if USE(PLATFORM_STRATEGIES)
30
31 #include "BlockingResponseMap.h"
32 #include "DataReference.h"
33 #include "NetworkResourceLoadParameters.h"
34 #include "PluginInfoStore.h"
35 #include "StorageNamespaceProxy.h"
36 #include "WebContextMessages.h"
37 #include "WebCookieManager.h"
38 #include "WebCoreArgumentCoders.h"
39 #include "WebErrors.h"
40 #include "WebPage.h"
41 #include "WebProcess.h"
42 #include "WebProcessProxyMessages.h"
43 #include <WebCore/Color.h>
44 #include <WebCore/KURL.h>
45 #include <WebCore/LoaderStrategy.h>
46 #include <WebCore/NetworkStorageSession.h>
47 #include <WebCore/NetworkingContext.h>
48 #include <WebCore/Page.h>
49 #include <WebCore/PlatformCookieJar.h>
50 #include <WebCore/PlatformPasteboard.h>
51 #include <WebCore/ResourceError.h>
52 #include <WebCore/StorageNamespace.h>
53 #include <wtf/Atomics.h>
54
55 #if ENABLE(NETWORK_PROCESS)
56 #include "NetworkConnectionToWebProcessMessages.h"
57 #include "NetworkProcessConnection.h"
58 #include "WebResourceLoadScheduler.h"
59 #endif
60
61 // FIXME: Remove this once it works well enough to be the default.
62 #define ENABLE_UI_PROCESS_STORAGE 0
63
64 using namespace WebCore;
65
66 namespace WebKit {
67
68 void WebPlatformStrategies::initialize()
69 {
70     DEFINE_STATIC_LOCAL(WebPlatformStrategies, platformStrategies, ());
71     setPlatformStrategies(&platformStrategies);
72 }
73
74 WebPlatformStrategies::WebPlatformStrategies()
75 #if ENABLE(NETSCAPE_PLUGIN_API)
76     : m_pluginCacheIsPopulated(false)
77     , m_shouldRefreshPlugins(false)
78 #endif // ENABLE(NETSCAPE_PLUGIN_API)
79 {
80 }
81
82 CookiesStrategy* WebPlatformStrategies::createCookiesStrategy()
83 {
84     return this;
85 }
86
87 DatabaseStrategy* WebPlatformStrategies::createDatabaseStrategy()
88 {
89     return this;
90 }
91
92 LoaderStrategy* WebPlatformStrategies::createLoaderStrategy()
93 {
94     return this;
95 }
96
97 PasteboardStrategy* WebPlatformStrategies::createPasteboardStrategy()
98 {
99     return this;
100 }
101
102 PluginStrategy* WebPlatformStrategies::createPluginStrategy()
103 {
104     return this;
105 }
106
107 SharedWorkerStrategy* WebPlatformStrategies::createSharedWorkerStrategy()
108 {
109     return this;
110 }
111
112 StorageStrategy* WebPlatformStrategies::createStorageStrategy()
113 {
114     return this;
115 }
116
117 VisitedLinkStrategy* WebPlatformStrategies::createVisitedLinkStrategy()
118 {
119     return this;
120 }
121
122 // CookiesStrategy
123
124 String WebPlatformStrategies::cookiesForDOM(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
125 {
126 #if ENABLE(NETWORK_PROCESS)
127     if (WebProcess::shared().usesNetworkProcess()) {
128         String result;
129         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookiesForDOM(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookiesForDOM::Reply(result), 0))
130             return String();
131         return result;
132     }
133 #endif
134
135     return WebCore::cookiesForDOM(session, firstParty, url);
136 }
137
138 void WebPlatformStrategies::setCookiesFromDOM(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url, const String& cookieString)
139 {
140 #if ENABLE(NETWORK_PROCESS)
141     if (WebProcess::shared().usesNetworkProcess()) {
142         WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::SetCookiesFromDOM(session.isPrivateBrowsingSession(), firstParty, url, cookieString), 0);
143         return;
144     }
145 #endif
146
147     WebCore::setCookiesFromDOM(session, firstParty, url, cookieString);
148 }
149
150 bool WebPlatformStrategies::cookiesEnabled(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
151 {
152 #if ENABLE(NETWORK_PROCESS)
153     if (WebProcess::shared().usesNetworkProcess()) {
154         bool result;
155         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookiesEnabled(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookiesEnabled::Reply(result), 0))
156             return false;
157         return result;
158     }
159 #endif
160
161     return WebCore::cookiesEnabled(session, firstParty, url);
162 }
163
164 String WebPlatformStrategies::cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url)
165 {
166 #if ENABLE(NETWORK_PROCESS)
167     if (WebProcess::shared().usesNetworkProcess()) {
168         String result;
169         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::CookieRequestHeaderFieldValue(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::CookieRequestHeaderFieldValue::Reply(result), 0))
170             return String();
171         return result;
172     }
173 #endif
174
175     return WebCore::cookieRequestHeaderFieldValue(session, firstParty, url);
176 }
177
178 bool WebPlatformStrategies::getRawCookies(const NetworkStorageSession& session, const KURL& firstParty, const KURL& url, Vector<Cookie>& rawCookies)
179 {
180 #if ENABLE(NETWORK_PROCESS)
181     if (WebProcess::shared().usesNetworkProcess()) {
182         if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::GetRawCookies(session.isPrivateBrowsingSession(), firstParty, url), Messages::NetworkConnectionToWebProcess::GetRawCookies::Reply(rawCookies), 0))
183             return false;
184         return true;
185     }
186 #endif
187
188     return WebCore::getRawCookies(session, firstParty, url, rawCookies);
189 }
190
191 void WebPlatformStrategies::deleteCookie(const NetworkStorageSession& session, const KURL& url, const String& cookieName)
192 {
193 #if ENABLE(NETWORK_PROCESS)
194     if (WebProcess::shared().usesNetworkProcess()) {
195         WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::DeleteCookie(session.isPrivateBrowsingSession(), url, cookieName), 0);
196         return;
197     }
198 #endif
199
200     WebCore::deleteCookie(session, url, cookieName);
201 }
202
203 // DatabaseStrategy
204
205 #if ENABLE(SQL_DATABASE)
206 AbstractDatabaseServer* WebPlatformStrategies::getDatabaseServer()
207 {
208     return DatabaseStrategy::getDatabaseServer(); // Use the default for now.
209 }
210 #endif
211
212 // LoaderStrategy
213
214 #if ENABLE(NETWORK_PROCESS)
215 ResourceLoadScheduler* WebPlatformStrategies::resourceLoadScheduler()
216 {
217     static ResourceLoadScheduler* scheduler;
218     if (!scheduler) {
219         if (WebProcess::shared().usesNetworkProcess())
220             scheduler = &WebProcess::shared().webResourceLoadScheduler();
221         else
222             scheduler = WebCore::resourceLoadScheduler();
223     }
224     
225     return scheduler;
226 }
227
228 void WebPlatformStrategies::loadResourceSynchronously(NetworkingContext* context, unsigned long resourceLoadIdentifier, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data)
229 {
230     if (!WebProcess::shared().usesNetworkProcess()) {
231         LoaderStrategy::loadResourceSynchronously(context, resourceLoadIdentifier, request, storedCredentials, error, response, data);
232         return;
233     }
234
235     CoreIPC::DataReference dataReference;
236
237     NetworkResourceLoadParameters loadParameters(resourceLoadIdentifier, 0, 0, request, ResourceLoadPriorityHighest, SniffContent, storedCredentials, context->storageSession().isPrivateBrowsingSession(), context->shouldClearReferrerOnHTTPSToHTTPRedirect());
238     if (!WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, dataReference), 0)) {
239         response = ResourceResponse();
240         error = internalError(request.url());
241         data.resize(0);
242
243         return;
244     }
245
246     data.resize(dataReference.size());
247     memcpy(data.data(), dataReference.data(), dataReference.size());
248 }
249
250 #endif
251
252 // PluginStrategy
253
254 void WebPlatformStrategies::refreshPlugins()
255 {
256 #if ENABLE(NETSCAPE_PLUGIN_API)
257     m_cachedPlugins.clear();
258     m_pluginCacheIsPopulated = false;
259     m_shouldRefreshPlugins = true;
260
261     populatePluginCache();
262 #endif // ENABLE(NETSCAPE_PLUGIN_API)
263 }
264
265 void WebPlatformStrategies::getPluginInfo(const WebCore::Page*, Vector<WebCore::PluginInfo>& plugins)
266 {
267 #if ENABLE(NETSCAPE_PLUGIN_API)
268     populatePluginCache();
269     plugins = m_cachedPlugins;
270 #endif // ENABLE(NETSCAPE_PLUGIN_API)
271 }
272
273 #if ENABLE(NETSCAPE_PLUGIN_API)
274 void WebPlatformStrategies::populatePluginCache()
275 {
276     if (m_pluginCacheIsPopulated)
277         return;
278
279     ASSERT(m_cachedPlugins.isEmpty());
280     
281     // FIXME: Should we do something in case of error here?
282     if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::GetPlugins(m_shouldRefreshPlugins), Messages::WebProcessProxy::GetPlugins::Reply(m_cachedPlugins), 0))
283         return;
284
285     m_shouldRefreshPlugins = false;
286     m_pluginCacheIsPopulated = true;
287 }
288 #endif // ENABLE(NETSCAPE_PLUGIN_API)
289
290 // StorageStrategy
291
292 PassRefPtr<StorageNamespace> WebPlatformStrategies::localStorageNamespace(const String& path, unsigned quota)
293 {
294     return StorageStrategy::localStorageNamespace(path, quota);
295 }
296
297 PassRefPtr<StorageNamespace> WebPlatformStrategies::sessionStorageNamespace(Page* page, unsigned quota)
298 {
299 #if ENABLE(UI_PROCESS_STORAGE)
300     return StorageNamespaceProxy::createSessionStorageNamespace(WebPage::fromCorePage(page));
301 #else
302     return StorageStrategy::sessionStorageNamespace(page, quota);
303 #endif
304 }
305
306 // VisitedLinkStrategy
307
308 bool WebPlatformStrategies::isLinkVisited(Page*, LinkHash linkHash, const KURL&, const AtomicString&)
309 {
310     return WebProcess::shared().isLinkVisited(linkHash);
311 }
312
313 void WebPlatformStrategies::addVisitedLink(Page*, LinkHash linkHash)
314 {
315     WebProcess::shared().addVisitedLink(linkHash);
316 }
317
318 #if PLATFORM(MAC)
319 // PasteboardStrategy
320
321 void WebPlatformStrategies::getTypes(Vector<String>& types, const String& pasteboardName)
322 {
323     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardTypes(pasteboardName),
324                                                 Messages::WebContext::GetPasteboardTypes::Reply(types), 0);
325 }
326
327 PassRefPtr<WebCore::SharedBuffer> WebPlatformStrategies::bufferForType(const String& pasteboardType, const String& pasteboardName)
328 {
329     SharedMemory::Handle handle;
330     uint64_t size = 0;
331     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardBufferForType(pasteboardName, pasteboardType),
332                                                 Messages::WebContext::GetPasteboardBufferForType::Reply(handle, size), 0);
333     if (handle.isNull())
334         return 0;
335     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly);
336     return SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
337 }
338
339 void WebPlatformStrategies::getPathnamesForType(Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
340 {
341     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardPathnamesForType(pasteboardName, pasteboardType),
342                                                 Messages::WebContext::GetPasteboardPathnamesForType::Reply(pathnames), 0);
343 }
344
345 String WebPlatformStrategies::stringForType(const String& pasteboardType, const String& pasteboardName)
346 {
347     String value;
348     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardStringForType(pasteboardName, pasteboardType),
349                                                 Messages::WebContext::GetPasteboardStringForType::Reply(value), 0);
350     return value;
351 }
352
353 void WebPlatformStrategies::copy(const String& fromPasteboard, const String& toPasteboard)
354 {
355     WebProcess::shared().connection()->send(Messages::WebContext::PasteboardCopy(fromPasteboard, toPasteboard), 0);
356 }
357
358 int WebPlatformStrategies::changeCount(const WTF::String &pasteboardName)
359 {
360     uint64_t changeCount;
361     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardChangeCount(pasteboardName),
362                                                 Messages::WebContext::GetPasteboardChangeCount::Reply(changeCount), 0);
363     return changeCount;
364 }
365
366 String WebPlatformStrategies::uniqueName()
367 {
368     String pasteboardName;
369     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardUniqueName(),
370                                                 Messages::WebContext::GetPasteboardUniqueName::Reply(pasteboardName), 0);
371     return pasteboardName;
372 }
373
374 Color WebPlatformStrategies::color(const String& pasteboardName)
375 {
376     Color color;
377     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardColor(pasteboardName),
378                                                 Messages::WebContext::GetPasteboardColor::Reply(color), 0);
379     return color;
380 }
381
382 KURL WebPlatformStrategies::url(const String& pasteboardName)
383 {
384     String urlString;
385     WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPasteboardURL(pasteboardName),
386                                                 Messages::WebContext::GetPasteboardURL::Reply(urlString), 0);
387     return KURL(ParsedURLString, urlString);
388 }
389
390 void WebPlatformStrategies::addTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
391 {
392     WebProcess::shared().connection()->send(Messages::WebContext::AddPasteboardTypes(pasteboardName, pasteboardTypes), 0);
393 }
394
395 void WebPlatformStrategies::setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
396 {
397     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardTypes(pasteboardName, pasteboardTypes), 0);
398 }
399
400 void WebPlatformStrategies::setBufferForType(PassRefPtr<SharedBuffer> buffer, const String& pasteboardType, const String& pasteboardName)
401 {
402     SharedMemory::Handle handle;
403     if (buffer) {
404         RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(buffer->size());
405         memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
406         sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly);
407     }
408     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardBufferForType(pasteboardName, pasteboardType, handle, buffer ? buffer->size() : 0), 0);
409 }
410
411 void WebPlatformStrategies::setPathnamesForType(const Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
412 {
413     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardPathnamesForType(pasteboardName, pasteboardType, pathnames), 0);
414 }
415
416 void WebPlatformStrategies::setStringForType(const String& string, const String& pasteboardType, const String& pasteboardName)
417 {
418     WebProcess::shared().connection()->send(Messages::WebContext::SetPasteboardStringForType(pasteboardName, pasteboardType, string), 0);
419 }
420 #endif
421
422 } // namespace WebKit
423
424 #endif // USE(PLATFORM_STRATEGIES)