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