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