f1fe4b6b1f0191446dd8f805b3dd9e009310abd8
[WebKit.git] / Source / WebKit / WebProcess / WebCoreSupport / WebPlatformStrategies.cpp
1 /*
2  * Copyright (C) 2010-2018 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 #include "BlobRegistryProxy.h"
30 #include "BlockingResponseMap.h"
31 #include "DataReference.h"
32 #include "HangDetectionDisabler.h"
33 #include "NetworkConnectionToWebProcessMessages.h"
34 #include "NetworkProcessConnection.h"
35 #include "NetworkResourceLoadParameters.h"
36 #include "PluginInfoStore.h"
37 #include "WebCoreArgumentCoders.h"
38 #include "WebErrors.h"
39 #include "WebFrame.h"
40 #include "WebFrameLoaderClient.h"
41 #include "WebLoaderStrategy.h"
42 #include "WebPage.h"
43 #include "WebPasteboardOverrides.h"
44 #include "WebPasteboardProxyMessages.h"
45 #include "WebProcess.h"
46 #include "WebProcessProxyMessages.h"
47 #include <WebCore/Color.h>
48 #include <WebCore/Document.h>
49 #include <WebCore/DocumentLoader.h>
50 #include <WebCore/Frame.h>
51 #include <WebCore/LoaderStrategy.h>
52 #include <WebCore/NetworkStorageSession.h>
53 #include <WebCore/Page.h>
54 #include <WebCore/PageGroup.h>
55 #include <WebCore/PasteboardItemInfo.h>
56 #include <WebCore/PlatformPasteboard.h>
57 #include <WebCore/ProgressTracker.h>
58 #include <WebCore/ResourceError.h>
59 #include <WebCore/SameSiteInfo.h>
60 #include <WebCore/StorageNamespace.h>
61 #include <WebCore/SubframeLoader.h>
62 #include <wtf/Atomics.h>
63 #include <wtf/URL.h>
64
65 #if PLATFORM(MAC)
66 #include "StringUtilities.h"
67 #endif
68
69 #if PLATFORM(GTK)
70 #include "WebSelectionData.h"
71 #endif
72
73 namespace WebKit {
74 using namespace WebCore;
75
76 void WebPlatformStrategies::initialize()
77 {
78     static NeverDestroyed<WebPlatformStrategies> platformStrategies;
79     setPlatformStrategies(&platformStrategies.get());
80 }
81
82 WebPlatformStrategies::WebPlatformStrategies()
83 {
84 }
85
86 LoaderStrategy* WebPlatformStrategies::createLoaderStrategy()
87 {
88     return &WebProcess::singleton().webLoaderStrategy();
89 }
90
91 PasteboardStrategy* WebPlatformStrategies::createPasteboardStrategy()
92 {
93     return this;
94 }
95
96 BlobRegistry* WebPlatformStrategies::createBlobRegistry()
97 {
98     return new BlobRegistryProxy;
99 }
100
101 #if PLATFORM(COCOA)
102 // PasteboardStrategy
103
104 void WebPlatformStrategies::getTypes(Vector<String>& types, const String& pasteboardName)
105 {
106     // First check the overrides.
107     // The purpose of the overrides is to avoid messaging back to the UI process.
108     // Therefore, if there are any overridden types, we return just those.
109     types = WebPasteboardOverrides::sharedPasteboardOverrides().overriddenTypes(pasteboardName);
110     if (!types.isEmpty())
111         return;
112
113     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardTypes(pasteboardName), Messages::WebPasteboardProxy::GetPasteboardTypes::Reply(types), 0);
114 }
115
116 RefPtr<WebCore::SharedBuffer> WebPlatformStrategies::bufferForType(const String& pasteboardType, const String& pasteboardName)
117 {
118     // First check the overrides.
119     Vector<char> overrideBuffer;
120     if (WebPasteboardOverrides::sharedPasteboardOverrides().getDataForOverride(pasteboardName, pasteboardType, overrideBuffer))
121         return SharedBuffer::create(WTFMove(overrideBuffer));
122
123     // Fallback to messaging the UI process for native pasteboard content.
124     SharedMemory::Handle handle;
125     uint64_t size { 0 };
126     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardBufferForType(pasteboardName, pasteboardType), Messages::WebPasteboardProxy::GetPasteboardBufferForType::Reply(handle, size), 0);
127     if (handle.isNull())
128         return nullptr;
129     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
130     return SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
131 }
132
133 void WebPlatformStrategies::getPathnamesForType(Vector<String>& pathnames, const String& pasteboardType, const String& pasteboardName)
134 {
135     SandboxExtension::HandleArray sandboxExtensionsHandleArray;
136     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardPathnamesForType(pasteboardName, pasteboardType),
137         Messages::WebPasteboardProxy::GetPasteboardPathnamesForType::Reply(pathnames, sandboxExtensionsHandleArray), 0);
138     ASSERT(pathnames.size() == sandboxExtensionsHandleArray.size());
139     for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
140         if (auto extension = SandboxExtension::create(WTFMove(sandboxExtensionsHandleArray[i])))
141             extension->consumePermanently();
142     }
143 }
144
145 String WebPlatformStrategies::stringForType(const String& pasteboardType, const String& pasteboardName)
146 {
147     String value;
148     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardStringForType(pasteboardName, pasteboardType), Messages::WebPasteboardProxy::GetPasteboardStringForType::Reply(value), 0);
149     return value;
150 }
151
152 Vector<String> WebPlatformStrategies::allStringsForType(const String& pasteboardType, const String& pasteboardName)
153 {
154     Vector<String> values;
155     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardStringsForType(pasteboardName, pasteboardType), Messages::WebPasteboardProxy::GetPasteboardStringsForType::Reply(values), 0);
156     return values;
157 }
158
159 long WebPlatformStrategies::changeCount(const WTF::String &pasteboardName)
160 {
161     uint64_t changeCount { 0 };
162     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardChangeCount(pasteboardName), Messages::WebPasteboardProxy::GetPasteboardChangeCount::Reply(changeCount), 0);
163     return changeCount;
164 }
165
166 String WebPlatformStrategies::uniqueName()
167 {
168     String pasteboardName;
169     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardUniqueName(), Messages::WebPasteboardProxy::GetPasteboardUniqueName::Reply(pasteboardName), 0);
170     return pasteboardName;
171 }
172
173 Color WebPlatformStrategies::color(const String& pasteboardName)
174 {
175     Color color;
176     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardColor(pasteboardName), Messages::WebPasteboardProxy::GetPasteboardColor::Reply(color), 0);
177     return color;
178 }
179
180 URL WebPlatformStrategies::url(const String& pasteboardName)
181 {
182     String urlString;
183     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardURL(pasteboardName), Messages::WebPasteboardProxy::GetPasteboardURL::Reply(urlString), 0);
184     return URL({ }, urlString);
185 }
186
187 long WebPlatformStrategies::addTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
188 {
189     uint64_t newChangeCount { 0 };
190     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::AddPasteboardTypes(pasteboardName, pasteboardTypes), Messages::WebPasteboardProxy::AddPasteboardTypes::Reply(newChangeCount), 0);
191     return newChangeCount;
192 }
193
194 long WebPlatformStrategies::setTypes(const Vector<String>& pasteboardTypes, const String& pasteboardName)
195 {
196     uint64_t newChangeCount { 0 };
197     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardTypes(pasteboardName, pasteboardTypes), Messages::WebPasteboardProxy::SetPasteboardTypes::Reply(newChangeCount), 0);
198     return newChangeCount;
199 }
200
201 long WebPlatformStrategies::setBufferForType(SharedBuffer* buffer, const String& pasteboardType, const String& pasteboardName)
202 {
203     SharedMemory::Handle handle;
204     if (buffer && buffer->size()) {
205         RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(buffer->size());
206         // FIXME: Null check prevents crashing, but it is not great that we will have empty pasteboard content for this type,
207         // because we've already set the types.
208         if (sharedMemoryBuffer) {
209             memcpy(sharedMemoryBuffer->data(), buffer->data(), buffer->size());
210             sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
211         }
212     }
213     uint64_t newChangeCount { 0 };
214     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardBufferForType(pasteboardName, pasteboardType, handle, buffer ? buffer->size() : 0), Messages::WebPasteboardProxy::SetPasteboardBufferForType::Reply(newChangeCount), 0);
215     return newChangeCount;
216 }
217
218 long WebPlatformStrategies::setURL(const PasteboardURL& pasteboardURL, const String& pasteboardName)
219 {
220     uint64_t newChangeCount;
221     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardURL(pasteboardURL, pasteboardName), Messages::WebPasteboardProxy::SetPasteboardURL::Reply(newChangeCount), 0);
222     return newChangeCount;
223 }
224
225 long WebPlatformStrategies::setColor(const Color& color, const String& pasteboardName)
226 {
227     uint64_t newChangeCount { 0 };
228     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardColor(pasteboardName, color), Messages::WebPasteboardProxy::SetPasteboardColor::Reply(newChangeCount), 0);
229     return newChangeCount;
230 }
231
232 long WebPlatformStrategies::setStringForType(const String& string, const String& pasteboardType, const String& pasteboardName)
233 {
234     uint64_t newChangeCount { 0 };
235     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardStringForType(pasteboardName, pasteboardType, string), Messages::WebPasteboardProxy::SetPasteboardStringForType::Reply(newChangeCount), 0);
236     return newChangeCount;
237 }
238
239 int WebPlatformStrategies::getNumberOfFiles(const String& pasteboardName)
240 {
241     uint64_t numberOfFiles { 0 };
242     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetNumberOfFiles(pasteboardName), Messages::WebPasteboardProxy::GetNumberOfFiles::Reply(numberOfFiles), 0);
243     return numberOfFiles;
244 }
245
246 #if PLATFORM(IOS_FAMILY)
247
248 void WebPlatformStrategies::writeToPasteboard(const PasteboardURL& url, const String& pasteboardName)
249 {
250     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteURLToPasteboard(url, pasteboardName), 0);
251 }
252
253 void WebPlatformStrategies::writeToPasteboard(const WebCore::PasteboardWebContent& content, const String& pasteboardName)
254 {
255     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteWebContentToPasteboard(content, pasteboardName), 0);
256 }
257
258 void WebPlatformStrategies::writeToPasteboard(const WebCore::PasteboardImage& image, const String& pasteboardName)
259 {
260     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteImageToPasteboard(image, pasteboardName), 0);
261 }
262
263 void WebPlatformStrategies::writeToPasteboard(const String& pasteboardType, const String& text, const String& pasteboardName)
264 {
265     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteStringToPasteboard(pasteboardType, text, pasteboardName), 0);
266 }
267
268 int WebPlatformStrategies::getPasteboardItemsCount(const String& pasteboardName)
269 {
270     uint64_t itemsCount { 0 };
271     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardItemsCount(pasteboardName), Messages::WebPasteboardProxy::GetPasteboardItemsCount::Reply(itemsCount), 0);
272     return itemsCount;
273 }
274
275 Vector<PasteboardItemInfo> WebPlatformStrategies::allPasteboardItemInfo(const String& pasteboardName)
276 {
277     Vector<PasteboardItemInfo> allInfo;
278     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::AllPasteboardItemInfo(pasteboardName), Messages::WebPasteboardProxy::AllPasteboardItemInfo::Reply(allInfo), 0);
279     return allInfo;
280 }
281
282 PasteboardItemInfo WebPlatformStrategies::informationForItemAtIndex(int index, const String& pasteboardName)
283 {
284     PasteboardItemInfo info;
285     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::InformationForItemAtIndex(index, pasteboardName), Messages::WebPasteboardProxy::InformationForItemAtIndex::Reply(info), 0);
286     return info;
287 }
288
289 void WebPlatformStrategies::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
290 {
291     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::UpdateSupportedTypeIdentifiers(identifiers, pasteboardName), 0);
292 }
293
294 RefPtr<WebCore::SharedBuffer> WebPlatformStrategies::readBufferFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName)
295 {
296     SharedMemory::Handle handle;
297     uint64_t size { 0 };
298     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadBufferFromPasteboard(index, pasteboardType, pasteboardName), Messages::WebPasteboardProxy::ReadBufferFromPasteboard::Reply(handle, size), 0);
299     if (handle.isNull())
300         return nullptr;
301     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
302     return SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
303 }
304
305 URL WebPlatformStrategies::readURLFromPasteboard(int index, const String& pasteboardName, String& title)
306 {
307     String urlString;
308     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadURLFromPasteboard(index, pasteboardName), Messages::WebPasteboardProxy::ReadURLFromPasteboard::Reply(urlString, title), 0);
309     return URL({ }, urlString);
310 }
311
312 String WebPlatformStrategies::readStringFromPasteboard(int index, const String& pasteboardType, const String& pasteboardName)
313 {
314     String value;
315     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadStringFromPasteboard(index, pasteboardType, pasteboardName), Messages::WebPasteboardProxy::ReadStringFromPasteboard::Reply(value), 0);
316     return value;
317 }
318 #endif // PLATFORM(IOS_FAMILY)
319
320 #endif // PLATFORM(COCOA)
321
322 #if PLATFORM(GTK)
323 // PasteboardStrategy
324
325 void WebPlatformStrategies::writeToClipboard(const String& pasteboardName, const SelectionData& selection)
326 {
327     WebSelectionData selectionData(selection);
328     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteToClipboard(pasteboardName, selectionData), 0);
329 }
330
331 Ref<SelectionData> WebPlatformStrategies::readFromClipboard(const String& pasteboardName)
332 {
333     WebSelectionData selection;
334     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadFromClipboard(pasteboardName), Messages::WebPasteboardProxy::ReadFromClipboard::Reply(selection), 0);
335     return WTFMove(selection.selectionData);
336 }
337
338 #endif // PLATFORM(GTK)
339
340 #if USE(LIBWPE)
341 // PasteboardStrategy
342
343 void WebPlatformStrategies::getTypes(Vector<String>& types)
344 {
345     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::GetPasteboardTypes(), Messages::WebPasteboardProxy::GetPasteboardTypes::Reply(types), 0);
346 }
347
348 String WebPlatformStrategies::readStringFromPasteboard(int index, const String& pasteboardType)
349 {
350     String value;
351     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::ReadStringFromPasteboard(index, pasteboardType), Messages::WebPasteboardProxy::ReadStringFromPasteboard::Reply(value), 0);
352     return value;
353 }
354
355 void WebPlatformStrategies::writeToPasteboard(const WebCore::PasteboardWebContent& content)
356 {
357     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteWebContentToPasteboard(content), 0);
358 }
359
360 void WebPlatformStrategies::writeToPasteboard(const String& pasteboardType, const String& text)
361 {
362     WebProcess::singleton().parentProcessConnection()->send(Messages::WebPasteboardProxy::WriteStringToPasteboard(pasteboardType, text), 0);
363 }
364
365 #endif // USE(LIBWPE)
366
367 Vector<String> WebPlatformStrategies::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin)
368 {
369     Vector<String> types;
370     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite(pasteboardName, origin), Messages::WebPasteboardProxy::TypesSafeForDOMToReadAndWrite::Reply(types), 0);
371     return types;
372 }
373
374 long WebPlatformStrategies::writeCustomData(const WebCore::PasteboardCustomData& data, const String& pasteboardName)
375 {
376     uint64_t newChangeCount { 0 };
377     WebProcess::singleton().parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::WriteCustomData(data, pasteboardName), Messages::WebPasteboardProxy::WriteCustomData::Reply(newChangeCount), 0);
378     return newChangeCount;
379 }
380
381 } // namespace WebKit