[Clipboard API] Refactor Pasteboard item reading functions to work on both iOS and...
[WebKit.git] / Source / WebKit / UIProcess / Cocoa / WebPasteboardProxyCocoa.mm
1 /*
2  * Copyright (C) 2014 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 #import "config.h"
27 #import "WebPasteboardProxy.h"
28
29 #import "SandboxExtension.h"
30 #import "WebProcessProxy.h"
31 #import <WebCore/Color.h>
32 #import <WebCore/Pasteboard.h>
33 #import <WebCore/PasteboardItemInfo.h>
34 #import <WebCore/PlatformPasteboard.h>
35 #import <WebCore/SharedBuffer.h>
36 #import <wtf/URL.h>
37
38 namespace WebKit {
39 using namespace WebCore;
40
41 void WebPasteboardProxy::getPasteboardTypes(const String& pasteboardName, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
42 {
43     Vector<String> pasteboardTypes;
44     PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes);
45     completionHandler(WTFMove(pasteboardTypes));
46 }
47
48 void WebPasteboardProxy::getPasteboardPathnamesForType(IPC::Connection& connection, const String& pasteboardName, const String& pasteboardType,
49     CompletionHandler<void(Vector<String>&& pathnames, SandboxExtension::HandleArray&& sandboxExtensions)>&& completionHandler)
50 {
51     Vector<String> pathnames;
52     SandboxExtension::HandleArray sandboxExtensions;
53     for (auto* webProcessProxy : m_webProcessProxyList) {
54         if (!webProcessProxy->hasConnection(connection))
55             continue;
56
57         PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType);
58
59 #if PLATFORM(MAC)
60         // On iOS, files are copied into app's container upon paste.
61         sandboxExtensions.allocate(pathnames.size());
62         for (size_t i = 0; i < pathnames.size(); i++) {
63             auto& filename = pathnames[i];
64             if (![[NSFileManager defaultManager] fileExistsAtPath:filename])
65                 continue;
66             SandboxExtension::createHandle(filename, SandboxExtension::Type::ReadOnly, sandboxExtensions[i]);
67         }
68 #endif
69     }
70     completionHandler(WTFMove(pathnames), WTFMove(sandboxExtensions));
71 }
72
73 void WebPasteboardProxy::getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(String&&)>&& completionHandler)
74 {
75     completionHandler(PlatformPasteboard(pasteboardName).stringForType(pasteboardType));
76 }
77
78 void WebPasteboardProxy::getPasteboardStringsForType(const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
79 {
80     completionHandler(PlatformPasteboard(pasteboardName).allStringsForType(pasteboardType));
81 }
82
83 void WebPasteboardProxy::getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, CompletionHandler<void(SharedMemory::Handle&&, uint64_t)>&& completionHandler)
84 {
85     RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).bufferForType(pasteboardType);
86     if (!buffer)
87         return completionHandler({ }, 0);
88     uint64_t size = buffer->size();
89     if (!size)
90         return completionHandler({ }, 0);
91     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(size);
92     if (!sharedMemoryBuffer)
93         return completionHandler({ }, 0);
94     memcpy(sharedMemoryBuffer->data(), buffer->data(), size);
95     SharedMemory::Handle handle;
96     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
97     completionHandler(WTFMove(handle), size);
98 }
99
100 void WebPasteboardProxy::pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, CompletionHandler<void(uint64_t)>&& completionHandler)
101 {
102     completionHandler(PlatformPasteboard(toPasteboard).copy(fromPasteboard));
103 }
104
105 void WebPasteboardProxy::getPasteboardChangeCount(const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
106 {
107     completionHandler(PlatformPasteboard(pasteboardName).changeCount());
108 }
109
110 void WebPasteboardProxy::getPasteboardUniqueName(CompletionHandler<void(String&&)>&& completionHandler)
111 {
112     completionHandler(PlatformPasteboard::uniqueName());
113 }
114
115 void WebPasteboardProxy::getPasteboardColor(const String& pasteboardName, CompletionHandler<void(WebCore::Color&&)>&& completionHandler)
116 {
117     completionHandler(PlatformPasteboard(pasteboardName).color());
118 }
119
120 void WebPasteboardProxy::getPasteboardURL(const String& pasteboardName, CompletionHandler<void(const String&)>&& completionHandler)
121 {
122     completionHandler(PlatformPasteboard(pasteboardName).url().string());
123 }
124
125 void WebPasteboardProxy::addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, CompletionHandler<void(uint64_t)>&& completionHandler)
126 {
127     completionHandler(PlatformPasteboard(pasteboardName).addTypes(pasteboardTypes));
128 }
129
130 void WebPasteboardProxy::setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, CompletionHandler<void(uint64_t)>&& completionHandler)
131 {
132     completionHandler(PlatformPasteboard(pasteboardName).setTypes(pasteboardTypes));
133 }
134
135 void WebPasteboardProxy::setPasteboardURL(IPC::Connection& connection, const PasteboardURL& pasteboardURL, const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
136 {
137     for (auto* webProcessProxy : m_webProcessProxyList) {
138         if (!webProcessProxy->hasConnection(connection))
139             continue;
140
141         if (!webProcessProxy->checkURLReceivedFromWebProcess(pasteboardURL.url.string()))
142             return completionHandler(0);
143
144         return completionHandler(PlatformPasteboard(pasteboardName).setURL(pasteboardURL));
145     }
146     completionHandler(0);
147 }
148
149 void WebPasteboardProxy::setPasteboardColor(const String& pasteboardName, const WebCore::Color& color, CompletionHandler<void(uint64_t)>&& completionHandler)
150 {
151     completionHandler(PlatformPasteboard(pasteboardName).setColor(color));
152 }
153
154 void WebPasteboardProxy::setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String& string, CompletionHandler<void(uint64_t)>&& completionHandler)
155 {
156     completionHandler(PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType));
157 }
158
159 void WebPasteboardProxy::setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle& handle, uint64_t size, CompletionHandler<void(uint64_t)>&& completionHandler)
160 {
161     if (handle.isNull())
162         return completionHandler(PlatformPasteboard(pasteboardName).setBufferForType(0, pasteboardType));
163     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::map(handle, SharedMemory::Protection::ReadOnly);
164     auto buffer = SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
165     completionHandler(PlatformPasteboard(pasteboardName).setBufferForType(buffer.ptr(), pasteboardType));
166 }
167
168 void WebPasteboardProxy::getNumberOfFiles(const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
169 {
170     completionHandler(PlatformPasteboard(pasteboardName).numberOfFiles());
171 }
172
173 void WebPasteboardProxy::typesSafeForDOMToReadAndWrite(const String& pasteboardName, const String& origin, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
174 {
175     completionHandler(PlatformPasteboard(pasteboardName).typesSafeForDOMToReadAndWrite(origin));
176 }
177
178 void WebPasteboardProxy::writeCustomData(const WebCore::PasteboardCustomData& data, const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
179 {
180     completionHandler(PlatformPasteboard(pasteboardName).write(data));
181 }
182
183 void WebPasteboardProxy::allPasteboardItemInfo(const String& pasteboardName, CompletionHandler<void(Vector<PasteboardItemInfo>&&)>&& completionHandler)
184 {
185     completionHandler(PlatformPasteboard(pasteboardName).allPasteboardItemInfo());
186 }
187
188 void WebPasteboardProxy::informationForItemAtIndex(size_t index, const String& pasteboardName, CompletionHandler<void(PasteboardItemInfo&&)>&& completionHandler)
189 {
190     completionHandler(PlatformPasteboard(pasteboardName).informationForItemAtIndex(index));
191 }
192
193 void WebPasteboardProxy::getPasteboardItemsCount(const String& pasteboardName, CompletionHandler<void(uint64_t)>&& completionHandler)
194 {
195     completionHandler(PlatformPasteboard(pasteboardName).count());
196 }
197
198 void WebPasteboardProxy::readStringFromPasteboard(size_t index, const String& pasteboardType, const String& pasteboardName, CompletionHandler<void(String&&)>&& completionHandler)
199 {
200     completionHandler(PlatformPasteboard(pasteboardName).readString(index, pasteboardType));
201 }
202
203 void WebPasteboardProxy::readURLFromPasteboard(size_t index, const String& pasteboardName, CompletionHandler<void(String&& url, String&& title)>&& completionHandler)
204 {
205     String title;
206     String url = PlatformPasteboard(pasteboardName).readURL(index, title);
207     completionHandler(WTFMove(url), WTFMove(title));
208 }
209
210 void WebPasteboardProxy::readBufferFromPasteboard(size_t index, const String& pasteboardType, const String& pasteboardName, CompletionHandler<void(SharedMemory::Handle&&, uint64_t size)>&& completionHandler)
211 {
212     RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).readBuffer(index, pasteboardType);
213     if (!buffer)
214         return completionHandler({ }, 0);
215     uint64_t size = buffer->size();
216     if (!size)
217         return completionHandler({ }, 0);
218     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(size);
219     if (!sharedMemoryBuffer)
220         return completionHandler({ }, 0);
221     memcpy(sharedMemoryBuffer->data(), buffer->data(), size);
222     SharedMemory::Handle handle;
223     sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
224     completionHandler(WTFMove(handle), size);
225 }
226
227 #if PLATFORM(IOS_FAMILY)
228
229 void WebPasteboardProxy::writeURLToPasteboard(const PasteboardURL& url, const String& pasteboardName)
230 {
231     PlatformPasteboard(pasteboardName).write(url);
232 }
233
234 void WebPasteboardProxy::writeWebContentToPasteboard(const WebCore::PasteboardWebContent& content, const String& pasteboardName)
235 {
236     PlatformPasteboard(pasteboardName).write(content);
237 }
238
239 void WebPasteboardProxy::writeImageToPasteboard(const WebCore::PasteboardImage& pasteboardImage, const String& pasteboardName)
240 {
241     PlatformPasteboard(pasteboardName).write(pasteboardImage);
242 }
243
244 void WebPasteboardProxy::writeStringToPasteboard(const String& pasteboardType, const String& text, const String& pasteboardName)
245 {
246     PlatformPasteboard(pasteboardName).write(pasteboardType, text);
247 }
248
249 void WebPasteboardProxy::updateSupportedTypeIdentifiers(const Vector<String>& identifiers, const String& pasteboardName)
250 {
251     PlatformPasteboard(pasteboardName).updateSupportedTypeIdentifiers(identifiers);
252 }
253
254 #endif // PLATFORM(IOS_FAMILY)
255
256 } // namespace WebKit