[WK2] Pass ranges over IPC in a cross-platform manner
[WebKit-https.git] / Source / WebKit2 / UIProcess / ios / WebPageProxyIOS.mm
1 /*
2  * Copyright (C) 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 #import "config.h"
27 #import "WebPageProxy.h"
28
29 #if PLATFORM(IOS)
30
31 #import "DataReference.h"
32 #import "EditingRange.h"
33 #import "NativeWebKeyboardEvent.h"
34 #import "PageClient.h"
35 #import "RemoteLayerTreeTransaction.h"
36 #import "ViewUpdateDispatcherMessages.h"
37 #import "WKBrowsingContextControllerInternal.h"
38 #import "WebKitSystemInterfaceIOS.h"
39 #import "WebPageMessages.h"
40 #import "WebProcessProxy.h"
41 #import "WebVideoFullscreenManagerProxy.h"
42 #import <WebCore/NotImplemented.h>
43 #import <WebCore/SharedBuffer.h>
44 #import <WebCore/UserAgent.h>
45
46 using namespace WebCore;
47
48 namespace WebKit {
49
50 void WebPageProxy::platformInitialize()
51 {
52 }
53
54 static String userVisibleWebKitVersionString()
55 {
56     // If the version is longer than 3 digits then the leading digits represent the version of the OS. Our user agent
57     // string should not include the leading digits, so strip them off and report the rest as the version. <rdar://problem/4997547>
58     NSString *fullVersion = [[NSBundle bundleForClass:NSClassFromString(@"WKView")] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
59     NSRange nonDigitRange = [fullVersion rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
60     if (nonDigitRange.location == NSNotFound && fullVersion.length > 3)
61         return [fullVersion substringFromIndex:fullVersion.length - 3];
62     if (nonDigitRange.location != NSNotFound && nonDigitRange.location > 3)
63         return [fullVersion substringFromIndex:nonDigitRange.location - 3];
64     return fullVersion;
65 }
66
67 String WebPageProxy::standardUserAgent(const String& applicationName)
68 {
69     return standardUserAgentWithApplicationName(applicationName, userVisibleWebKitVersionString());
70 }
71
72 void WebPageProxy::getIsSpeaking(bool&)
73 {
74     notImplemented();
75 }
76
77 void WebPageProxy::speak(const String&)
78 {
79     notImplemented();
80 }
81
82 void WebPageProxy::stopSpeaking()
83 {
84     notImplemented();
85 }
86
87 void WebPageProxy::searchWithSpotlight(const String&)
88 {
89     notImplemented();
90 }
91
92 void WebPageProxy::searchTheWeb(const String&)
93 {
94     notImplemented();
95 }
96
97 void WebPageProxy::windowAndViewFramesChanged(const FloatRect&, const FloatPoint&)
98 {
99     notImplemented();
100 }
101
102 void WebPageProxy::setComposition(const String& text, Vector<CompositionUnderline> underline, const EditingRange& selectionRange, const EditingRange&)
103 {
104     if (!isValid())
105         return;
106
107     process().send(Messages::WebPage::SetComposition(text, underline, selectionRange), m_pageID);
108 }
109
110 void WebPageProxy::confirmComposition()
111 {
112     if (!isValid())
113         return;
114
115     process().send(Messages::WebPage::ConfirmComposition(), m_pageID);
116 }
117
118 void WebPageProxy::cancelComposition()
119 {
120     notImplemented();
121
122 }
123
124 bool WebPageProxy::insertText(const String& text, const EditingRange& replacementRange)
125 {
126     if (!isValid())
127         return true;
128     
129     process().send(Messages::WebPage::InsertText(text, replacementRange), m_pageID);
130     return true;
131 }
132
133 bool WebPageProxy::insertDictatedText(const String&, const EditingRange&, const Vector<WebCore::TextAlternativeWithRange>&)
134 {
135     notImplemented();
136     return false;
137 }
138
139 void WebPageProxy::getMarkedRange(EditingRange&)
140 {
141     notImplemented();
142 }
143
144 void WebPageProxy::getSelectedRange(EditingRange&)
145 {
146     notImplemented();
147 }
148
149 void WebPageProxy::getAttributedSubstringFromRange(const EditingRange&, AttributedString&)
150 {
151     notImplemented();
152 }
153
154 uint64_t WebPageProxy::characterIndexForPoint(const IntPoint)
155 {
156     notImplemented();
157     return 0;
158 }
159
160 IntRect WebPageProxy::firstRectForCharacterRange(const EditingRange&)
161 {
162     notImplemented();
163     return IntRect();
164 }
165
166 bool WebPageProxy::executeKeypressCommands(const Vector<WebCore::KeypressCommand>&)
167 {
168     notImplemented();
169     return false;
170 }
171
172 String WebPageProxy::stringSelectionForPasteboard()
173 {
174     notImplemented();
175     return String();
176 }
177
178 PassRefPtr<WebCore::SharedBuffer> WebPageProxy::dataSelectionForPasteboard(const String&)
179 {
180     notImplemented();
181     return 0;
182 }
183
184 bool WebPageProxy::readSelectionFromPasteboard(const String&)
185 {
186     notImplemented();
187     return false;
188 }
189
190 void WebPageProxy::performDictionaryLookupAtLocation(const WebCore::FloatPoint&)
191 {
192     notImplemented();
193 }
194
195 void WebPageProxy::gestureCallback(const WebCore::IntPoint& point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, uint64_t callbackID)
196 {
197     RefPtr<GestureCallback> callback = m_gestureCallbacks.take(callbackID);
198     if (!callback) {
199         ASSERT_NOT_REACHED();
200         return;
201     }
202     
203     callback->performCallbackWithReturnValue(point, gestureType, gestureState, flags);
204 }
205
206 void WebPageProxy::touchesCallback(const WebCore::IntPoint& point, uint32_t touches, uint64_t callbackID)
207 {
208     RefPtr<TouchesCallback> callback = m_touchesCallbacks.take(callbackID);
209     if (!callback) {
210         ASSERT_NOT_REACHED();
211         return;
212     }
213
214     callback->performCallbackWithReturnValue(point, touches);
215 }
216
217 void WebPageProxy::autocorrectionDataCallback(const Vector<WebCore::FloatRect>& rects, const String& fontName, float fontSize, uint64_t fontTraits, uint64_t callbackID)
218 {
219     RefPtr<AutocorrectionDataCallback> callback = m_autocorrectionCallbacks.take(callbackID);
220     if (!callback) {
221         ASSERT_NOT_REACHED();
222         return;
223     }
224
225     callback->performCallbackWithReturnValue(rects, fontName, fontSize, fontTraits);
226 }
227
228 void WebPageProxy::autocorrectionContextCallback(const String& beforeText, const String& markedText, const String& selectedText, const String& afterText, uint64_t location, uint64_t length, uint64_t callbackID)
229 {
230     RefPtr<AutocorrectionContextCallback> callback = m_autocorrectionContextCallbacks.take(callbackID);
231     if (!callback) {
232         ASSERT_NOT_REACHED();
233         return;
234     }
235
236     callback->performCallbackWithReturnValue(beforeText, markedText, selectedText, afterText, location, length);
237 }
238
239 bool WebPageProxy::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdateInfo)
240 {
241     if (visibleContentRectUpdateInfo == m_lastVisibleContentRectUpdate)
242         return false;
243
244     m_lastVisibleContentRectUpdate = visibleContentRectUpdateInfo;
245     m_process->send(Messages::ViewUpdateDispatcher::VisibleContentRectUpdate(m_pageID, visibleContentRectUpdateInfo), 0);
246     return true;
247 }
248
249 void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize& size)
250 {
251     m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
252 }
253
254 void WebPageProxy::didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
255 {
256     m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
257
258     m_pageClient.didCommitLayerTree(layerTreeTransaction);
259 }
260
261 void WebPageProxy::selectWithGesture(const WebCore::IntPoint point, WebCore::TextGranularity granularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback> callback)
262 {
263     if (!isValid()) {
264         callback->invalidate();
265         return;
266     }
267     
268     uint64_t callbackID = callback->callbackID();
269     m_gestureCallbacks.set(callbackID, callback);
270     m_process->send(Messages::WebPage::SelectWithGesture(point, (uint32_t)granularity, gestureType, gestureState, callbackID), m_pageID);
271 }
272
273 void WebPageProxy::updateSelectionWithTouches(const WebCore::IntPoint point, uint32_t touches, bool baseIsStart, PassRefPtr<TouchesCallback> callback)
274 {
275     if (!isValid()) {
276         callback->invalidate();
277         return;
278     }
279
280     uint64_t callbackID = callback->callbackID();
281     m_touchesCallbacks.set(callbackID, callback);
282     m_process->send(Messages::WebPage::UpdateSelectionWithTouches(point, touches, baseIsStart, callbackID), m_pageID);
283 }
284
285 void WebPageProxy::requestAutocorrectionData(const String& textForAutocorrection, PassRefPtr<AutocorrectionDataCallback> callback)
286 {
287     if (!isValid()) {
288         callback->invalidate();
289         return;
290     }
291
292     uint64_t callbackID = callback->callbackID();
293     m_autocorrectionCallbacks.set(callbackID, callback);
294     m_process->send(Messages::WebPage::RequestAutocorrectionData(textForAutocorrection, callbackID), m_pageID);
295 }
296
297 void WebPageProxy::applyAutocorrection(const String& correction, const String& originalText, PassRefPtr<StringCallback> callback)
298 {
299     if (!isValid()) {
300         callback->invalidate();
301         return;
302     }
303
304     uint64_t callbackID = callback->callbackID();
305     m_stringCallbacks.set(callbackID, callback);
306     m_process->send(Messages::WebPage::ApplyAutocorrection(correction, originalText, callbackID), m_pageID);
307 }
308
309 bool WebPageProxy::applyAutocorrection(const String& correction, const String& originalText)
310 {
311     bool autocorrectionApplied = false;
312     m_process->sendSync(Messages::WebPage::SyncApplyAutocorrection(correction, originalText), Messages::WebPage::SyncApplyAutocorrection::Reply(autocorrectionApplied), m_pageID);
313     return autocorrectionApplied;
314 }
315
316 void WebPageProxy::requestAutocorrectionContext(PassRefPtr<AutocorrectionContextCallback> callback)
317 {
318     if (!isValid()) {
319         callback->invalidate();
320         return;
321     }
322
323     uint64_t callbackID = callback->callbackID();
324     m_autocorrectionContextCallbacks.set(callbackID, callback);
325     m_process->send(Messages::WebPage::RequestAutocorrectionContext(callbackID), m_pageID);
326 }
327
328 void WebPageProxy::getAutocorrectionContext(String& beforeContext, String& markedText, String& selectedText, String& afterContext, uint64_t& location, uint64_t& length)
329 {
330     m_process->sendSync(Messages::WebPage::GetAutocorrectionContext(), Messages::WebPage::GetAutocorrectionContext::Reply(beforeContext, markedText, selectedText, afterContext, location, length), m_pageID);
331 }
332
333 void WebPageProxy::selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback> callback)
334 {
335     if (!isValid()) {
336         callback->invalidate();
337         return;
338     }
339
340     uint64_t callbackID = callback->callbackID();
341     m_gestureCallbacks.set(callbackID, callback);
342     m_process->send(Messages::WebPage::SelectWithTwoTouches(from, to, gestureType, gestureState, callbackID), m_pageID);
343 }
344
345 void WebPageProxy::updateBlockSelectionWithTouch(const WebCore::IntPoint point, uint32_t touch, uint32_t handlePosition)
346 {
347     m_process->send(Messages::WebPage::UpdateBlockSelectionWithTouch(point, touch, handlePosition), m_pageID);
348 }
349
350 void WebPageProxy::didReceivePositionInformation(const InteractionInformationAtPosition& info)
351 {
352     m_pageClient.positionInformationDidChange(info);
353 }
354
355 void WebPageProxy::getPositionInformation(const WebCore::IntPoint& point, InteractionInformationAtPosition& info)
356 {
357     m_process->sendSync(Messages::WebPage::GetPositionInformation(point), Messages::WebPage::GetPositionInformation::Reply(info), m_pageID);
358 }
359
360 void WebPageProxy::requestPositionInformation(const WebCore::IntPoint& point)
361 {
362     m_process->send(Messages::WebPage::RequestPositionInformation(point), m_pageID);
363 }
364
365 void WebPageProxy::startInteractionWithElementAtPosition(const WebCore::IntPoint& point)
366 {
367     m_process->send(Messages::WebPage::StartInteractionWithElementAtPosition(point), m_pageID);
368 }
369
370 void WebPageProxy::stopInteraction()
371 {
372     m_process->send(Messages::WebPage::StopInteraction(), m_pageID);
373 }
374
375 void WebPageProxy::performActionOnElement(uint32_t action)
376 {
377     m_process->send(Messages::WebPage::PerformActionOnElement(action), m_pageID);
378 }
379
380 void WebPageProxy::saveImageToLibrary(const SharedMemory::Handle& imageHandle, uint64_t imageSize)
381 {
382     RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(imageHandle, SharedMemory::ReadOnly);
383     RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), imageSize);
384     m_pageClient.saveImageToLibrary(buffer);
385 }
386
387 void WebPageProxy::didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold)
388 {
389     m_pageClient.didUpdateBlockSelectionWithTouch(touch, flags, growThreshold, shrinkThreshold);
390 }
391
392 void WebPageProxy::applicationWillEnterForeground()
393 {
394     m_process->send(Messages::WebPage::ApplicationWillEnterForeground(), m_pageID);
395 }
396
397 void WebPageProxy::applicationWillResignActive()
398 {
399     m_process->send(Messages::WebPage::ApplicationWillResignActive(), m_pageID);
400 }
401
402 void WebPageProxy::applicationDidBecomeActive()
403 {
404     m_process->send(Messages::WebPage::ApplicationDidBecomeActive(), m_pageID);
405 }
406
407 void WebPageProxy::notifyRevealedSelection()
408 {
409     m_pageClient.selectionDidChange();
410 }
411
412 void WebPageProxy::extendSelection(WebCore::TextGranularity granularity)
413 {
414     m_process->send(Messages::WebPage::ExtendSelection(static_cast<uint32_t>(granularity)), m_pageID);
415 }
416
417 void WebPageProxy::interpretKeyEvent(const EditorState& state, bool isCharEvent, bool& handled)
418 {
419     m_editorState = state;
420     handled = m_pageClient.interpretKeyEvent(m_keyEventQueue.first(), isCharEvent);
421 }
422
423 // Complex text input support for plug-ins.
424 void WebPageProxy::sendComplexTextInputToPlugin(uint64_t, const String&)
425 {
426     notImplemented();
427 }
428
429 void WebPageProxy::setSmartInsertDeleteEnabled(bool)
430 {
431     notImplemented();
432 }
433
434 void WebPageProxy::registerWebProcessAccessibilityToken(const IPC::DataReference& data)
435 {
436     m_pageClient.accessibilityWebProcessTokenReceived(data);
437 }    
438
439 void WebPageProxy::makeFirstResponder()
440 {
441     notImplemented();
442 }
443
444 void WebPageProxy::registerUIProcessAccessibilityTokens(const IPC::DataReference& elementToken, const IPC::DataReference& windowToken)
445 {
446     if (!isValid())
447         return;
448     
449     process().send(Messages::WebPage::RegisterUIProcessAccessibilityTokens(elementToken, windowToken), m_pageID);
450 }
451
452 void WebPageProxy::pluginFocusOrWindowFocusChanged(uint64_t, bool)
453 {
454     notImplemented();
455 }
456
457 void WebPageProxy::setPluginComplexTextInputState(uint64_t, uint64_t)
458 {
459     notImplemented();
460 }
461
462 void WebPageProxy::executeSavedCommandBySelector(const String&, bool&)
463 {
464     notImplemented();
465 }
466
467 bool WebPageProxy::shouldDelayWindowOrderingForEvent(const WebKit::WebMouseEvent&)
468 {
469     notImplemented();
470     return false;
471 }
472
473 bool WebPageProxy::acceptsFirstMouse(int, const WebKit::WebMouseEvent&)
474 {
475     notImplemented();
476     return false;
477 }
478
479 void WebPageProxy::willStartUserTriggeredZooming()
480 {
481     process().send(Messages::WebPage::WillStartUserTriggeredZooming(), m_pageID);
482 }
483
484 void WebPageProxy::tapHighlightAtPosition(const WebCore::FloatPoint& position, uint64_t& requestID)
485 {
486     static uint64_t uniqueRequestID = 0;
487     requestID = ++uniqueRequestID;
488
489     process().send(Messages::WebPage::TapHighlightAtPosition(requestID, position), m_pageID);
490 }
491
492 void WebPageProxy::blurAssistedNode()
493 {
494     process().send(Messages::WebPage::BlurAssistedNode(), m_pageID);
495 }
496
497 FloatSize WebPageProxy::viewportScreenSize()
498 {
499     return FloatSize(WKGetViewportScreenSize());
500 }
501
502 void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius)
503 {
504     m_pageClient.didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
505 }
506
507 void WebPageProxy::startAssistingNode(const AssistedNodeInformation& information)
508 {
509     m_pageClient.startAssistingNode(information);
510 }
511
512 void WebPageProxy::stopAssistingNode()
513 {
514     m_pageClient.stopAssistingNode();
515 }
516
517 void WebPageProxy::focusNextAssistedNode(bool isForward)
518 {
519     process().send(Messages::WebPage::FocusNextAssistedNode(isForward), m_pageID);
520 }
521
522 void WebPageProxy::setAssistedNodeValue(const String& value)
523 {
524     process().send(Messages::WebPage::SetAssistedNodeValue(value), m_pageID);
525 }
526
527 void WebPageProxy::setAssistedNodeValueAsNumber(double value)
528 {
529     process().send(Messages::WebPage::SetAssistedNodeValueAsNumber(value), m_pageID);
530 }
531
532 void WebPageProxy::setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection)
533 {
534     process().send(Messages::WebPage::SetAssistedNodeSelectedIndex(index, allowMultipleSelection), m_pageID);
535 }
536
537 void WebPageProxy::didPerformDictionaryLookup(const AttributedString&, const DictionaryPopupInfo&)
538 {
539     notImplemented();
540 }
541
542 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String&, const String&, const IPC::DataReference&, const String&)
543 {
544     notImplemented();
545 }
546
547 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplicationRaw(const String&, const String&, const uint8_t*, unsigned long, const String&)
548 {
549     notImplemented();
550 }
551
552 void WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication(const String&)
553 {
554     notImplemented();
555 }
556
557 void WebPageProxy::setAcceleratedCompositingRootLayer(LayerOrView* rootLayer)
558 {
559     m_pageClient.setAcceleratedCompositingRootLayer(rootLayer);
560 }
561
562 } // namespace WebKit
563
564 #endif // PLATFORM(IOS)