diff options
| author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
|---|---|---|
| committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
| commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
| tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebKit2/UIProcess | |
| parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
| download | WebKitGtk-tarball-master.tar.gz | |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebKit2/UIProcess')
683 files changed, 50318 insertions, 16965 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h b/Source/WebKit2/UIProcess/API/APIAutomationClient.h index 0333335ba..299581095 100644 --- a/Source/WebKit2/UIProcess/API/C/soup/WKAPICastSoup.h +++ b/Source/WebKit2/UIProcess/API/APIAutomationClient.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (c) 2012 Igalia S.L. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,24 +23,25 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKAPICastSoup_h -#define WKAPICastSoup_h +#ifndef APIAutomationClient_h +#define APIAutomationClient_h -#ifndef WKAPICast_h -#error "Please #include \"WKAPICast.h\" instead of this file directly." -#endif +#include <wtf/Forward.h> namespace WebKit { +class WebProcessPool; +} -class WebSoupCustomProtocolRequestManager; -class WebSoupRequestManagerProxy; +namespace API { -#if ENABLE(CUSTOM_PROTOCOLS) -WK_ADD_API_MAPPING(WKSoupCustomProtocolRequestManagerRef, WebSoupCustomProtocolRequestManager) -#else -WK_ADD_API_MAPPING(WKSoupRequestManagerRef, WebSoupRequestManagerProxy) -#endif +class AutomationClient { +public: + virtual ~AutomationClient() { } -} + virtual bool allowsRemoteAutomation(WebKit::WebProcessPool*) { return false; } + virtual void didRequestAutomationSession(WebKit::WebProcessPool*, const WTF::String&) { } +}; + +} // namespace API -#endif // WKAPICastSoup_h +#endif // APIAutomationClient_h diff --git a/Source/WebKit2/UIProcess/API/APIAutomationSessionClient.h b/Source/WebKit2/UIProcess/API/APIAutomationSessionClient.h new file mode 100644 index 000000000..f6c92734c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIAutomationSessionClient.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIAutomationSessionClient_h +#define APIAutomationSessionClient_h + +#include <wtf/text/WTFString.h> + +namespace WebKit { +class WebAutomationSession; +class WebPageProxy; +} + +namespace API { + +class AutomationSessionClient { +public: + virtual ~AutomationSessionClient() { } + + virtual String sessionIdentifier() const { return String(); } + virtual void didDisconnectFromRemote(WebKit::WebAutomationSession*) { } + virtual WebKit::WebPageProxy* didRequestNewWindow(WebKit::WebAutomationSession*) { return nullptr; } + virtual bool isShowingJavaScriptDialogOnPage(WebKit::WebAutomationSession*, WebKit::WebPageProxy*) { return false; } + virtual void dismissCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession*, WebKit::WebPageProxy*) { } + virtual void acceptCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession*, WebKit::WebPageProxy*) { } + virtual String messageOfCurrentJavaScriptDialogOnPage(WebKit::WebAutomationSession*, WebKit::WebPageProxy*) { return String(); } + virtual void setUserInputForCurrentJavaScriptPromptOnPage(WebKit::WebAutomationSession*, WebKit::WebPageProxy*, const String&) { } +}; + +} // namespace API + +#endif // APIAutomationSessionClient_h diff --git a/Source/WebKit2/UIProcess/API/APIContextMenuClient.h b/Source/WebKit2/UIProcess/API/APIContextMenuClient.h new file mode 100644 index 000000000..8b2d244c2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIContextMenuClient.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIContextMenuClient_h +#define APIContextMenuClient_h + +#if ENABLE(CONTEXT_MENUS) + +#include "WebContextMenuListenerProxy.h" +#include "WebHitTestResultData.h" +#include <WebKit/WKBase.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> + +OBJC_CLASS NSMenu; + +namespace WebCore { +class IntPoint; +} + +namespace WebKit { +class WebContextMenuItem; +class WebContextMenuItemData; +class WebPageProxy; +} + +namespace API { + +class ContextMenuClient { +public: + virtual ~ContextMenuClient() { } + + virtual bool getContextMenuFromProposedMenu(WebKit::WebPageProxy&, const Vector<RefPtr<WebKit::WebContextMenuItem>>& /* proposedMenu */, Vector<RefPtr<WebKit::WebContextMenuItem>>& /* customMenu */, const WebKit::WebHitTestResultData&, API::Object* /* userData */) { return false; } + virtual bool getContextMenuFromProposedMenuAsync(WebKit::WebPageProxy&, const Vector<RefPtr<WebKit::WebContextMenuItem>>& /* proposedMenu */, WebKit::WebContextMenuListenerProxy*, const WebKit::WebHitTestResultData&, API::Object* /* userData */) { return false; } + virtual void customContextMenuItemSelected(WebKit::WebPageProxy&, const WebKit::WebContextMenuItemData&) { } + virtual bool showContextMenu(WebKit::WebPageProxy&, const WebCore::IntPoint&, const Vector<RefPtr<WebKit::WebContextMenuItem>>&) { return false; } + virtual bool hideContextMenu(WebKit::WebPageProxy&) { return false; } + +#if PLATFORM(MAC) + virtual RetainPtr<NSMenu> menuFromProposedMenu(WebKit::WebPageProxy&, NSMenu *menu, const WebKit::WebHitTestResultData&, API::Object*) { return menu; } +#endif +}; + +} // namespace API + +#endif // ENABLE(CONTEXT_MENUS) +#endif // APIContextMenuClient_h diff --git a/Source/WebKit2/UIProcess/WebBatteryProvider.h b/Source/WebKit2/UIProcess/API/APICustomProtocolManagerClient.h index a1dba015e..945de3fca 100644 --- a/Source/WebKit2/UIProcess/WebBatteryProvider.h +++ b/Source/WebKit2/UIProcess/API/APICustomProtocolManagerClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,33 +23,28 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebBatteryProvider_h -#define WebBatteryProvider_h +#pragma once -#if ENABLE(BATTERY_STATUS) - -#include "APIClient.h" -#include "WKBatteryManager.h" #include <wtf/Forward.h> -namespace API { -template<> struct ClientTraits<WKBatteryProviderBase> { - typedef std::tuple<WKBatteryProviderV0> Versions; -}; +namespace WebKit { +class CustomProtocolManagerProxy; } -namespace WebKit { +namespace WebCore { +class ResourceRequest; +} -class WebBatteryManagerProxy; +namespace API { -class WebBatteryProvider : public API::Client<WKBatteryProviderBase> { +class CustomProtocolManagerClient { public: - void startUpdating(WebBatteryManagerProxy*); - void stopUpdating(WebBatteryManagerProxy*); -}; + virtual ~CustomProtocolManagerClient() { } -} // namespace WebKit + virtual void startLoading(WebKit::CustomProtocolManagerProxy&, uint64_t /* customProtocolID */, const WebCore::ResourceRequest&) { } + virtual void stopLoading(WebKit::CustomProtocolManagerProxy&, uint64_t /* customProtocolID */) { } -#endif // ENABLE(BATTERY_STATUS) + virtual void invalidate(WebKit::CustomProtocolManagerProxy&) { } +}; -#endif // WebBatteryProvider_h +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIDiagnosticLoggingClient.h b/Source/WebKit2/UIProcess/API/APIDiagnosticLoggingClient.h new file mode 100644 index 000000000..e99e747ff --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIDiagnosticLoggingClient.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIDiagnosticLoggingClient_h +#define APIDiagnosticLoggingClient_h + +#include <WebCore/DiagnosticLoggingResultType.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { +class WebPageProxy; +} + +namespace API { + +class DiagnosticLoggingClient { +public: + virtual ~DiagnosticLoggingClient() { } + + virtual void logDiagnosticMessage(WebKit::WebPageProxy*, const WTF::String& message, const WTF::String& description) { UNUSED_PARAM(message); UNUSED_PARAM(description); } + virtual void logDiagnosticMessageWithResult(WebKit::WebPageProxy*, const WTF::String& message, const WTF::String& description, WebCore::DiagnosticLoggingResultType) { UNUSED_PARAM(message); UNUSED_PARAM(description); } + virtual void logDiagnosticMessageWithValue(WebKit::WebPageProxy*, const WTF::String& message, const WTF::String& description, const WTF::String& value) { UNUSED_PARAM(message); UNUSED_PARAM(description); UNUSED_PARAM(value); } + virtual void logDiagnosticMessageWithEnhancedPrivacy(WebKit::WebPageProxy*, const WTF::String& message, const WTF::String& description) { UNUSED_PARAM(message); UNUSED_PARAM(description); } +}; + +} // namespace API + +#endif // APIDiagnosticLoggingClient_h + diff --git a/Source/WebKit2/UIProcess/API/APIDownloadClient.h b/Source/WebKit2/UIProcess/API/APIDownloadClient.h new file mode 100644 index 000000000..2a7e3a6ba --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIDownloadClient.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIDownloadClient_h +#define APIDownloadClient_h + +#include <functional> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class ResourceError; +class ResourceRequest; +class ResourceResponse; +} + +namespace WebKit { +class AuthenticationChallengeProxy; +class DownloadProxy; +class WebProcessPool; +class WebProtectionSpace; +} + +namespace API { + +class DownloadClient { +public: + virtual ~DownloadClient() { } + + virtual void didStart(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { } + virtual void didReceiveAuthenticationChallenge(WebKit::WebProcessPool*, WebKit::DownloadProxy*, WebKit::AuthenticationChallengeProxy*) { } + virtual void didReceiveResponse(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WebCore::ResourceResponse&) { } + virtual void didReceiveData(WebKit::WebProcessPool*, WebKit::DownloadProxy*, uint64_t) { } + virtual bool shouldDecodeSourceDataOfMIMEType(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WTF::String&) { return true; } + virtual WTF::String decideDestinationWithSuggestedFilename(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WTF::String&, bool&) { return { }; } + virtual void didCreateDestination(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WTF::String&) { } + virtual void didFinish(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { } + virtual void didFail(WebKit::WebProcessPool*, WebKit::DownloadProxy*, const WebCore::ResourceError&) { } + virtual void didCancel(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { } + virtual void processDidCrash(WebKit::WebProcessPool*, WebKit::DownloadProxy*) { } + virtual bool canAuthenticateAgainstProtectionSpace(WebKit::WebProtectionSpace*) { return true; } + virtual void willSendRequest(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse&, std::function<void(const WebCore::ResourceRequest&)> callback) { callback(request); } +}; + +} // namespace API + +#endif // APIDownloadClient_h diff --git a/Source/WebKit2/UIProcess/API/APIExperimentalFeature.cpp b/Source/WebKit2/UIProcess/API/APIExperimentalFeature.cpp new file mode 100644 index 000000000..b80ad6f2d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIExperimentalFeature.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIExperimentalFeature.h" + +namespace API { + +Ref<ExperimentalFeature> ExperimentalFeature::create(const WTF::String& name, const WTF::String& key, const WTF::String& details, bool defaultValue) +{ + return adoptRef(*new ExperimentalFeature(name, key, details, defaultValue)); +} + +ExperimentalFeature::ExperimentalFeature(const WTF::String& name, const WTF::String& key, const WTF::String& details, bool defaultValue) + : m_name(name) + , m_key(key) + , m_details(details) + , m_defaultValue(defaultValue) +{ +} + +ExperimentalFeature::~ExperimentalFeature() +{ +} + +} diff --git a/Source/WebKit2/UIProcess/API/APIExperimentalFeature.h b/Source/WebKit2/UIProcess/API/APIExperimentalFeature.h new file mode 100644 index 000000000..68a506c7c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIExperimentalFeature.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIExperimentalFeature_h +#define APIExperimentalFeature_h + +#include "APIObject.h" +#include <wtf/text/WTFString.h> + +namespace API { + +class ExperimentalFeature final : public ObjectImpl<Object::Type::ExperimentalFeature> { +public: + static Ref<ExperimentalFeature> create(const WTF::String& name, const WTF::String& key, const WTF::String& details, bool defaultValue); + virtual ~ExperimentalFeature(); + + WTF::String name() const { return m_name; } + WTF::String key() const { return m_key; } + WTF::String details() const { return m_details; } + bool defaultValue() const { return m_defaultValue; } + +private: + explicit ExperimentalFeature(const WTF::String& name, const WTF::String& key, const WTF::String& details, bool defaultValue); + + WTF::String m_name; + WTF::String m_key; + WTF::String m_details; + bool m_defaultValue; +}; + +} + +#endif // APIExperimentalFeature_h diff --git a/Source/WebKit2/UIProcess/API/APIFindClient.h b/Source/WebKit2/UIProcess/API/APIFindClient.h new file mode 100644 index 000000000..0abf8f673 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIFindClient.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIFindClient_h +#define APIFindClient_h + +#include <wtf/text/WTFString.h> + +namespace WebCore { +class IntRect; +} + +namespace WebKit { +class WebPageProxy; +} + +namespace API { + +class FindClient { +public: + virtual ~FindClient() { } + + virtual void didCountStringMatches(WebKit::WebPageProxy*, const WTF::String&, uint32_t) { } + virtual void didFindString(WebKit::WebPageProxy*, const WTF::String&, const Vector<WebCore::IntRect>& matchRects, uint32_t, int32_t) { } + virtual void didFailToFindString(WebKit::WebPageProxy*, const WTF::String&) { } +}; + +} // namespace API + +#endif // APIFindClient_h diff --git a/Source/WebKit2/UIProcess/API/APIFindMatchesClient.h b/Source/WebKit2/UIProcess/API/APIFindMatchesClient.h new file mode 100644 index 000000000..c6f457342 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIFindMatchesClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIFindMatchesClient_h +#define APIFindMatchesClient_h + +#include <WebCore/IntRect.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { +class WebImage; +class WebPageProxy; +} + +namespace API { + +class FindMatchesClient { +public: + virtual ~FindMatchesClient() { } + + virtual void didFindStringMatches(WebKit::WebPageProxy*, const WTF::String&, const WTF::Vector<WTF::Vector<WebCore::IntRect>>&, int32_t) { } + virtual void didGetImageForMatchResult(WebKit::WebPageProxy*, WebKit::WebImage*, int32_t) { } +}; + +} // namespace API + +#endif // APIFindMatchesClient_h diff --git a/Source/WebKit2/UIProcess/WebOriginDataManagerProxyChangeClient.h b/Source/WebKit2/UIProcess/API/APIFormClient.h index 2fea808ac..44c005ba6 100644 --- a/Source/WebKit2/UIProcess/WebOriginDataManagerProxyChangeClient.h +++ b/Source/WebKit2/UIProcess/API/APIFormClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,28 +23,31 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebOriginDataManagerProxyChangeClient_h -#define WebOriginDataManagerProxyChangeClient_h +#ifndef APIFormClient_h +#define APIFormClient_h -#include "APIClient.h" -#include "WKOriginDataManager.h" +#include "WebFormSubmissionListenerProxy.h" #include <wtf/Forward.h> - -namespace API { -template<> struct ClientTraits<WKOriginDataManagerChangeClientBase> { - typedef std::tuple<WKOriginDataManagerChangeClientV0> Versions; -}; -} +#include <wtf/Vector.h> namespace WebKit { +class WebFrameProxy; +class WebPageProxy; +} -class WebOriginDataManagerProxy; +namespace API { +class Object; -class WebOriginDataManagerProxyChangeClient : public API::Client<WKOriginDataManagerChangeClientBase> { +class FormClient { public: - void didChange(WebOriginDataManagerProxy*); + virtual ~FormClient() { } + + virtual void willSubmitForm(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, WebKit::WebFrameProxy&, const Vector<std::pair<WTF::String, WTF::String>>&, API::Object*, Ref<WebKit::WebFormSubmissionListenerProxy>&& listener) + { + listener->continueSubmission(); + } }; -} // namespace WebKit +} // namespace API -#endif // WebOriginDataManagerProxyChangeClient_h +#endif // APIFormClient_h diff --git a/Source/WebKit2/UIProcess/API/APIFrameInfo.cpp b/Source/WebKit2/UIProcess/API/APIFrameInfo.cpp new file mode 100644 index 000000000..3e322e557 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIFrameInfo.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIFrameInfo.h" + +#include "APIFrameHandle.h" +#include "FrameInfoData.h" +#include "WebFrameProxy.h" + +namespace API { + +Ref<FrameInfo> FrameInfo::create(const WebKit::FrameInfoData& frameInfoData) +{ + return adoptRef(*new FrameInfo(frameInfoData)); +} + +Ref<FrameInfo> FrameInfo::create(const WebKit::WebFrameProxy& frame, const WebCore::SecurityOrigin& securityOrigin) +{ + WebKit::FrameInfoData frameInfoData; + + frameInfoData.isMainFrame = frame.isMainFrame(); + // FIXME: This should use the full request of the frame, not just the URL. + frameInfoData.request = WebCore::ResourceRequest(frame.url()); + frameInfoData.securityOrigin = WebCore::SecurityOriginData::fromSecurityOrigin(securityOrigin); + frameInfoData.frameID = frame.frameID(); + + return create(frameInfoData); +} + +FrameInfo::FrameInfo(const WebKit::FrameInfoData& frameInfoData) + : m_isMainFrame(frameInfoData.isMainFrame) + , m_request(frameInfoData.request) + , m_securityOrigin(*SecurityOrigin::create(frameInfoData.securityOrigin.securityOrigin())) + , m_handle(API::FrameHandle::create(frameInfoData.frameID)) +{ +} + +FrameInfo::~FrameInfo() +{ +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIFrameInfo.h b/Source/WebKit2/UIProcess/API/APIFrameInfo.h new file mode 100644 index 000000000..29eef55ec --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIFrameInfo.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIObject.h" +#include <WebCore/ResourceRequest.h> + +namespace WebCore { +class SecurityOrigin; +} + +namespace WebKit { +class WebFrameProxy; +struct FrameInfoData; +} + +namespace API { + +class FrameHandle; +class SecurityOrigin; + +class FrameInfo final : public ObjectImpl<Object::Type::FrameInfo> { +public: + static Ref<FrameInfo> create(const WebKit::FrameInfoData&); + static Ref<FrameInfo> create(const WebKit::WebFrameProxy&, const WebCore::SecurityOrigin&); + virtual ~FrameInfo(); + + bool isMainFrame() const { return m_isMainFrame; } + const WebCore::ResourceRequest& request() const { return m_request; } + SecurityOrigin& securityOrigin() { return m_securityOrigin.get(); } + API::FrameHandle& handle() { return m_handle.get(); } + +private: + FrameInfo(const WebKit::FrameInfoData&); + + bool m_isMainFrame; + WebCore::ResourceRequest m_request; + Ref<SecurityOrigin> m_securityOrigin; + Ref<FrameHandle> m_handle; +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIFullscreenClient.h b/Source/WebKit2/UIProcess/API/APIFullscreenClient.h new file mode 100644 index 000000000..c348b8bfe --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIFullscreenClient.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +namespace WebKit { +class WebPageProxy; +} + +namespace API { + +class FullscreenClient { +public: + virtual ~FullscreenClient() { } + + virtual void willEnterFullscreen(WebKit::WebPageProxy*) { } + virtual void didEnterFullscreen(WebKit::WebPageProxy*) { } + virtual void willExitFullscreen(WebKit::WebPageProxy*) { } + virtual void didExitFullscreen(WebKit::WebPageProxy*) { } +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIHistoryClient.h b/Source/WebKit2/UIProcess/API/APIHistoryClient.h new file mode 100644 index 000000000..77fca2656 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIHistoryClient.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIHistoryClient_h +#define APIHistoryClient_h + +#include <wtf/Forward.h> + +namespace WebKit { +class WebPageProxy; +struct WebNavigationDataStore; +} + +namespace API { + +class HistoryClient { +public: + virtual ~HistoryClient() { } + + virtual void didNavigateWithNavigationData(WebKit::WebPageProxy&, const WebKit::WebNavigationDataStore&) { } + virtual void didPerformClientRedirect(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&) { } + virtual void didPerformServerRedirect(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&) { } + virtual void didUpdateHistoryTitle(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&) { } +}; + +} // namespace API + +#endif // APIHistoryClient_h diff --git a/Source/WebKit2/UIProcess/API/APIHitTestResult.cpp b/Source/WebKit2/UIProcess/API/APIHitTestResult.cpp new file mode 100644 index 000000000..4d4e06234 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIHitTestResult.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "APIHitTestResult.h" + +using namespace WebCore; + +namespace API { + +PassRefPtr<HitTestResult> HitTestResult::create(const WebKit::WebHitTestResultData& hitTestResultData) +{ + return adoptRef(new HitTestResult(hitTestResultData)); +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIHitTestResult.h b/Source/WebKit2/UIProcess/API/APIHitTestResult.h new file mode 100644 index 000000000..dc4f610b2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIHitTestResult.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef APIHitTestResult_h +#define APIHitTestResult_h + +#include "APIObject.h" +#include "SharedMemory.h" +#include "WebHitTestResultData.h" +#include <WebCore/DictionaryPopupInfo.h> +#include <WebCore/FloatPoint.h> +#include <WebCore/IntRect.h> +#include <WebCore/PageOverlay.h> +#include <wtf/Forward.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +OBJC_CLASS DDActionContext; + +namespace IPC { +class Decoder; +class Encoder; +} + +namespace WebCore { +class HitTestResult; +} + +namespace API { + +class WebFrame; + +class HitTestResult : public API::ObjectImpl<API::Object::Type::HitTestResult> { +public: + static PassRefPtr<HitTestResult> create(const WebKit::WebHitTestResultData&); + + WTF::String absoluteImageURL() const { return m_data.absoluteImageURL; } + WTF::String absolutePDFURL() const { return m_data.absolutePDFURL; } + WTF::String absoluteLinkURL() const { return m_data.absoluteLinkURL; } + WTF::String absoluteMediaURL() const { return m_data.absoluteMediaURL; } + + WTF::String linkLabel() const { return m_data.linkLabel; } + WTF::String linkTitle() const { return m_data.linkTitle; } + WTF::String lookupText() const { return m_data.lookupText; } + + bool isContentEditable() const { return m_data.isContentEditable; } + + WebCore::IntRect elementBoundingBox() const { return m_data.elementBoundingBox; } + + bool isScrollbar() const { return m_data.isScrollbar; } + + bool isSelected() const { return m_data.isSelected; } + + bool isTextNode() const { return m_data.isTextNode; } + + bool isOverTextInsideFormControlElement() const { return m_data.isOverTextInsideFormControlElement; } + + bool allowsCopy() const { return m_data.allowsCopy; } + + bool isDownloadableMedia() const { return m_data.isDownloadableMedia; } + +private: + explicit HitTestResult(const WebKit::WebHitTestResultData& hitTestResultData) + : m_data(hitTestResultData) + { + } + + WebKit::WebHitTestResultData m_data; +}; + +} // namespace API + +#endif // APIHitTestResult_h diff --git a/Source/WebKit2/UIProcess/API/APIIconLoadingClient.h b/Source/WebKit2/UIProcess/API/APIIconLoadingClient.h new file mode 100644 index 000000000..5331cba1f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIIconLoadingClient.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "GenericCallback.h" +#include <WebCore/LinkIcon.h> +#include <wtf/Function.h> + +namespace IPC { +class DataReference; +} + +namespace API { + +class IconLoadingClient { +public: + virtual ~IconLoadingClient() { } + + virtual void getLoadDecisionForIcon(const WebCore::LinkIcon&, std::function<void (std::function<void (API::Data*, WebKit::CallbackBase::Error)>)> completionHandler) { + completionHandler(nullptr); + } +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/WebHistoryClient.h b/Source/WebKit2/UIProcess/API/APILegacyContextHistoryClient.h index c748d77cf..cbb9e0a97 100644 --- a/Source/WebKit2/UIProcess/WebHistoryClient.h +++ b/Source/WebKit2/UIProcess/API/APILegacyContextHistoryClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,37 +23,32 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebHistoryClient_h -#define WebHistoryClient_h +#ifndef APILegacyContextHistoryClient_h +#define APILegacyContextHistoryClient_h -#include "APIClient.h" -#include "WKContext.h" #include <wtf/Forward.h> -namespace API { -template<> struct ClientTraits<WKContextHistoryClientBase> { - typedef std::tuple<WKContextHistoryClientV0> Versions; -}; -} - namespace WebKit { - -class WebContext; class WebFrameProxy; class WebPageProxy; +class WebProcessPool; struct WebNavigationDataStore; +} -class WebHistoryClient : public API::Client<WKContextHistoryClientBase> { -public: - void didNavigateWithNavigationData(WebContext*, WebPageProxy*, const WebNavigationDataStore&, WebFrameProxy*); - void didPerformClientRedirect(WebContext*, WebPageProxy*, const String& sourceURL, const String& destinationURL, WebFrameProxy*); - void didPerformServerRedirect(WebContext*, WebPageProxy*, const String& sourceURL, const String& destinationURL, WebFrameProxy*); - void didUpdateHistoryTitle(WebContext*, WebPageProxy*, const String& title, const String& url, WebFrameProxy*); - void populateVisitedLinks(WebContext*); +namespace API { - bool shouldTrackVisitedLinks() const { return m_client.populateVisitedLinks; } +class LegacyContextHistoryClient { +public: + virtual ~LegacyContextHistoryClient() { } + + virtual void didNavigateWithNavigationData(WebKit::WebProcessPool&, WebKit::WebPageProxy&, const WebKit::WebNavigationDataStore&, WebKit::WebFrameProxy&) { } + virtual void didPerformClientRedirect(WebKit::WebProcessPool&, WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + virtual void didPerformServerRedirect(WebKit::WebProcessPool&, WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + virtual void didUpdateHistoryTitle(WebKit::WebProcessPool&, WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + virtual void populateVisitedLinks(WebKit::WebProcessPool&) { } + virtual bool addsVisitedLinks() const { return false; } }; -} // namespace WebKit +} // namespace API -#endif // WebHistoryClient_h +#endif // APILegacyContextHistoryClient_h diff --git a/Source/WebKit2/UIProcess/API/APILoaderClient.h b/Source/WebKit2/UIProcess/API/APILoaderClient.h index f7d68b1fb..f9b6e4632 100644 --- a/Source/WebKit2/UIProcess/API/APILoaderClient.h +++ b/Source/WebKit2/UIProcess/API/APILoaderClient.h @@ -26,6 +26,7 @@ #ifndef APILoaderClient_h #define APILoaderClient_h +#include "APIData.h" #include "PluginModuleInfo.h" #include "SameDocumentNavigationType.h" #include <WebCore/FrameLoaderTypes.h> @@ -38,67 +39,84 @@ class ResourceError; namespace WebKit { class AuthenticationChallengeProxy; -class ImmutableDictionary; +class QuickLookDocumentData; class WebBackForwardListItem; class WebFrameProxy; class WebPageProxy; class WebProtectionSpace; +struct WebNavigationDataStore; } namespace API { +class Dictionary; +class Navigation; class Object; class LoaderClient { public: virtual ~LoaderClient() { } - virtual void didStartProvisionalLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didFailProvisionalLoadWithErrorForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::ResourceError&, API::Object*) { } - virtual void didCommitLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didFinishDocumentLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didFinishLoadForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didFailLoadWithErrorForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::ResourceError&, API::Object*) { } - virtual void didSameDocumentNavigationForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::SameDocumentNavigationType, API::Object*) { } - virtual void didReceiveTitleForFrame(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didFirstLayoutForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } + virtual void didStartProvisionalLoadForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, API::Object*) { } + virtual void didReceiveServerRedirectForProvisionalLoadForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, API::Object*) { } + virtual void didFailProvisionalLoadWithErrorForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, const WebCore::ResourceError&, API::Object*) { } + virtual void didCommitLoadForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, API::Object*) { } + virtual void didFinishDocumentLoadForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, API::Object*) { } + virtual void didFinishLoadForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, API::Object*) { } + virtual void didFailLoadWithErrorForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, const WebCore::ResourceError&, API::Object*) { } + virtual void didSameDocumentNavigationForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, WebKit::SameDocumentNavigationType, API::Object*) { } + virtual void didReceiveTitleForFrame(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy&, API::Object*) { } + virtual void didFirstLayoutForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Object*) { } // FIXME: We should consider removing didFirstVisuallyNonEmptyLayoutForFrame since it is replaced by didLayout. - virtual void didFirstVisuallyNonEmptyLayoutForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } + virtual void didFirstVisuallyNonEmptyLayoutForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Object*) { } - virtual void didRemoveFrameFromHierarchy(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didDisplayInsecureContentForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didRunInsecureContentForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } - virtual void didDetectXSSForFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, API::Object*) { } + virtual void didDisplayInsecureContentForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Object*) { } + virtual void didRunInsecureContentForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Object*) { } + virtual void didDetectXSSForFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Object*) { } - virtual void didLayout(WebKit::WebPageProxy*, WebCore::LayoutMilestones, API::Object*) { } + virtual void didReachLayoutMilestone(WebKit::WebPageProxy&, WebCore::LayoutMilestones) { } - virtual bool canAuthenticateAgainstProtectionSpaceInFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::WebProtectionSpace*) { return false; } - virtual void didReceiveAuthenticationChallengeInFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebKit::AuthenticationChallengeProxy*) { } + virtual bool canAuthenticateAgainstProtectionSpaceInFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, WebKit::WebProtectionSpace*) { return false; } + virtual void didReceiveAuthenticationChallengeInFrame(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, WebKit::AuthenticationChallengeProxy*) { } - virtual void didStartProgress(WebKit::WebPageProxy*) { } - virtual void didChangeProgress(WebKit::WebPageProxy*) { } - virtual void didFinishProgress(WebKit::WebPageProxy*) { } + virtual void didStartProgress(WebKit::WebPageProxy&) { } + virtual void didChangeProgress(WebKit::WebPageProxy&) { } + virtual void didFinishProgress(WebKit::WebPageProxy&) { } - // FIXME: These three functions should not be part of this client. - virtual void processDidBecomeUnresponsive(WebKit::WebPageProxy*) { } - virtual void interactionOccurredWhileProcessUnresponsive(WebKit::WebPageProxy*) { } - virtual void processDidBecomeResponsive(WebKit::WebPageProxy*) { } - virtual void processDidCrash(WebKit::WebPageProxy*) { } + // FIXME: These functions should not be part of this client. + virtual void processDidBecomeUnresponsive(WebKit::WebPageProxy&) { } + virtual void processDidBecomeResponsive(WebKit::WebPageProxy&) { } + virtual void processDidCrash(WebKit::WebPageProxy&) { } - virtual void didChangeBackForwardList(WebKit::WebPageProxy*, WebKit::WebBackForwardListItem* addedItem, Vector<RefPtr<API::Object>>* removedItems) { } - virtual void willGoToBackForwardListItem(WebKit::WebPageProxy*, WebKit::WebBackForwardListItem*, API::Object*) { } + virtual void didChangeBackForwardList(WebKit::WebPageProxy&, WebKit::WebBackForwardListItem*, Vector<RefPtr<WebKit::WebBackForwardListItem>>) { } + virtual bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy&, WebKit::WebBackForwardListItem*) { return true; } + virtual void willGoToBackForwardListItem(WebKit::WebPageProxy&, WebKit::WebBackForwardListItem*, API::Object*) { } + + virtual void didNavigateWithNavigationData(WebKit::WebPageProxy&, const WebKit::WebNavigationDataStore&, WebKit::WebFrameProxy&) { } + virtual void didPerformClientRedirect(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + virtual void didPerformServerRedirect(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + virtual void didUpdateHistoryTitle(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy&) { } + + virtual void navigationGestureDidBegin(WebKit::WebPageProxy&) { } + virtual void navigationGestureWillEnd(WebKit::WebPageProxy&, bool willNavigate, WebKit::WebBackForwardListItem&) { } + virtual void navigationGestureDidEnd(WebKit::WebPageProxy&, bool willNavigate, WebKit::WebBackForwardListItem&) { } #if ENABLE(NETSCAPE_PLUGIN_API) - virtual WebKit::PluginModuleLoadPolicy pluginLoadPolicy(WebKit::WebPageProxy*, WebKit::PluginModuleLoadPolicy currentPluginLoadPolicy, WebKit::ImmutableDictionary*, WTF::String& unavailabilityDescription) { return currentPluginLoadPolicy; } - virtual void didFailToInitializePlugin(WebKit::WebPageProxy*, WebKit::ImmutableDictionary*) { } - virtual void didBlockInsecurePluginVersion(WebKit::WebPageProxy*, WebKit::ImmutableDictionary*) { } + virtual WebKit::PluginModuleLoadPolicy pluginLoadPolicy(WebKit::WebPageProxy&, WebKit::PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary*, WTF::String& /* unavailabilityDescription */) { return currentPluginLoadPolicy; } + virtual void didFailToInitializePlugin(WebKit::WebPageProxy&, API::Dictionary*) { } + virtual void didBlockInsecurePluginVersion(WebKit::WebPageProxy&, API::Dictionary*) { } #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(WEBGL) - virtual WebCore::WebGLLoadPolicy webGLLoadPolicy(WebKit::WebPageProxy*, const WTF::String&) const { return WebCore::WebGLLoadPolicy::WebGLAllow; } + virtual WebCore::WebGLLoadPolicy webGLLoadPolicy(WebKit::WebPageProxy&, const WTF::String&) const { return WebCore::WebGLLoadPolicy::WebGLAllowCreation; } + virtual WebCore::WebGLLoadPolicy resolveWebGLLoadPolicy(WebKit::WebPageProxy&, const WTF::String&) const { return WebCore::WebGLLoadPolicy::WebGLAllowCreation; } #endif // ENABLE(WEBGL) + +#if USE(QUICK_LOOK) + virtual void didStartLoadForQuickLookDocumentInMainFrame(const WTF::String& fileName, const WTF::String& uti) { } + virtual void didFinishLoadForQuickLookDocumentInMainFrame(const WebKit::QuickLookDocumentData&) { } +#endif }; } // namespace API diff --git a/Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp b/Source/WebKit2/UIProcess/API/APINavigation.cpp index 5907d5657..1a80b04ce 100644 --- a/Source/WebKit2/UIProcess/gtk/WebProcessProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/API/APINavigation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,20 +24,25 @@ */ #include "config.h" -#include "WebProcessProxy.h" -#include <glib.h> +#include "APINavigation.h" -namespace WebKit { +#include "WebNavigationState.h" -void WebProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) +namespace API { + +Navigation::Navigation(WebKit::WebNavigationState& state) + : m_navigationID(state.generateNavigationID()) +{ +} + +Navigation::Navigation(WebKit::WebNavigationState& state, const WebCore::ResourceRequest& request) + : m_navigationID(state.generateNavigationID()) + , m_request(request) +{ +} + +Navigation::~Navigation() { -#ifndef NDEBUG - const char* webProcessCmdPrefix = g_getenv("WEB_PROCESS_CMD_PREFIX"); - if (webProcessCmdPrefix && *webProcessCmdPrefix) - launchOptions.processCmdPrefix = String::fromUTF8(webProcessCmdPrefix); -#else - UNUSED_PARAM(launchOptions); -#endif } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/APINavigation.h b/Source/WebKit2/UIProcess/API/APINavigation.h new file mode 100644 index 000000000..a014898c1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APINavigation.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APINavigation_h +#define APINavigation_h + +#include "APIObject.h" +#include <WebCore/ResourceRequest.h> +#include <wtf/Ref.h> + +namespace WebKit { +class WebNavigationState; +} + +namespace API { + +class Navigation : public ObjectImpl<Object::Type::Navigation> { +public: + static Ref<Navigation> create(WebKit::WebNavigationState& state) + { + return adoptRef(*new Navigation(state)); + } + + static Ref<Navigation> create(WebKit::WebNavigationState& state, const WebCore::ResourceRequest& request) + { + return adoptRef(*new Navigation(state, request)); + } + + virtual ~Navigation(); + + uint64_t navigationID() const { return m_navigationID; } + + const WebCore::ResourceRequest& request() const { return m_request; } + +private: + explicit Navigation(WebKit::WebNavigationState&); + explicit Navigation(WebKit::WebNavigationState&, const WebCore::ResourceRequest&); + + uint64_t m_navigationID; + WebCore::ResourceRequest m_request; +}; + +} // namespace API + + +#endif // APINavigation_h diff --git a/Source/WebKit2/UIProcess/API/APINavigationAction.h b/Source/WebKit2/UIProcess/API/APINavigationAction.h new file mode 100644 index 000000000..59497e0e0 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APINavigationAction.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APINavigationAction_h +#define APINavigationAction_h + +#include "APIFrameInfo.h" +#include "APIObject.h" +#include "APIUserInitiatedAction.h" +#include "NavigationActionData.h" +#include <WebCore/ResourceRequest.h> +#include <WebCore/URL.h> + +namespace API { + +class NavigationAction final : public ObjectImpl<Object::Type::NavigationAction> { +public: + static Ref<NavigationAction> create(const WebKit::NavigationActionData& navigationActionData, API::FrameInfo* sourceFrame, API::FrameInfo* targetFrame, const WebCore::ResourceRequest& request, const WebCore::URL& originalURL, bool shouldOpenAppLinks, RefPtr<UserInitiatedAction> userInitiatedAction) + { + return adoptRef(*new NavigationAction(navigationActionData, sourceFrame, targetFrame, request, originalURL, shouldOpenAppLinks, WTFMove(userInitiatedAction))); + } + + NavigationAction(const WebKit::NavigationActionData& navigationActionData, API::FrameInfo* sourceFrame, API::FrameInfo* targetFrame, const WebCore::ResourceRequest& request, const WebCore::URL& originalURL, bool shouldOpenAppLinks, RefPtr<UserInitiatedAction> userInitiatedAction) + : m_sourceFrame(sourceFrame) + , m_targetFrame(targetFrame) + , m_request(request) + , m_originalURL(originalURL) + , m_shouldOpenAppLinks(shouldOpenAppLinks) + , m_userInitiatedAction(WTFMove(userInitiatedAction)) + , m_navigationActionData(navigationActionData) + { + } + + FrameInfo* sourceFrame() const { return m_sourceFrame.get(); } + FrameInfo* targetFrame() const { return m_targetFrame.get(); } + + const WebCore::ResourceRequest& request() const { return m_request; } + const WebCore::URL& originalURL() const { return m_originalURL; } + + WebCore::NavigationType navigationType() const { return m_navigationActionData.navigationType; } + WebKit::WebEvent::Modifiers modifiers() const { return m_navigationActionData.modifiers; } + WebKit::WebMouseEvent::Button mouseButton() const { return m_navigationActionData.mouseButton; } + WebKit::WebMouseEvent::SyntheticClickType syntheticClickType() const { return m_navigationActionData.syntheticClickType; } + bool canHandleRequest() const { return m_navigationActionData.canHandleRequest; } + bool shouldOpenExternalSchemes() const { return m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow || m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes; } + bool shouldOpenAppLinks() const { return m_shouldOpenAppLinks && m_navigationActionData.shouldOpenExternalURLsPolicy == WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; } + bool shouldPerformDownload() const { return !m_navigationActionData.downloadAttribute.isNull(); } + + bool isProcessingUserGesture() const { return m_userInitiatedAction; } + UserInitiatedAction* userInitiatedAction() const { return m_userInitiatedAction.get(); } + +private: + RefPtr<FrameInfo> m_sourceFrame; + RefPtr<FrameInfo> m_targetFrame; + + WebCore::ResourceRequest m_request; + WebCore::URL m_originalURL; + + bool m_shouldOpenAppLinks; + + RefPtr<UserInitiatedAction> m_userInitiatedAction; + + WebKit::NavigationActionData m_navigationActionData; +}; + +} // namespace API + +#endif // APINavigationAction_h diff --git a/Source/WebKit2/UIProcess/API/APINavigationClient.h b/Source/WebKit2/UIProcess/API/APINavigationClient.h new file mode 100644 index 000000000..a6332f7da --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APINavigationClient.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIData.h" +#include "PluginModuleInfo.h" +#include "SameDocumentNavigationType.h" +#include "WebEvent.h" +#include "WebFramePolicyListenerProxy.h" +#include "WebsitePolicies.h" +#include <WebCore/FrameLoaderTypes.h> +#include <WebCore/LayoutMilestones.h> +#include <wtf/Forward.h> + +namespace WebCore { +class ResourceError; +class ResourceRequest; +class ResourceResponse; +struct SecurityOriginData; +} + +namespace WebKit { +class AuthenticationChallengeProxy; +class QuickLookDocumentData; +class WebBackForwardListItem; +class WebFramePolicyListenerProxy; +class WebFrameProxy; +class WebPageProxy; +class WebProtectionSpace; +struct NavigationActionData; +struct WebNavigationDataStore; +} + +namespace API { + +class Dictionary; +class Navigation; +class NavigationAction; +class NavigationResponse; +class Object; + +class NavigationClient { +public: + virtual ~NavigationClient() { } + + virtual void didStartProvisionalNavigation(WebKit::WebPageProxy&, API::Navigation*, API::Object*) { } + virtual void didReceiveServerRedirectForProvisionalNavigation(WebKit::WebPageProxy&, API::Navigation*, API::Object*) { } + virtual void didFailProvisionalNavigationWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, const WebCore::ResourceError&, API::Object*) { } + virtual void didFailProvisionalLoadInSubframeWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, const WebCore::SecurityOriginData&, API::Navigation*, const WebCore::ResourceError&, API::Object*) { } + virtual void didCommitNavigation(WebKit::WebPageProxy&, API::Navigation*, API::Object*) { } + virtual void didFinishDocumentLoad(WebKit::WebPageProxy&, API::Navigation*, API::Object*) { } + virtual void didFinishNavigation(WebKit::WebPageProxy&, API::Navigation*, API::Object*) { } + virtual void didFailNavigationWithError(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, API::Navigation*, const WebCore::ResourceError&, API::Object*) { } + virtual void didSameDocumentNavigation(WebKit::WebPageProxy&, API::Navigation*, WebKit::SameDocumentNavigationType, API::Object*) { } + + virtual void renderingProgressDidChange(WebKit::WebPageProxy&, WebCore::LayoutMilestones) { } + + virtual bool canAuthenticateAgainstProtectionSpace(WebKit::WebPageProxy&, WebKit::WebProtectionSpace*) { return false; } + virtual void didReceiveAuthenticationChallenge(WebKit::WebPageProxy&, WebKit::AuthenticationChallengeProxy*) { } + + // FIXME: These function should not be part of this client. + virtual void processDidCrash(WebKit::WebPageProxy&) { } + virtual void processDidBecomeResponsive(WebKit::WebPageProxy&) { } + virtual void processDidBecomeUnresponsive(WebKit::WebPageProxy&) { } + + virtual RefPtr<Data> webCryptoMasterKey(WebKit::WebPageProxy&) { return nullptr; } + +#if USE(QUICK_LOOK) + virtual void didStartLoadForQuickLookDocumentInMainFrame(const WTF::String& fileName, const WTF::String& uti) { } + virtual void didFinishLoadForQuickLookDocumentInMainFrame(const WebKit::QuickLookDocumentData&) { } +#endif + + virtual void decidePolicyForNavigationAction(WebKit::WebPageProxy&, API::NavigationAction&, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object*) + { + listener->use({ }); + } + + virtual void decidePolicyForNavigationResponse(WebKit::WebPageProxy&, API::NavigationResponse&, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object*) + { + listener->use({ }); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + virtual WebKit::PluginModuleLoadPolicy decidePolicyForPluginLoad(WebKit::WebPageProxy&, WebKit::PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary*, WTF::String&) + { + return currentPluginLoadPolicy; + } +#endif + + virtual void didBeginNavigationGesture(WebKit::WebPageProxy&) { } + virtual void willEndNavigationGesture(WebKit::WebPageProxy&, bool willNavigate, WebKit::WebBackForwardListItem&) { } + virtual void didEndNavigationGesture(WebKit::WebPageProxy&, bool willNavigate, WebKit::WebBackForwardListItem&) { } + virtual void didRemoveNavigationGestureSnapshot(WebKit::WebPageProxy&) { } +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/APINavigationData.cpp b/Source/WebKit2/UIProcess/API/APINavigationData.cpp index 7415e5358..7415e5358 100644 --- a/Source/WebKit2/UIProcess/APINavigationData.cpp +++ b/Source/WebKit2/UIProcess/API/APINavigationData.cpp diff --git a/Source/WebKit2/UIProcess/APINavigationData.h b/Source/WebKit2/UIProcess/API/APINavigationData.h index 22e4183df..f614cc4fc 100644 --- a/Source/WebKit2/UIProcess/APINavigationData.h +++ b/Source/WebKit2/UIProcess/API/APINavigationData.h @@ -28,15 +28,14 @@ #include "APIObject.h" #include "WebNavigationDataStore.h" -#include <wtf/PassRefPtr.h> namespace API { class NavigationData : public ObjectImpl<Object::Type::NavigationData> { public: - static PassRefPtr<NavigationData> create(const WebKit::WebNavigationDataStore& store) + static Ref<NavigationData> create(const WebKit::WebNavigationDataStore& store) { - return adoptRef(new NavigationData(store)); + return adoptRef(*new NavigationData(store)); } virtual ~NavigationData(); diff --git a/Source/WebKit2/UIProcess/API/APINavigationResponse.h b/Source/WebKit2/UIProcess/API/APINavigationResponse.h new file mode 100644 index 000000000..75c456f53 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APINavigationResponse.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APINavigationResponse_h +#define APINavigationResponse_h + +#include "APIFrameInfo.h" +#include "APIObject.h" +#include <WebCore/ResourceRequest.h> +#include <WebCore/ResourceResponse.h> + +namespace API { + +class FrameInfo; + +class NavigationResponse final : public ObjectImpl<Object::Type::NavigationResponse> { +public: + static Ref<NavigationResponse> create(API::FrameInfo& frame, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, bool canShowMIMEType) + { + return adoptRef(*new NavigationResponse(frame, request, response, canShowMIMEType)); + } + + NavigationResponse(API::FrameInfo& frame, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, bool canShowMIMEType) + : m_frame(frame) + , m_request(request) + , m_response(response) + , m_canShowMIMEType(canShowMIMEType) + { + } + + FrameInfo& frame() { return m_frame.get(); } + + const WebCore::ResourceRequest& request() const { return m_request; } + const WebCore::ResourceResponse& response() const { return m_response; } + + bool canShowMIMEType() const { return m_canShowMIMEType; } + +private: + Ref<FrameInfo> m_frame; + + WebCore::ResourceRequest m_request; + WebCore::ResourceResponse m_response; + bool m_canShowMIMEType; +}; + +} // namespace API + +#endif // APINavigationResponse_h diff --git a/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.cpp b/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.cpp new file mode 100644 index 000000000..d1442a3ea --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIOpenPanelParameters.h" + +#include "APIArray.h" +#include "APIString.h" +#include <wtf/Vector.h> + +using namespace WebCore; + +namespace API { + +Ref<OpenPanelParameters> OpenPanelParameters::create(const FileChooserSettings& settings) +{ + return adoptRef(*new OpenPanelParameters(settings)); +} + +OpenPanelParameters::OpenPanelParameters(const FileChooserSettings& settings) + : m_settings(settings) +{ +} + +OpenPanelParameters::~OpenPanelParameters() +{ +} + +Ref<API::Array> OpenPanelParameters::acceptMIMETypes() const +{ + return API::Array::createStringArray(m_settings.acceptMIMETypes); +} + +#if ENABLE(MEDIA_CAPTURE) +WebCore::MediaCaptureType OpenPanelParameters::mediaCaptureType() const +{ + return m_settings.mediaCaptureType; +} +#endif + +Ref<API::Array> OpenPanelParameters::selectedFileNames() const +{ + return API::Array::createStringArray(m_settings.selectedFiles); +} + +} // namespace WebCore diff --git a/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.h b/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.h new file mode 100644 index 000000000..ddf7a4ced --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIOpenPanelParameters.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIObject.h" +#include <WebCore/FileChooser.h> + +namespace API { + +class Array; + +class OpenPanelParameters : public API::ObjectImpl<API::Object::Type::OpenPanelParameters> { +public: + static Ref<OpenPanelParameters> create(const WebCore::FileChooserSettings&); + ~OpenPanelParameters(); + + bool allowMultipleFiles() const { return m_settings.allowsMultipleFiles; } + Ref<API::Array> acceptMIMETypes() const; + Ref<API::Array> selectedFileNames() const; +#if ENABLE(MEDIA_CAPTURE) + WebCore::MediaCaptureType mediaCaptureType() const; +#endif + +private: + explicit OpenPanelParameters(const WebCore::FileChooserSettings&); + + WebCore::FileChooserSettings m_settings; +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIPageConfiguration.cpp b/Source/WebKit2/UIProcess/API/APIPageConfiguration.cpp new file mode 100644 index 000000000..33c8192e2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIPageConfiguration.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2015, 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIPageConfiguration.h" + +#include "APIProcessPoolConfiguration.h" +#include "WebPageGroup.h" +#include "WebPageProxy.h" +#include "WebPreferences.h" +#include "WebProcessPool.h" +#include "WebUserContentControllerProxy.h" + +using namespace WebKit; + +namespace API { + +Ref<PageConfiguration> PageConfiguration::create() +{ + return adoptRef(*new PageConfiguration); +} + +PageConfiguration::PageConfiguration() +{ +} + +PageConfiguration::~PageConfiguration() +{ +} + +Ref<PageConfiguration> PageConfiguration::copy() const +{ + auto copy = create(); + + copy->m_processPool = this->m_processPool; + copy->m_userContentController = this->m_userContentController; + copy->m_pageGroup = this->m_pageGroup; + copy->m_preferences = this->m_preferences; + copy->m_preferenceValues = this->m_preferenceValues; + copy->m_relatedPage = this->m_relatedPage; + copy->m_visitedLinkStore = this->m_visitedLinkStore; + copy->m_websiteDataStore = this->m_websiteDataStore; + copy->m_sessionID = this->m_sessionID; + copy->m_treatsSHA1SignedCertificatesAsInsecure = this->m_treatsSHA1SignedCertificatesAsInsecure; +#if PLATFORM(IOS) + copy->m_alwaysRunsAtForegroundPriority = this->m_alwaysRunsAtForegroundPriority; +#endif + copy->m_initialCapitalizationEnabled = this->m_initialCapitalizationEnabled; + copy->m_controlledByAutomation = this->m_controlledByAutomation; + copy->m_overrideContentSecurityPolicy = this->m_overrideContentSecurityPolicy; + + return copy; +} + + +WebProcessPool* PageConfiguration::processPool() +{ + return m_processPool.get(); +} + +void PageConfiguration::setProcessPool(WebProcessPool* processPool) +{ + m_processPool = processPool; +} + +WebUserContentControllerProxy* PageConfiguration::userContentController() +{ + return m_userContentController.get(); +} + +void PageConfiguration::setUserContentController(WebUserContentControllerProxy* userContentController) +{ + m_userContentController = userContentController; +} + +WebPageGroup* PageConfiguration::pageGroup() +{ + return m_pageGroup.get(); +} + +void PageConfiguration::setPageGroup(WebPageGroup* pageGroup) +{ + m_pageGroup = pageGroup; +} + +WebPreferences* PageConfiguration::preferences() +{ + return m_preferences.get(); +} + +void PageConfiguration::setPreferences(WebPreferences* preferences) +{ + m_preferences = preferences; +} + +WebPageProxy* PageConfiguration::relatedPage() +{ + return m_relatedPage.get(); +} + +void PageConfiguration::setRelatedPage(WebPageProxy* relatedPage) +{ + m_relatedPage = relatedPage; +} + + +VisitedLinkStore* PageConfiguration::visitedLinkStore() +{ + return m_visitedLinkStore.get(); +} + +void PageConfiguration::setVisitedLinkStore(VisitedLinkStore* visitedLinkStore) +{ + m_visitedLinkStore = visitedLinkStore; +} + +API::WebsiteDataStore* PageConfiguration::websiteDataStore() +{ + return m_websiteDataStore.get(); +} + +void PageConfiguration::setWebsiteDataStore(API::WebsiteDataStore* websiteDataStore) +{ + m_websiteDataStore = websiteDataStore; + + if (m_websiteDataStore) + m_sessionID = m_websiteDataStore->websiteDataStore().sessionID(); + else + m_sessionID = WebCore::SessionID(); +} + +WebCore::SessionID PageConfiguration::sessionID() +{ + return m_sessionID; +} + +void PageConfiguration::setSessionID(WebCore::SessionID sessionID) +{ + m_sessionID = sessionID; +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIPageConfiguration.h b/Source/WebKit2/UIProcess/API/APIPageConfiguration.h new file mode 100644 index 000000000..98ae2aa71 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIPageConfiguration.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015, 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIPageConfiguration_h +#define APIPageConfiguration_h + +#include "APIObject.h" +#include "WebPreferencesStore.h" +#include <WebCore/SessionID.h> +#include <wtf/Forward.h> +#include <wtf/GetPtr.h> + +namespace WebKit { +class VisitedLinkStore; +class WebPageGroup; +class WebPageProxy; +class WebPreferences; +class WebProcessPool; +class WebUserContentControllerProxy; +} + +namespace API { + +class WebsiteDataStore; + +class PageConfiguration : public ObjectImpl<Object::Type::PageConfiguration> { +public: + static Ref<PageConfiguration> create(); + + explicit PageConfiguration(); + virtual ~PageConfiguration(); + + Ref<PageConfiguration> copy() const; + + // FIXME: The configuration properties should return their default values + // rather than nullptr. + + WebKit::WebProcessPool* processPool(); + void setProcessPool(WebKit::WebProcessPool*); + + WebKit::WebUserContentControllerProxy* userContentController(); + void setUserContentController(WebKit::WebUserContentControllerProxy*); + + WebKit::WebPageGroup* pageGroup(); + void setPageGroup(WebKit::WebPageGroup*); + + WebKit::WebPreferences* preferences(); + void setPreferences(WebKit::WebPreferences*); + + WebKit::WebPreferencesStore::ValueMap& preferenceValues() { return m_preferenceValues; } + + WebKit::WebPageProxy* relatedPage(); + void setRelatedPage(WebKit::WebPageProxy*); + + WebKit::VisitedLinkStore* visitedLinkStore(); + void setVisitedLinkStore(WebKit::VisitedLinkStore*); + + WebsiteDataStore* websiteDataStore(); + void setWebsiteDataStore(WebsiteDataStore*); + + WebCore::SessionID sessionID(); + void setSessionID(WebCore::SessionID); + + bool treatsSHA1SignedCertificatesAsInsecure() { return m_treatsSHA1SignedCertificatesAsInsecure; } + void setTreatsSHA1SignedCertificatesAsInsecure(bool treatsSHA1SignedCertificatesAsInsecure) { m_treatsSHA1SignedCertificatesAsInsecure = treatsSHA1SignedCertificatesAsInsecure; } + +#if PLATFORM(IOS) + bool alwaysRunsAtForegroundPriority() { return m_alwaysRunsAtForegroundPriority; } + void setAlwaysRunsAtForegroundPriority(bool alwaysRunsAtForegroundPriority) { m_alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority; } +#endif + bool initialCapitalizationEnabled() { return m_initialCapitalizationEnabled; } + void setInitialCapitalizationEnabled(bool initialCapitalizationEnabled) { m_initialCapitalizationEnabled = initialCapitalizationEnabled; } + + bool waitsForPaintAfterViewDidMoveToWindow() const { return m_waitsForPaintAfterViewDidMoveToWindow; } + void setWaitsForPaintAfterViewDidMoveToWindow(bool shouldSynchronize) { m_waitsForPaintAfterViewDidMoveToWindow = shouldSynchronize; } + + bool isControlledByAutomation() const { return m_controlledByAutomation; } + void setControlledByAutomation(bool controlledByAutomation) { m_controlledByAutomation = controlledByAutomation; } + + const WTF::String& overrideContentSecurityPolicy() const { return m_overrideContentSecurityPolicy; } + void setOverrideContentSecurityPolicy(const WTF::String& overrideContentSecurityPolicy) { m_overrideContentSecurityPolicy = overrideContentSecurityPolicy; } + +private: + + RefPtr<WebKit::WebProcessPool> m_processPool; + RefPtr<WebKit::WebUserContentControllerProxy> m_userContentController; + RefPtr<WebKit::WebPageGroup> m_pageGroup; + RefPtr<WebKit::WebPreferences> m_preferences; + WebKit::WebPreferencesStore::ValueMap m_preferenceValues; + RefPtr<WebKit::WebPageProxy> m_relatedPage; + RefPtr<WebKit::VisitedLinkStore> m_visitedLinkStore; + + RefPtr<WebsiteDataStore> m_websiteDataStore; + // FIXME: We currently have to pass the session ID separately here to support the legacy private browsing session. + // Once we get rid of it we should get rid of this configuration parameter as well. + WebCore::SessionID m_sessionID; + + bool m_treatsSHA1SignedCertificatesAsInsecure = true; +#if PLATFORM(IOS) + bool m_alwaysRunsAtForegroundPriority = false; +#endif + bool m_initialCapitalizationEnabled = true; + bool m_waitsForPaintAfterViewDidMoveToWindow = true; + bool m_controlledByAutomation = false; + + WTF::String m_overrideContentSecurityPolicy; +}; + +} // namespace API + + +#endif // APIPageConfiguration_h diff --git a/Source/WebKit2/UIProcess/API/APIPolicyClient.h b/Source/WebKit2/UIProcess/API/APIPolicyClient.h index b0215a48a..6dc087142 100644 --- a/Source/WebKit2/UIProcess/API/APIPolicyClient.h +++ b/Source/WebKit2/UIProcess/API/APIPolicyClient.h @@ -28,6 +28,7 @@ #include "WebEvent.h" #include "WebFramePolicyListenerProxy.h" +#include "WebsitePolicies.h" #include <WebCore/FrameLoaderTypes.h> #include <wtf/Forward.h> @@ -51,10 +52,19 @@ class PolicyClient { public: virtual ~PolicyClient() { } - virtual void decidePolicyForNavigationAction(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebKit::NavigationActionData&, WebKit::WebFrameProxy* originatingFrame, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, WebKit::WebFramePolicyListenerProxy* listener, API::Object* userData) { listener->use(); } - virtual void decidePolicyForNewWindowAction(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, WebCore::NavigationType, WebKit::WebEvent::Modifiers, WebKit::WebMouseEvent::Button, const WebCore::ResourceRequest&, const WTF::String& frameName, WebKit::WebFramePolicyListenerProxy* listener, API::Object* userData) { listener->use(); } - virtual void decidePolicyForResponse(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, WebKit::WebFramePolicyListenerProxy* listener, API::Object* userData) { listener->use(); } - virtual void unableToImplementPolicy(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::ResourceError&, API::Object* userData) { } + virtual void decidePolicyForNavigationAction(WebKit::WebPageProxy&, WebKit::WebFrameProxy*, const WebKit::NavigationActionData&, WebKit::WebFrameProxy*, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object*) + { + listener->use({ }); + } + virtual void decidePolicyForNewWindowAction(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, const WebKit::NavigationActionData&, const WebCore::ResourceRequest&, const WTF::String&, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object*) + { + listener->use({ }); + } + virtual void decidePolicyForResponse(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object*) + { + listener->use({ }); + } + virtual void unableToImplementPolicy(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, const WebCore::ResourceError&, API::Object*) { } }; } // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp b/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp new file mode 100644 index 000000000..18d1e2b97 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIProcessPoolConfiguration.h" + +#include "APIWebsiteDataStore.h" +#include "WebProcessPool.h" + +namespace API { + +Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::create() +{ + return adoptRef(*new ProcessPoolConfiguration); +} + +Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::createWithLegacyOptions() +{ + auto configuration = ProcessPoolConfiguration::create(); + + configuration->m_shouldHaveLegacyDataStore = true; + configuration->m_maximumProcessCount = 1; + configuration->m_cacheModel = WebKit::CacheModelDocumentViewer; + + configuration->m_applicationCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultApplicationCacheDirectory(); + configuration->m_applicationCacheFlatFileSubdirectoryName = "ApplicationCache"; + configuration->m_diskCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultNetworkCacheDirectory(); + configuration->m_mediaCacheDirectory = WebKit::WebProcessPool::legacyPlatformDefaultMediaCacheDirectory(); + configuration->m_indexedDBDatabaseDirectory = WebKit::WebProcessPool::legacyPlatformDefaultIndexedDBDatabaseDirectory(); + configuration->m_localStorageDirectory = WebKit::WebProcessPool::legacyPlatformDefaultLocalStorageDirectory(); + configuration->m_mediaKeysStorageDirectory = WebKit::WebProcessPool::legacyPlatformDefaultMediaKeysStorageDirectory(); + configuration->m_webSQLDatabaseDirectory = WebKit::WebProcessPool::legacyPlatformDefaultWebSQLDatabaseDirectory(); + + return configuration; +} + +Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration(const WebKit::WebsiteDataStore::Configuration& legacyConfiguration) +{ + auto configuration = ProcessPoolConfiguration::create(); + + configuration->m_applicationCacheDirectory = legacyConfiguration.applicationCacheDirectory; + configuration->m_applicationCacheFlatFileSubdirectoryName = legacyConfiguration.applicationCacheFlatFileSubdirectoryName; + configuration->m_diskCacheDirectory = legacyConfiguration.networkCacheDirectory; + configuration->m_mediaCacheDirectory = legacyConfiguration.mediaCacheDirectory; + configuration->m_indexedDBDatabaseDirectory = WebKit::WebProcessPool::legacyPlatformDefaultIndexedDBDatabaseDirectory(); + configuration->m_localStorageDirectory = legacyConfiguration.localStorageDirectory; + configuration->m_mediaKeysStorageDirectory = legacyConfiguration.mediaKeysStorageDirectory; + configuration->m_webSQLDatabaseDirectory = legacyConfiguration.webSQLDatabaseDirectory; + + return configuration; +} + +ProcessPoolConfiguration::ProcessPoolConfiguration() + : m_applicationCacheDirectory(WebsiteDataStore::defaultApplicationCacheDirectory()) + , m_applicationCacheFlatFileSubdirectoryName("Files") + , m_diskCacheDirectory(WebsiteDataStore::defaultNetworkCacheDirectory()) + , m_mediaCacheDirectory(WebsiteDataStore::defaultMediaCacheDirectory()) + , m_indexedDBDatabaseDirectory(WebsiteDataStore::defaultIndexedDBDatabaseDirectory()) + , m_localStorageDirectory(WebsiteDataStore::defaultLocalStorageDirectory()) + , m_webSQLDatabaseDirectory(WebsiteDataStore::defaultWebSQLDatabaseDirectory()) + , m_mediaKeysStorageDirectory(WebsiteDataStore::defaultMediaKeysStorageDirectory()) +{ +} + +ProcessPoolConfiguration::~ProcessPoolConfiguration() +{ +} + +Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy() +{ + auto copy = this->create(); + + copy->m_shouldHaveLegacyDataStore = this->m_shouldHaveLegacyDataStore; + copy->m_maximumProcessCount = this->m_maximumProcessCount; + copy->m_cacheModel = this->m_cacheModel; + copy->m_diskCacheSpeculativeValidationEnabled = this->m_diskCacheSpeculativeValidationEnabled; + copy->m_unresponsiveBackgroundProcessesTerminationEnabled = this->m_unresponsiveBackgroundProcessesTerminationEnabled; + copy->m_diskCacheSizeOverride = this->m_diskCacheSizeOverride; + copy->m_applicationCacheDirectory = this->m_applicationCacheDirectory; + copy->m_applicationCacheFlatFileSubdirectoryName = this->m_applicationCacheFlatFileSubdirectoryName; + copy->m_diskCacheDirectory = this->m_diskCacheDirectory; + copy->m_mediaCacheDirectory = this->m_mediaCacheDirectory; + copy->m_indexedDBDatabaseDirectory = this->m_indexedDBDatabaseDirectory; + copy->m_injectedBundlePath = this->m_injectedBundlePath; + copy->m_localStorageDirectory = this->m_localStorageDirectory; + copy->m_mediaKeysStorageDirectory = this->m_mediaKeysStorageDirectory; + copy->m_webSQLDatabaseDirectory = this->m_webSQLDatabaseDirectory; + copy->m_cachePartitionedURLSchemes = this->m_cachePartitionedURLSchemes; + copy->m_alwaysRevalidatedURLSchemes = this->m_alwaysRevalidatedURLSchemes; + copy->m_fullySynchronousModeIsAllowedForTesting = this->m_fullySynchronousModeIsAllowedForTesting; + copy->m_ignoreSynchronousMessagingTimeoutsForTesting = this->m_ignoreSynchronousMessagingTimeoutsForTesting; + copy->m_overrideLanguages = this->m_overrideLanguages; + copy->m_sourceApplicationBundleIdentifier = this->m_sourceApplicationBundleIdentifier; + copy->m_sourceApplicationSecondaryIdentifier = this->m_sourceApplicationSecondaryIdentifier; + copy->m_alwaysRunsAtBackgroundPriority = this->m_alwaysRunsAtBackgroundPriority; +#if PLATFORM(IOS) + copy->m_ctDataConnectionServiceType = this->m_ctDataConnectionServiceType; +#endif + + return copy; +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h b/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h new file mode 100644 index 000000000..d42b749b9 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIContextConfiguration_h +#define APIContextConfiguration_h + +#include "APIObject.h" +#include "CacheModel.h" +#include "WebsiteDataStore.h" +#include <wtf/Ref.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace API { + +class ProcessPoolConfiguration final : public ObjectImpl<Object::Type::ProcessPoolConfiguration> { +public: + static Ref<ProcessPoolConfiguration> create(); + static Ref<ProcessPoolConfiguration> createWithLegacyOptions(); + static Ref<ProcessPoolConfiguration> createWithWebsiteDataStoreConfiguration(const WebKit::WebsiteDataStore::Configuration&); + + explicit ProcessPoolConfiguration(); + virtual ~ProcessPoolConfiguration(); + + Ref<ProcessPoolConfiguration> copy(); + + bool shouldHaveLegacyDataStore() const { return m_shouldHaveLegacyDataStore; } + void setShouldHaveLegacyDataStore(bool shouldHaveLegacyDataStore) { m_shouldHaveLegacyDataStore = shouldHaveLegacyDataStore; } + + unsigned maximumProcessCount() const { return m_maximumProcessCount; } + void setMaximumProcessCount(unsigned maximumProcessCount) { m_maximumProcessCount = maximumProcessCount; } + + bool diskCacheSpeculativeValidationEnabled() const { return m_diskCacheSpeculativeValidationEnabled; } + void setDiskCacheSpeculativeValidationEnabled(bool enabled) { m_diskCacheSpeculativeValidationEnabled = enabled; } + + bool unresponsiveBackgroundProcessesTerminationEnabled() const { return m_unresponsiveBackgroundProcessesTerminationEnabled; } + void setUnresponsiveBackgroundProcessesTerminationEnabled(bool enabled) { m_unresponsiveBackgroundProcessesTerminationEnabled = enabled; } + + WebKit::CacheModel cacheModel() const { return m_cacheModel; } + void setCacheModel(WebKit::CacheModel cacheModel) { m_cacheModel = cacheModel; } + + int64_t diskCacheSizeOverride() const { return m_diskCacheSizeOverride; } + void setDiskCacheSizeOverride(int64_t size) { m_diskCacheSizeOverride = size; } + + const WTF::String& applicationCacheDirectory() const { return m_applicationCacheDirectory; } + void setApplicationCacheDirectory(const WTF::String& applicationCacheDirectory) { m_applicationCacheDirectory = applicationCacheDirectory; } + + const WTF::String& applicationCacheFlatFileSubdirectoryName() const { return m_applicationCacheFlatFileSubdirectoryName; } + + const WTF::String& diskCacheDirectory() const { return m_diskCacheDirectory; } + void setDiskCacheDirectory(const WTF::String& diskCacheDirectory) { m_diskCacheDirectory = diskCacheDirectory; } + + const WTF::String& mediaCacheDirectory() const { return m_mediaCacheDirectory; } + void setMediaCacheDirectory(const WTF::String& mediaCacheDirectory) { m_mediaCacheDirectory = mediaCacheDirectory; } + + const WTF::String& indexedDBDatabaseDirectory() const { return m_indexedDBDatabaseDirectory; } + void setIndexedDBDatabaseDirectory(const WTF::String& indexedDBDatabaseDirectory) { m_indexedDBDatabaseDirectory = indexedDBDatabaseDirectory; } + + const WTF::String& injectedBundlePath() const { return m_injectedBundlePath; } + void setInjectedBundlePath(const WTF::String& injectedBundlePath) { m_injectedBundlePath = injectedBundlePath; } + + const WTF::String& localStorageDirectory() const { return m_localStorageDirectory; } + void setLocalStorageDirectory(const WTF::String& localStorageDirectory) { m_localStorageDirectory = localStorageDirectory; } + + const WTF::String& webSQLDatabaseDirectory() const { return m_webSQLDatabaseDirectory; } + void setWebSQLDatabaseDirectory(const WTF::String& webSQLDatabaseDirectory) { m_webSQLDatabaseDirectory = webSQLDatabaseDirectory; } + + const WTF::String& mediaKeysStorageDirectory() const { return m_mediaKeysStorageDirectory; } + void setMediaKeysStorageDirectory(const WTF::String& mediaKeysStorageDirectory) { m_mediaKeysStorageDirectory = mediaKeysStorageDirectory; } + + const Vector<WTF::String>& cachePartitionedURLSchemes() { return m_cachePartitionedURLSchemes; } + void setCachePartitionedURLSchemes(Vector<WTF::String>&& cachePartitionedURLSchemes) { m_cachePartitionedURLSchemes = WTFMove(cachePartitionedURLSchemes); } + + const Vector<WTF::String>& alwaysRevalidatedURLSchemes() { return m_alwaysRevalidatedURLSchemes; } + void setAlwaysRevalidatedURLSchemes(Vector<WTF::String>&& alwaysRevalidatedURLSchemes) { m_alwaysRevalidatedURLSchemes = WTFMove(alwaysRevalidatedURLSchemes); } + + bool fullySynchronousModeIsAllowedForTesting() const { return m_fullySynchronousModeIsAllowedForTesting; } + void setFullySynchronousModeIsAllowedForTesting(bool allowed) { m_fullySynchronousModeIsAllowedForTesting = allowed; } + + bool ignoreSynchronousMessagingTimeoutsForTesting() const { return m_ignoreSynchronousMessagingTimeoutsForTesting; } + void setIgnoreSynchronousMessagingTimeoutsForTesting(bool allowed) { m_ignoreSynchronousMessagingTimeoutsForTesting = allowed; } + + const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; } + void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTFMove(languages); } + + const WTF::String& sourceApplicationBundleIdentifier() const { return m_sourceApplicationBundleIdentifier; } + void setSourceApplicationBundleIdentifier(const WTF::String& sourceApplicationBundleIdentifier) { m_sourceApplicationBundleIdentifier = sourceApplicationBundleIdentifier; } + + const WTF::String& sourceApplicationSecondaryIdentifier() const { return m_sourceApplicationSecondaryIdentifier; } + void setSourceApplicationSecondaryIdentifier(const WTF::String& sourceApplicationSecondaryIdentifier) { m_sourceApplicationSecondaryIdentifier = sourceApplicationSecondaryIdentifier; } + + bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; } + void setAlwaysRunsAtBackgroundPriority(bool alwaysRunsAtBackgroundPriority) { m_alwaysRunsAtBackgroundPriority = alwaysRunsAtBackgroundPriority; } + +#if PLATFORM(IOS) + const WTF::String& ctDataConnectionServiceType() const { return m_ctDataConnectionServiceType; } + void setCTDataConnectionServiceType(const WTF::String& ctDataConnectionServiceType) { m_ctDataConnectionServiceType = ctDataConnectionServiceType; } +#endif + +private: + bool m_shouldHaveLegacyDataStore { false }; + + unsigned m_maximumProcessCount { 0 }; + bool m_diskCacheSpeculativeValidationEnabled { false }; + bool m_unresponsiveBackgroundProcessesTerminationEnabled { false }; + WebKit::CacheModel m_cacheModel { WebKit::CacheModelPrimaryWebBrowser }; + int64_t m_diskCacheSizeOverride { -1 }; + + WTF::String m_applicationCacheDirectory; + WTF::String m_applicationCacheFlatFileSubdirectoryName; + WTF::String m_diskCacheDirectory; + WTF::String m_mediaCacheDirectory; + WTF::String m_indexedDBDatabaseDirectory; + WTF::String m_injectedBundlePath; + WTF::String m_localStorageDirectory; + WTF::String m_webSQLDatabaseDirectory; + WTF::String m_mediaKeysStorageDirectory; + WTF::String m_resourceLoadStatisticsDirectory; + Vector<WTF::String> m_cachePartitionedURLSchemes; + Vector<WTF::String> m_alwaysRevalidatedURLSchemes; + bool m_fullySynchronousModeIsAllowedForTesting { false }; + bool m_ignoreSynchronousMessagingTimeoutsForTesting { false }; + Vector<WTF::String> m_overrideLanguages; + WTF::String m_sourceApplicationBundleIdentifier; + WTF::String m_sourceApplicationSecondaryIdentifier; + bool m_alwaysRunsAtBackgroundPriority { false }; +#if PLATFORM(IOS) + WTF::String m_ctDataConnectionServiceType; +#endif +}; + +} // namespace API + +#endif // APIContextConfiguration_h diff --git a/Source/WebKit2/UIProcess/API/C/WKSessionRef.cpp b/Source/WebKit2/UIProcess/API/APISessionState.cpp index 4af2f7bb5..473e5c750 100644 --- a/Source/WebKit2/UIProcess/API/C/WKSessionRef.cpp +++ b/Source/WebKit2/UIProcess/API/APISessionState.cpp @@ -24,25 +24,22 @@ */ #include "config.h" -#include "WKSessionRef.h" +#include "APISessionState.h" -#include "APISession.h" -#include "WKAPICast.h" +namespace API { -using namespace WebKit; - -WKSessionRef WKSessionCreate(bool isEphemeral) +Ref<SessionState> SessionState::create(WebKit::SessionState sessionState) { - RefPtr<API::Session> session = API::Session::create(isEphemeral); - return toAPI(session.release().leakRef()); + return adoptRef(*new SessionState(WTFMove(sessionState))); } -WKTypeID WKSessionGetTypeID() +SessionState::SessionState(WebKit::SessionState sessionState) + : m_sessionState(WTFMove(sessionState)) { - return toAPI(API::Session::APIType); } -bool WKSessionIsEphemeral(WKSessionRef sessionRef) +SessionState::~SessionState() { - return toAPI(toImpl(sessionRef)->isEphemeral()); } + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APISessionState.h b/Source/WebKit2/UIProcess/API/APISessionState.h new file mode 100644 index 000000000..e4d32f7fc --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APISessionState.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APISessionState_h +#define APISessionState_h + +#include "APIObject.h" +#include "SessionState.h" + +namespace API { + +class SessionState final : public ObjectImpl<Object::Type::SessionState> { +public: + static Ref<SessionState> create(WebKit::SessionState); + virtual ~SessionState(); + + const WebKit::SessionState& sessionState() const { return m_sessionState; } + +private: + explicit SessionState(WebKit::SessionState); + + const WebKit::SessionState m_sessionState; +}; + +} // namespace API + +#endif // APISessionState_h diff --git a/Source/WebKit2/UIProcess/API/APIUIClient.h b/Source/WebKit2/UIProcess/API/APIUIClient.h new file mode 100644 index 000000000..44a3e22ef --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUIClient.h @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUIClient_h +#define APIUIClient_h + +#include "WKPage.h" +#include "WebEvent.h" +#include "WebHitTestResultData.h" +#include "WebPageProxy.h" +#include <WebCore/FloatRect.h> +#include <functional> +#include <wtf/PassRefPtr.h> + +#if PLATFORM(IOS) +OBJC_CLASS NSArray; +OBJC_CLASS _WKActivatedElementInfo; +OBJC_CLASS UIViewController; +#endif + +namespace WebCore { +class ResourceRequest; +struct SecurityOriginData; +struct WindowFeatures; +} + +namespace WebKit { +class GeolocationPermissionRequestProxy; +class NativeWebKeyboardEvent; +class NativeWebWheelEvent; +class NotificationPermissionRequest; +class UserMediaPermissionRequestProxy; +class WebColorPickerResultListenerProxy; +class WebFrameProxy; +class WebOpenPanelResultListenerProxy; +class WebPageProxy; +struct NavigationActionData; + +#if ENABLE(MEDIA_SESSION) +class WebMediaSessionMetadata; +#endif +} + +namespace API { + +class Data; +class Dictionary; +class Object; +class OpenPanelParameters; +class SecurityOrigin; + +class UIClient { +public: + virtual ~UIClient() { } + + virtual PassRefPtr<WebKit::WebPageProxy> createNewPage(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const WebKit::NavigationActionData&) { return nullptr; } + virtual void showPage(WebKit::WebPageProxy*) { } + virtual void fullscreenMayReturnToInline(WebKit::WebPageProxy*) { } + virtual void didEnterFullscreen(WebKit::WebPageProxy*) { } + virtual void didExitFullscreen(WebKit::WebPageProxy*) { } + virtual void close(WebKit::WebPageProxy*) { } + + virtual void takeFocus(WebKit::WebPageProxy*, WKFocusDirection) { } + virtual void focus(WebKit::WebPageProxy*) { } + virtual void unfocus(WebKit::WebPageProxy*) { } + + virtual void runJavaScriptAlert(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void ()>&& completionHandler) { completionHandler(); } + virtual void runJavaScriptConfirm(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) { completionHandler(false); } + virtual void runJavaScriptPrompt(WebKit::WebPageProxy*, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (const WTF::String&)>&& completionHandler) { completionHandler(WTF::String()); } + + virtual void setStatusText(WebKit::WebPageProxy*, const WTF::String&) { } + virtual void mouseDidMoveOverElement(WebKit::WebPageProxy*, const WebKit::WebHitTestResultData&, WebKit::WebEvent::Modifiers, API::Object*) { } +#if ENABLE(NETSCAPE_PLUGIN_API) + virtual void unavailablePluginButtonClicked(WebKit::WebPageProxy*, WKPluginUnavailabilityReason, API::Dictionary*) { } +#endif // ENABLE(NETSCAPE_PLUGIN_API) + + virtual bool implementsDidNotHandleKeyEvent() const { return false; } + virtual void didNotHandleKeyEvent(WebKit::WebPageProxy*, const WebKit::NativeWebKeyboardEvent&) { } + + virtual bool implementsDidNotHandleWheelEvent() const { return false; } + virtual void didNotHandleWheelEvent(WebKit::WebPageProxy*, const WebKit::NativeWebWheelEvent&) { } + + virtual bool toolbarsAreVisible(WebKit::WebPageProxy*) { return true; } + virtual void setToolbarsAreVisible(WebKit::WebPageProxy*, bool) { } + virtual bool menuBarIsVisible(WebKit::WebPageProxy*) { return true; } + virtual void setMenuBarIsVisible(WebKit::WebPageProxy*, bool) { } + virtual bool statusBarIsVisible(WebKit::WebPageProxy*) { return true; } + virtual void setStatusBarIsVisible(WebKit::WebPageProxy*, bool) { } + virtual bool isResizable(WebKit::WebPageProxy*) { return true; } + virtual void setIsResizable(WebKit::WebPageProxy*, bool) { } + + virtual void setWindowFrame(WebKit::WebPageProxy*, const WebCore::FloatRect&) { } + virtual WebCore::FloatRect windowFrame(WebKit::WebPageProxy*) { return WebCore::FloatRect(); } + + virtual bool canRunBeforeUnloadConfirmPanel() const { return false; } + virtual void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String&, WebKit::WebFrameProxy*, Function<void (bool)>&& completionHandler) { completionHandler(true); } + + virtual void pageDidScroll(WebKit::WebPageProxy*) { } + + virtual void exceededDatabaseQuota(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, SecurityOrigin*, const WTF::String&, const WTF::String&, unsigned long long currentQuota, unsigned long long, unsigned long long, unsigned long long, Function<void (unsigned long long)>&& completionHandler) + { + completionHandler(currentQuota); + } + + virtual void reachedApplicationCacheOriginQuota(WebKit::WebPageProxy*, const WebCore::SecurityOrigin&, uint64_t currentQuota, uint64_t, Function<void (unsigned long long)>&& completionHandler) + { + completionHandler(currentQuota); + } + + virtual bool runOpenPanel(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::SecurityOriginData&, OpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*) { return false; } + virtual bool decidePolicyForGeolocationPermissionRequest(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, SecurityOrigin*, WebKit::GeolocationPermissionRequestProxy*) { return false; } + virtual bool decidePolicyForUserMediaPermissionRequest(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, SecurityOrigin&, WebKit::UserMediaPermissionRequestProxy&) { return false; } + virtual bool checkUserMediaPermissionForOrigin(WebKit::WebPageProxy&, WebKit::WebFrameProxy&, SecurityOrigin&, SecurityOrigin&, WebKit::UserMediaPermissionCheckProxy&) { return false; } + virtual bool decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy*, SecurityOrigin*, WebKit::NotificationPermissionRequest*) { return false; } + + // Printing. + virtual float headerHeight(WebKit::WebPageProxy*, WebKit::WebFrameProxy*) { return 0; } + virtual float footerHeight(WebKit::WebPageProxy*, WebKit::WebFrameProxy*) { return 0; } + virtual void drawHeader(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::FloatRect&) { } + virtual void drawFooter(WebKit::WebPageProxy*, WebKit::WebFrameProxy*, const WebCore::FloatRect&) { } + virtual void printFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy*) { } + + virtual bool canRunModal() const { return false; } + virtual void runModal(WebKit::WebPageProxy*) { } + + virtual void saveDataToFileInDownloadsFolder(WebKit::WebPageProxy*, const WTF::String&, const WTF::String&, const WTF::String&, API::Data*) { } + + virtual void pinnedStateDidChange(WebKit::WebPageProxy&) { } + + virtual void isPlayingAudioDidChange(WebKit::WebPageProxy&) { } + virtual void didBeginCaptureSession() { } + virtual void didEndCaptureSession() { } + virtual void didPlayMediaPreventedFromPlayingWithoutUserGesture(WebKit::WebPageProxy&) { } + +#if ENABLE(MEDIA_SESSION) + virtual void mediaSessionMetadataDidChange(WebKit::WebPageProxy&, WebKit::WebMediaSessionMetadata*) { } +#endif + +#if PLATFORM(IOS) +#if HAVE(APP_LINKS) + virtual bool shouldIncludeAppLinkActionsForElement(_WKActivatedElementInfo *) { return true; } +#endif + virtual RetainPtr<NSArray> actionsForElement(_WKActivatedElementInfo *, RetainPtr<NSArray> defaultActions) { return defaultActions; } + virtual void didNotHandleTapAsClick(const WebCore::IntPoint&) { } + virtual UIViewController *presentingViewController() { return nullptr; } +#endif +#if PLATFORM(COCOA) + virtual NSDictionary *dataDetectionContext() { return nullptr; } +#endif + +#if ENABLE(POINTER_LOCK) + virtual void requestPointerLock(WebKit::WebPageProxy*) { } + virtual void didLosePointerLock(WebKit::WebPageProxy*) { } +#endif + + virtual void didClickAutoFillButton(WebKit::WebPageProxy&, API::Object*) { } + + virtual void imageOrMediaDocumentSizeChanged(const WebCore::IntSize&) { } +}; + +} // namespace API + +#endif // APIUIClient_h diff --git a/Source/WebKit2/UIProcess/API/APIUserContentExtension.cpp b/Source/WebKit2/UIProcess/API/APIUserContentExtension.cpp new file mode 100644 index 000000000..b06d9d43b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentExtension.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIUserContentExtension.h" + +#if ENABLE(CONTENT_EXTENSIONS) + +#include "WebCompiledContentExtension.h" + +namespace API { + +UserContentExtension::UserContentExtension(const WTF::String& name, Ref<WebKit::WebCompiledContentExtension>&& contentExtension) + : m_name(name) + , m_compiledExtension(WTFMove(contentExtension)) +{ +} + +UserContentExtension::~UserContentExtension() +{ +} + +} // namespace API + +#endif // ENABLE(CONTENT_EXTENSIONS) diff --git a/Source/WebKit2/UIProcess/API/APIUserContentExtension.h b/Source/WebKit2/UIProcess/API/APIUserContentExtension.h new file mode 100644 index 000000000..c60661870 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentExtension.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUserContentExtension_h +#define APIUserContentExtension_h + +#include "APIObject.h" +#include <wtf/text/WTFString.h> + +namespace WebKit { +class WebCompiledContentExtension; +} + +namespace API { + +class UserContentExtension final : public ObjectImpl<Object::Type::UserContentExtension> { +public: +#if ENABLE(CONTENT_EXTENSIONS) + static Ref<UserContentExtension> create(const WTF::String& name, Ref<WebKit::WebCompiledContentExtension>&& contentExtension) + { + return adoptRef(*new UserContentExtension(name, WTFMove(contentExtension))); + } + + UserContentExtension(const WTF::String& name, Ref<WebKit::WebCompiledContentExtension>&&); + virtual ~UserContentExtension(); + + const WTF::String& name() const { return m_name; } + const WebKit::WebCompiledContentExtension& compiledExtension() const { return m_compiledExtension.get(); } + +private: + WTF::String m_name; + Ref<WebKit::WebCompiledContentExtension> m_compiledExtension; +#endif // ENABLE(CONTENT_EXTENSIONS) +}; + +} // namespace API + +#endif // APIUserContentExtension_h diff --git a/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.cpp b/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.cpp new file mode 100644 index 000000000..3a740fd50 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.cpp @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIUserContentExtensionStore.h" + +#if ENABLE(CONTENT_EXTENSIONS) + +#include "APIUserContentExtension.h" +#include "NetworkCacheData.h" +#include "NetworkCacheFileSystem.h" +#include "SharedMemory.h" +#include "WebCompiledContentExtension.h" +#include <WebCore/ContentExtensionCompiler.h> +#include <WebCore/ContentExtensionError.h> +#include <string> +#include <wtf/NeverDestroyed.h> +#include <wtf/RunLoop.h> +#include <wtf/WorkQueue.h> +#include <wtf/persistence/Decoder.h> +#include <wtf/persistence/Encoder.h> + +using namespace WebKit::NetworkCache; + +namespace API { + +UserContentExtensionStore& UserContentExtensionStore::defaultStore() +{ + static UserContentExtensionStore* defaultStore = adoptRef(new UserContentExtensionStore).leakRef(); + return *defaultStore; +} + +Ref<UserContentExtensionStore> UserContentExtensionStore::storeWithPath(const WTF::String& storePath) +{ + return adoptRef(*new UserContentExtensionStore(storePath)); +} + +UserContentExtensionStore::UserContentExtensionStore() + : UserContentExtensionStore(defaultStorePath()) +{ +} + +UserContentExtensionStore::UserContentExtensionStore(const WTF::String& storePath) + : m_storePath(storePath) + , m_compileQueue(WorkQueue::create("UserContentExtensionStore Compile Queue", WorkQueue::Type::Concurrent)) + , m_readQueue(WorkQueue::create("UserContentExtensionStore Read Queue")) + , m_removeQueue(WorkQueue::create("UserContentExtensionStore Remove Queue")) +{ +} + +UserContentExtensionStore::~UserContentExtensionStore() +{ +} + +static String constructedPath(const String& base, const String& identifier) +{ + return WebCore::pathByAppendingComponent(base, "ContentExtension-" + WebCore::encodeForFileName(identifier)); +} + +const size_t ContentExtensionFileHeaderSize = sizeof(uint32_t) + 4 * sizeof(uint64_t); +struct ContentExtensionMetaData { + uint32_t version { UserContentExtensionStore::CurrentContentExtensionFileVersion }; + uint64_t actionsSize { 0 }; + uint64_t filtersWithoutDomainsBytecodeSize { 0 }; + uint64_t filtersWithDomainBytecodeSize { 0 }; + uint64_t domainFiltersBytecodeSize { 0 }; + + size_t fileSize() const + { + return ContentExtensionFileHeaderSize + + actionsSize + + filtersWithoutDomainsBytecodeSize + + filtersWithDomainBytecodeSize + + domainFiltersBytecodeSize; + } +}; + +static Data encodeContentExtensionMetaData(const ContentExtensionMetaData& metaData) +{ + WTF::Persistence::Encoder encoder; + + encoder << metaData.version; + encoder << metaData.actionsSize; + encoder << metaData.filtersWithoutDomainsBytecodeSize; + encoder << metaData.filtersWithDomainBytecodeSize; + encoder << metaData.domainFiltersBytecodeSize; + + ASSERT(encoder.bufferSize() == ContentExtensionFileHeaderSize); + return Data(encoder.buffer(), encoder.bufferSize()); +} + +static bool decodeContentExtensionMetaData(ContentExtensionMetaData& metaData, const Data& fileData) +{ + bool success = false; + fileData.apply([&metaData, &success, &fileData](const uint8_t* data, size_t size) { + // The file data should be mapped into one continuous memory segment so the size + // passed to the applier should always equal the data size. + if (size != fileData.size()) + return false; + + WTF::Persistence::Decoder decoder(data, size); + if (!decoder.decode(metaData.version)) + return false; + if (!decoder.decode(metaData.actionsSize)) + return false; + if (!decoder.decode(metaData.filtersWithoutDomainsBytecodeSize)) + return false; + if (!decoder.decode(metaData.filtersWithDomainBytecodeSize)) + return false; + if (!decoder.decode(metaData.domainFiltersBytecodeSize)) + return false; + success = true; + return false; + }); + return success; +} + +static bool openAndMapContentExtension(const String& path, ContentExtensionMetaData& metaData, Data& fileData) +{ + fileData = mapFile(WebCore::fileSystemRepresentation(path).data()); + if (fileData.isNull()) + return false; + + if (!decodeContentExtensionMetaData(metaData, fileData)) + return false; + + return true; +} + +static bool writeDataToFile(const Data& fileData, WebCore::PlatformFileHandle fd) +{ + bool success = true; + fileData.apply([fd, &success](const uint8_t* data, size_t size) { + if (WebCore::writeToFile(fd, (const char*)data, size) == -1) { + success = false; + return false; + } + return true; + }); + + return success; +} + +static std::error_code compiledToFile(String&& json, const String& finalFilePath, ContentExtensionMetaData& metaData, Data& mappedData) +{ + using namespace WebCore::ContentExtensions; + + class CompilationClient final : public ContentExtensionCompilationClient { + public: + CompilationClient(WebCore::PlatformFileHandle fileHandle, ContentExtensionMetaData& metaData) + : m_fileHandle(fileHandle) + , m_metaData(metaData) + { + ASSERT(!metaData.actionsSize); + ASSERT(!metaData.filtersWithoutDomainsBytecodeSize); + ASSERT(!metaData.filtersWithDomainBytecodeSize); + ASSERT(!metaData.domainFiltersBytecodeSize); + } + + void writeFiltersWithoutDomainsBytecode(Vector<DFABytecode>&& bytecode) override + { + ASSERT(!m_filtersWithDomainBytecodeWritten); + ASSERT(!m_domainFiltersBytecodeWritten); + m_filtersWithoutDomainsBytecodeWritten += bytecode.size(); + writeToFile(Data(bytecode.data(), bytecode.size())); + } + + void writeFiltersWithDomainsBytecode(Vector<DFABytecode>&& bytecode) override + { + ASSERT(!m_domainFiltersBytecodeWritten); + m_filtersWithDomainBytecodeWritten += bytecode.size(); + writeToFile(Data(bytecode.data(), bytecode.size())); + } + + void writeDomainFiltersBytecode(Vector<DFABytecode>&& bytecode) override + { + m_domainFiltersBytecodeWritten += bytecode.size(); + writeToFile(Data(bytecode.data(), bytecode.size())); + } + + void writeActions(Vector<SerializedActionByte>&& actions) override + { + ASSERT(!m_filtersWithoutDomainsBytecodeWritten); + ASSERT(!m_filtersWithDomainBytecodeWritten); + ASSERT(!m_domainFiltersBytecodeWritten); + ASSERT(!m_actionsWritten); + m_actionsWritten += actions.size(); + writeToFile(Data(actions.data(), actions.size())); + } + + void finalize() override + { + m_metaData.actionsSize = m_actionsWritten; + m_metaData.filtersWithoutDomainsBytecodeSize = m_filtersWithoutDomainsBytecodeWritten; + m_metaData.filtersWithDomainBytecodeSize = m_filtersWithDomainBytecodeWritten; + m_metaData.domainFiltersBytecodeSize = m_domainFiltersBytecodeWritten; + + Data header = encodeContentExtensionMetaData(m_metaData); + if (!m_fileError && WebCore::seekFile(m_fileHandle, 0ll, WebCore::FileSeekOrigin::SeekFromBeginning) == -1) { + WebCore::closeFile(m_fileHandle); + m_fileError = true; + } + writeToFile(header); + } + + bool hadErrorWhileWritingToFile() { return m_fileError; } + + private: + void writeToFile(const Data& data) + { + if (!m_fileError && !writeDataToFile(data, m_fileHandle)) { + WebCore::closeFile(m_fileHandle); + m_fileError = true; + } + } + + WebCore::PlatformFileHandle m_fileHandle; + ContentExtensionMetaData& m_metaData; + size_t m_filtersWithoutDomainsBytecodeWritten { 0 }; + size_t m_filtersWithDomainBytecodeWritten { 0 }; + size_t m_domainFiltersBytecodeWritten { 0 }; + size_t m_actionsWritten { 0 }; + bool m_fileError { false }; + }; + + auto temporaryFileHandle = WebCore::invalidPlatformFileHandle; + String temporaryFilePath = WebCore::openTemporaryFile("ContentExtension", temporaryFileHandle); + if (temporaryFileHandle == WebCore::invalidPlatformFileHandle) + return UserContentExtensionStore::Error::CompileFailed; + + char invalidHeader[ContentExtensionFileHeaderSize]; + memset(invalidHeader, 0xFF, sizeof(invalidHeader)); + // This header will be rewritten in CompilationClient::finalize. + if (WebCore::writeToFile(temporaryFileHandle, invalidHeader, sizeof(invalidHeader)) == -1) { + WebCore::closeFile(temporaryFileHandle); + return UserContentExtensionStore::Error::CompileFailed; + } + + CompilationClient compilationClient(temporaryFileHandle, metaData); + + if (auto compilerError = compileRuleList(compilationClient, WTFMove(json))) { + WebCore::closeFile(temporaryFileHandle); + return compilerError; + } + if (compilationClient.hadErrorWhileWritingToFile()) { + WebCore::closeFile(temporaryFileHandle); + return UserContentExtensionStore::Error::CompileFailed; + } + + mappedData = adoptAndMapFile(temporaryFileHandle, 0, metaData.fileSize()); + if (mappedData.isNull()) + return UserContentExtensionStore::Error::CompileFailed; + + if (!WebCore::moveFile(temporaryFilePath, finalFilePath)) + return UserContentExtensionStore::Error::CompileFailed; + + return { }; +} + +static RefPtr<API::UserContentExtension> createExtension(const String& identifier, const ContentExtensionMetaData& metaData, const Data& fileData) +{ + auto sharedMemory = WebKit::SharedMemory::create(const_cast<uint8_t*>(fileData.data()), fileData.size(), WebKit::SharedMemory::Protection::ReadOnly); + auto compiledContentExtensionData = WebKit::WebCompiledContentExtensionData( + WTFMove(sharedMemory), + fileData, + ContentExtensionFileHeaderSize, + metaData.actionsSize, + ContentExtensionFileHeaderSize + + metaData.actionsSize, + metaData.filtersWithoutDomainsBytecodeSize, + ContentExtensionFileHeaderSize + + metaData.actionsSize + + metaData.filtersWithoutDomainsBytecodeSize, + metaData.filtersWithDomainBytecodeSize, + ContentExtensionFileHeaderSize + + metaData.actionsSize + + metaData.filtersWithoutDomainsBytecodeSize + + metaData.filtersWithDomainBytecodeSize, + metaData.domainFiltersBytecodeSize + ); + auto compiledContentExtension = WebKit::WebCompiledContentExtension::create(WTFMove(compiledContentExtensionData)); + return API::UserContentExtension::create(identifier, WTFMove(compiledContentExtension)); +} + +void UserContentExtensionStore::lookupContentExtension(const WTF::String& identifier, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)> completionHandler) +{ + m_readQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable { + auto path = constructedPath(storePath, identifier); + + ContentExtensionMetaData metaData; + Data fileData; + if (!openAndMapContentExtension(path, metaData, fileData)) { + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] { + completionHandler(nullptr, Error::LookupFailed); + }); + return; + } + + if (metaData.version != UserContentExtensionStore::CurrentContentExtensionFileVersion) { + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] { + completionHandler(nullptr, Error::VersionMismatch); + }); + return; + } + + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] { + RefPtr<API::UserContentExtension> userContentExtension = createExtension(identifier, metaData, fileData); + completionHandler(userContentExtension, { }); + }); + }); +} + +void UserContentExtensionStore::compileContentExtension(const WTF::String& identifier, WTF::String&& json, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)> completionHandler) +{ + m_compileQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), json = json.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)] () mutable { + auto path = constructedPath(storePath, identifier); + + ContentExtensionMetaData metaData; + Data fileData; + auto error = compiledToFile(WTFMove(json), path, metaData, fileData); + if (error) { + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), error = WTFMove(error), completionHandler = WTFMove(completionHandler)] { + completionHandler(nullptr, error); + }); + return; + } + + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), identifier = WTFMove(identifier), fileData = WTFMove(fileData), metaData = WTFMove(metaData), completionHandler = WTFMove(completionHandler)] { + RefPtr<API::UserContentExtension> userContentExtension = createExtension(identifier, metaData, fileData); + completionHandler(userContentExtension, { }); + }); + }); +} + +void UserContentExtensionStore::removeContentExtension(const WTF::String& identifier, std::function<void(std::error_code)> completionHandler) +{ + m_removeQueue->dispatch([protectedThis = makeRef(*this), identifier = identifier.isolatedCopy(), storePath = m_storePath.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable { + auto path = constructedPath(storePath, identifier); + + if (!WebCore::deleteFile(path)) { + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] { + completionHandler(Error::RemoveFailed); + }); + return; + } + + RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis), completionHandler = WTFMove(completionHandler)] { + completionHandler({ }); + }); + }); +} + +void UserContentExtensionStore::synchronousRemoveAllContentExtensions() +{ + for (const auto& path : WebCore::listDirectory(m_storePath, "*")) + WebCore::deleteFile(path); +} + +void UserContentExtensionStore::invalidateContentExtensionVersion(const WTF::String& identifier) +{ + auto file = WebCore::openFile(constructedPath(m_storePath, identifier), WebCore::OpenForWrite); + if (file == WebCore::invalidPlatformFileHandle) + return; + ContentExtensionMetaData invalidHeader = {0, 0, 0, 0, 0}; + auto bytesWritten = WebCore::writeToFile(file, reinterpret_cast<const char*>(&invalidHeader), sizeof(invalidHeader)); + ASSERT_UNUSED(bytesWritten, bytesWritten == sizeof(invalidHeader)); + WebCore::closeFile(file); +} + +const std::error_category& userContentExtensionStoreErrorCategory() +{ + class UserContentExtensionStoreErrorCategory : public std::error_category { + const char* name() const noexcept override + { + return "user content extension store"; + } + + std::string message(int errorCode) const override + { + switch (static_cast<UserContentExtensionStore::Error>(errorCode)) { + case UserContentExtensionStore::Error::LookupFailed: + return "Unspecified error during lookup."; + case UserContentExtensionStore::Error::VersionMismatch: + return "Version of file does not match version of interpreter."; + case UserContentExtensionStore::Error::CompileFailed: + return "Unspecified error during compile."; + case UserContentExtensionStore::Error::RemoveFailed: + return "Unspecified error during remove."; + } + + return std::string(); + } + }; + + static NeverDestroyed<UserContentExtensionStoreErrorCategory> contentExtensionErrorCategory; + return contentExtensionErrorCategory; +} + +} // namespace API + +#endif // ENABLE(CONTENT_EXTENSIONS) diff --git a/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.h b/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.h new file mode 100644 index 000000000..caf0f6e62 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentExtensionStore.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUserContentExtensionStore_h +#define APIUserContentExtensionStore_h + +#if ENABLE(CONTENT_EXTENSIONS) + +#include "APIObject.h" +#include <system_error> +#include <wtf/text/WTFString.h> + +namespace WTF { +class WorkQueue; +} + +namespace API { + +class UserContentExtension; + +class UserContentExtensionStore final : public ObjectImpl<Object::Type::UserContentExtensionStore> { +public: + enum class Error { + LookupFailed = 1, + VersionMismatch, + CompileFailed, + RemoveFailed + }; + + // This should be incremented every time a functional change is made to the bytecode, file format, etc. + // to prevent crashing while loading old data. + const static uint32_t CurrentContentExtensionFileVersion = 7; + + static UserContentExtensionStore& defaultStore(); + static Ref<UserContentExtensionStore> storeWithPath(const WTF::String& storePath); + + explicit UserContentExtensionStore(); + explicit UserContentExtensionStore(const WTF::String& storePath); + virtual ~UserContentExtensionStore(); + + void compileContentExtension(const WTF::String& identifier, WTF::String&& json, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)>); + void lookupContentExtension(const WTF::String& identifier, std::function<void(RefPtr<API::UserContentExtension>, std::error_code)>); + void removeContentExtension(const WTF::String& identifier, std::function<void(std::error_code)>); + + // For testing only. + void synchronousRemoveAllContentExtensions(); + void invalidateContentExtensionVersion(const WTF::String& identifier); + +private: + WTF::String defaultStorePath(); + + const WTF::String m_storePath; + Ref<WTF::WorkQueue> m_compileQueue; + Ref<WTF::WorkQueue> m_readQueue; + Ref<WTF::WorkQueue> m_removeQueue; +}; + +const std::error_category& userContentExtensionStoreErrorCategory(); + +inline std::error_code make_error_code(UserContentExtensionStore::Error error) +{ + return { static_cast<int>(error), userContentExtensionStoreErrorCategory() }; +} + +} // namespace API + +namespace std { + template<> struct is_error_code_enum<API::UserContentExtensionStore::Error> : public true_type { }; +} + +#endif // ENABLE(CONTENT_EXTENSIONS) +#endif // APIUserContentExtensionStore_h diff --git a/Source/WebKit2/UIProcess/API/APIUserContentWorld.cpp b/Source/WebKit2/UIProcess/API/APIUserContentWorld.cpp new file mode 100644 index 000000000..4dadfbfbd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentWorld.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIUserContentWorld.h" + +namespace API { + +static const uint64_t normalWorldIdentifer = 1; + +static uint64_t generateIdentifier() +{ + static uint64_t identifier = normalWorldIdentifer; + + return ++identifier; +} + +Ref<UserContentWorld> UserContentWorld::worldWithName(const WTF::String& name) +{ + return adoptRef(*new UserContentWorld(name)); +} + +UserContentWorld& UserContentWorld::normalWorld() +{ + static UserContentWorld* world = new UserContentWorld(ForNormalWorldOnly::NormalWorld); + return *world; +} + +UserContentWorld::UserContentWorld(const WTF::String& name) + : m_identifier(generateIdentifier()) + , m_name(name) +{ +} + +UserContentWorld::UserContentWorld(ForNormalWorldOnly) + : m_identifier(normalWorldIdentifer) +{ +} + +UserContentWorld::~UserContentWorld() +{ +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIUserContentWorld.h b/Source/WebKit2/UIProcess/API/APIUserContentWorld.h new file mode 100644 index 000000000..840fe1c30 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserContentWorld.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUserContentWorld_h +#define APIUserContentWorld_h + +#include "APIObject.h" +#include <wtf/text/WTFString.h> + +namespace API { + +class UserContentWorld final : public API::ObjectImpl<API::Object::Type::UserContentWorld> { +public: + static Ref<UserContentWorld> worldWithName(const WTF::String&); + static UserContentWorld& normalWorld(); + + virtual ~UserContentWorld(); + + const WTF::String& name() const { return m_name; } + uint64_t identifier() const { return m_identifier; } + +private: + UserContentWorld(const WTF::String&); + + enum class ForNormalWorldOnly { NormalWorld }; + UserContentWorld(ForNormalWorldOnly); + + uint64_t m_identifier; + WTF::String m_name; +}; + +} // namespace API + +#endif // APIUserContentWorld_h diff --git a/Source/WebKit2/UIProcess/API/APIUserInitiatedAction.h b/Source/WebKit2/UIProcess/API/APIUserInitiatedAction.h new file mode 100644 index 000000000..5aba76dbb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserInitiatedAction.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIObject.h" + +namespace API { + +class UserInitiatedAction final : public API::ObjectImpl<API::Object::Type::UserInitiatedAction> { +public: + static Ref<UserInitiatedAction> create() + { + return adoptRef(*new UserInitiatedAction); + } + + virtual ~UserInitiatedAction() + { + } + + void setConsumed() { m_consumed = true; } + bool consumed() const { return m_consumed; } + +private: + UserInitiatedAction() + { + } + + bool m_consumed = false; +}; + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/C/WKNetworkInfo.cpp b/Source/WebKit2/UIProcess/API/APIUserScript.cpp index 73fd05e53..845ab57ea 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNetworkInfo.cpp +++ b/Source/WebKit2/UIProcess/API/APIUserScript.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,32 +24,35 @@ */ #include "config.h" -#include "WKNetworkInfo.h" +#include "APIUserScript.h" -#if ENABLE(NETWORK_INFO) -#include "WKAPICast.h" -#include "WebNetworkInfo.h" +#include <wtf/text/StringBuilder.h> -using namespace WebKit; -#endif +namespace API { -WKTypeID WKNetworkInfoGetTypeID() +static uint64_t generateIdentifier() { -#if ENABLE(NETWORK_INFO) - return toAPI(WebNetworkInfo::APIType); -#else - return 0; -#endif + static uint64_t identifier; + + return ++identifier; } -WKNetworkInfoRef WKNetworkInfoCreate(double bandwidth, bool isMetered) +WebCore::URL UserScript::generateUniqueURL() { -#if ENABLE(NETWORK_INFO) - RefPtr<WebNetworkInfo> networkInfo = WebNetworkInfo::create(bandwidth, isMetered); - return toAPI(networkInfo.release().leakRef()); -#else - UNUSED_PARAM(bandwidth); - UNUSED_PARAM(isMetered); - return 0; -#endif + static uint64_t identifier; + + StringBuilder urlStringBuilder; + urlStringBuilder.appendLiteral("user-script:"); + urlStringBuilder.appendNumber(++identifier); + return { { }, urlStringBuilder.toString() }; } + +UserScript::UserScript(WebCore::UserScript userScript, API::UserContentWorld& world) + : m_identifier(generateIdentifier()) + , m_userScript(userScript) + , m_world(world) +{ +} + + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIUserScript.h b/Source/WebKit2/UIProcess/API/APIUserScript.h new file mode 100644 index 000000000..758350b9b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserScript.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUserScript_h +#define APIUserScript_h + +#include "APIObject.h" +#include "APIUserContentWorld.h" +#include <WebCore/UserScript.h> + +namespace API { + +class UserScript final : public ObjectImpl<Object::Type::UserScript> { +public: + static WebCore::URL generateUniqueURL(); + + static Ref<UserScript> create(WebCore::UserScript userScript, API::UserContentWorld& world) + { + return adoptRef(*new UserScript(WTFMove(userScript), world)); + } + + UserScript(WebCore::UserScript, API::UserContentWorld&); + + uint64_t identifier() const { return m_identifier; } + + const WebCore::UserScript& userScript() const { return m_userScript; } + + UserContentWorld& userContentWorld() { return m_world; } + const UserContentWorld& userContentWorld() const { return m_world; } + +private: + uint64_t m_identifier; + WebCore::UserScript m_userScript; + Ref<UserContentWorld> m_world; +}; + +} // namespace API + +#endif // APIUserScript_h diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKSoupCustomProtocolRequestManager.cpp b/Source/WebKit2/UIProcess/API/APIUserStyleSheet.cpp index 95b1f8124..28e800955 100644 --- a/Source/WebKit2/UIProcess/API/C/soup/WKSoupCustomProtocolRequestManager.cpp +++ b/Source/WebKit2/UIProcess/API/APIUserStyleSheet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Igalia S.L. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,28 +24,34 @@ */ #include "config.h" -#include "WKSoupCustomProtocolRequestManager.h" +#include "APIUserStyleSheet.h" -#include "WKAPICast.h" -#include "WebSoupCustomProtocolRequestManager.h" +#include <wtf/text/StringBuilder.h> -using namespace WebKit; +namespace API { -WKTypeID WKSoupCustomProtocolRequestManagerGetTypeID() +static uint64_t generateIdentifier() { -#if ENABLE(CUSTOM_PROTOCOLS) - return toAPI(WebSoupCustomProtocolRequestManager::APIType); -#else - return 0; -#endif + static uint64_t identifier; + + return ++identifier; +} + +WebCore::URL UserStyleSheet::generateUniqueURL() +{ + static uint64_t identifier; + + StringBuilder urlStringBuilder; + urlStringBuilder.appendLiteral("user-style-sheet:"); + urlStringBuilder.appendNumber(++identifier); + return { { }, urlStringBuilder.toString() }; } -void WKSoupCustomProtocolRequestManagerSetClient(WKSoupCustomProtocolRequestManagerRef soupRequestManagerRef, const WKSoupCustomProtocolRequestManagerClientBase* wkClient) +UserStyleSheet::UserStyleSheet(WebCore::UserStyleSheet userStyleSheet, API::UserContentWorld& world) + : m_identifier(generateIdentifier()) + , m_userStyleSheet(userStyleSheet) + , m_world(world) { -#if ENABLE(CUSTOM_PROTOCOLS) - toImpl(soupRequestManagerRef)->initializeClient(wkClient); -#else - UNUSED_PARAM(soupRequestManagerRef); - UNUSED_PARAM(wkClient); -#endif } + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/APIUserStyleSheet.h b/Source/WebKit2/UIProcess/API/APIUserStyleSheet.h new file mode 100644 index 000000000..fe4f49bb3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIUserStyleSheet.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIUserStyleSheet_h +#define APIUserStyleSheet_h + +#include "APIObject.h" +#include "APIUserContentWorld.h" +#include <WebCore/UserStyleSheet.h> + +namespace API { + +class UserStyleSheet final : public ObjectImpl<Object::Type::UserStyleSheet> { +public: + static WebCore::URL generateUniqueURL(); + + static Ref<UserStyleSheet> create(WebCore::UserStyleSheet userStyleSheet, API::UserContentWorld& world) + { + return adoptRef(*new UserStyleSheet(WTFMove(userStyleSheet), world)); + } + + UserStyleSheet(WebCore::UserStyleSheet, API::UserContentWorld&); + + uint64_t identifier() const { return m_identifier; } + + const WebCore::UserStyleSheet& userStyleSheet() const { return m_userStyleSheet; } + + UserContentWorld& userContentWorld() { return m_world; } + const UserContentWorld& userContentWorld() const { return m_world; } + +private: + uint64_t m_identifier; + WebCore::UserStyleSheet m_userStyleSheet; + Ref<UserContentWorld> m_world; +}; + +} // namespace API + +#endif // APIUserStyleSheet_h diff --git a/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.cpp b/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.cpp new file mode 100644 index 000000000..d4885904c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWebsiteDataRecord.h" + +namespace API { + +Ref<WebsiteDataRecord> WebsiteDataRecord::create(WebKit::WebsiteDataRecord&& websiteDataRecord) +{ + return adoptRef(*new WebsiteDataRecord(WTFMove(websiteDataRecord))); +} + +WebsiteDataRecord::WebsiteDataRecord(WebKit::WebsiteDataRecord&& websiteDataRecord) + : m_websiteDataRecord(WTFMove(websiteDataRecord)) +{ +} + +WebsiteDataRecord::~WebsiteDataRecord() +{ +} + +} diff --git a/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.h b/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.h new file mode 100644 index 000000000..0ccdb2190 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWebsiteDataRecord.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIWebsiteDataRecord_h +#define APIWebsiteDataRecord_h + +#include "APIObject.h" +#include "WebsiteDataRecord.h" + +namespace API { + +class WebsiteDataRecord final : public ObjectImpl<Object::Type::WebsiteDataRecord> { +public: + static Ref<WebsiteDataRecord> create(WebKit::WebsiteDataRecord&&); + virtual ~WebsiteDataRecord(); + + const WebKit::WebsiteDataRecord& websiteDataRecord() const { return m_websiteDataRecord; } + +private: + explicit WebsiteDataRecord(WebKit::WebsiteDataRecord&&); + + const WebKit::WebsiteDataRecord m_websiteDataRecord; +}; + +} + +#endif // APIWebsiteDataRecord_h diff --git a/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp b/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp new file mode 100644 index 000000000..5c78ccd7a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWebsiteDataStore.h" + +#include "WebKit2Initialize.h" +#include "WebsiteDataStore.h" + +namespace API { + +RefPtr<WebsiteDataStore> WebsiteDataStore::defaultDataStore() +{ + WebKit::InitializeWebKit2(); + + static WebsiteDataStore* defaultDataStore = adoptRef(new WebsiteDataStore(defaultDataStoreConfiguration())).leakRef(); + + return defaultDataStore; +} + +Ref<WebsiteDataStore> WebsiteDataStore::createNonPersistentDataStore() +{ + return adoptRef(*new WebsiteDataStore); +} + +Ref<WebsiteDataStore> WebsiteDataStore::create(WebKit::WebsiteDataStore::Configuration configuration) +{ + return adoptRef(*new WebsiteDataStore(WTFMove(configuration))); +} + +WebsiteDataStore::WebsiteDataStore() + : m_websiteDataStore(WebKit::WebsiteDataStore::createNonPersistent()) +{ +} + +WebsiteDataStore::WebsiteDataStore(WebKit::WebsiteDataStore::Configuration configuration) + : m_websiteDataStore(WebKit::WebsiteDataStore::create(WTFMove(configuration))) +{ +} + +WebsiteDataStore::~WebsiteDataStore() +{ +} + +bool WebsiteDataStore::isPersistent() +{ + return m_websiteDataStore->isPersistent(); +} + +bool WebsiteDataStore::resourceLoadStatisticsEnabled() const +{ + return m_websiteDataStore->resourceLoadStatisticsEnabled(); +} + +void WebsiteDataStore::setResourceLoadStatisticsEnabled(bool enabled) +{ + m_websiteDataStore->setResourceLoadStatisticsEnabled(enabled); +} + +void WebsiteDataStore::registerSharedResourceLoadObserver() +{ + m_websiteDataStore->registerSharedResourceLoadObserver(); +} + +#if !PLATFORM(COCOA) && !PLATFORM(GTK) +WebKit::WebsiteDataStore::Configuration WebsiteDataStore::defaultDataStoreConfiguration() +{ + // FIXME: Fill everything in. + WebKit::WebsiteDataStore::Configuration configuration; + + return configuration; +} + +String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String&) +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultLocalStorageDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultWebSQLDatabaseDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultNetworkCacheDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultApplicationCacheDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultMediaKeysStorageDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultIndexedDBDatabaseDirectory() +{ + // FIXME: Implement. + return String(); +} + +String WebsiteDataStore::defaultResourceLoadStatisticsDirectory() +{ + // FIXME: Implement. + return String(); +} + +#endif + +#if !PLATFORM(COCOA) +String WebsiteDataStore::defaultMediaCacheDirectory() +{ + // FIXME: Implement. https://bugs.webkit.org/show_bug.cgi?id=156369 and https://bugs.webkit.org/show_bug.cgi?id=156370 + return String(); +} +#endif + +} diff --git a/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h b/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h new file mode 100644 index 000000000..0daaf85a3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIWebsiteDataStore_h +#define APIWebsiteDataStore_h + +#include "APIObject.h" +#include "WebsiteDataStore.h" +#include <WebCore/SessionID.h> +#include <wtf/text/WTFString.h> + +namespace API { + +class WebsiteDataStore final : public ObjectImpl<Object::Type::WebsiteDataStore> { +public: + static RefPtr<WebsiteDataStore> defaultDataStore(); + static Ref<WebsiteDataStore> createNonPersistentDataStore(); + static Ref<WebsiteDataStore> create(WebKit::WebsiteDataStore::Configuration); + virtual ~WebsiteDataStore(); + + bool isPersistent(); + + bool resourceLoadStatisticsEnabled() const; + void setResourceLoadStatisticsEnabled(bool); + void registerSharedResourceLoadObserver(); + + WebKit::WebsiteDataStore& websiteDataStore() { return *m_websiteDataStore; } + + static String defaultApplicationCacheDirectory(); + static String defaultNetworkCacheDirectory(); + static String defaultMediaCacheDirectory(); + + static String defaultIndexedDBDatabaseDirectory(); + static String defaultLocalStorageDirectory(); + static String defaultMediaKeysStorageDirectory(); + static String defaultWebSQLDatabaseDirectory(); + static String defaultResourceLoadStatisticsDirectory(); + +private: + WebsiteDataStore(WebKit::WebsiteDataStore::Configuration); + WebsiteDataStore(); + + static String tempDirectoryFileSystemRepresentation(const String& directoryName); + static String cacheDirectoryFileSystemRepresentation(const String& directoryName); + static String websiteDataDirectoryFileSystemRepresentation(const String& directoryName); + + static WebKit::WebsiteDataStore::Configuration defaultDataStoreConfiguration(); + + RefPtr<WebKit::WebsiteDataStore> m_websiteDataStore; +}; + +} + +#endif // APIWebsiteDataStore_h diff --git a/Source/WebKit2/UIProcess/API/APIWebsitePolicies.cpp b/Source/WebKit2/UIProcess/API/APIWebsitePolicies.cpp new file mode 100644 index 000000000..d1c6f28ac --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWebsitePolicies.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWebsitePolicies.h" + +namespace API { + +Ref<WebsitePolicies> WebsitePolicies::create() +{ + return adoptRef(*new WebsitePolicies()); +} + +WebsitePolicies::WebsitePolicies() +{ +} + +WebsitePolicies::~WebsitePolicies() +{ +} + +} diff --git a/Source/WebKit2/UIProcess/APISession.h b/Source/WebKit2/UIProcess/API/APIWebsitePolicies.h index bd604b2d5..ca74f8192 100644 --- a/Source/WebKit2/UIProcess/APISession.h +++ b/Source/WebKit2/UIProcess/API/APIWebsitePolicies.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,32 +23,29 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef APISession_h -#define APISession_h +#pragma once #include "APIObject.h" -#include "SessionTracker.h" -#include <wtf/PassRefPtr.h> +#include "WebsitePolicies.h" namespace API { -class Session : public API::ObjectImpl<API::Object::Type::Session> { +class WebsitePolicies final : public ObjectImpl<Object::Type::WebsitePolicies> { public: - // FIXME: We can create sessions on demand, because we hardcode the fact that all sessions but the default one are ephemeral. We'll need to create them explicitly once sessions have more configuration options. - static PassRefPtr<Session> create(bool isEphemeral); - static Session& defaultSession(); - static Session& legacyPrivateSession(); - bool isEphemeral() const; - uint64_t getID() const; - virtual ~Session(); + static Ref<WebsitePolicies> create(); + explicit WebsitePolicies(); + virtual ~WebsitePolicies(); + bool contentBlockersEnabled() const { return m_websitePolicies.contentBlockersEnabled; } + void setContentBlockersEnabled(bool enabled) { m_websitePolicies.contentBlockersEnabled = enabled; } + + WebKit::WebsiteAutoplayPolicy autoplayPolicy() const { return m_websitePolicies.autoplayPolicy; } + void setAutoplayPolicy(WebKit::WebsiteAutoplayPolicy policy) { m_websitePolicies.autoplayPolicy = policy; } + + const WebKit::WebsitePolicies& websitePolicies() { return m_websitePolicies; } + private: - explicit Session(bool isEphemeral); - Session(bool isEphemeral, uint64_t sessionID); - bool m_isEphemeral; - uint64_t m_sessionID; + WebKit::WebsitePolicies m_websitePolicies; }; -} // namespace API - -#endif // APISession_h +} diff --git a/Source/WebKit2/UIProcess/API/APIWindowFeatures.cpp b/Source/WebKit2/UIProcess/API/APIWindowFeatures.cpp new file mode 100644 index 000000000..f6fa0dc31 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWindowFeatures.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWindowFeatures.h" + +namespace API { + +Ref<WindowFeatures> WindowFeatures::create(const WebCore::WindowFeatures& windowFeatures) +{ + return adoptRef(*new WindowFeatures(windowFeatures)); +} + +WindowFeatures::WindowFeatures(const WebCore::WindowFeatures& windowFeatures) + : m_windowFeatures(windowFeatures) +{ +} + +WindowFeatures::~WindowFeatures() +{ +} + +} diff --git a/Source/WebKit2/UIProcess/API/APIWindowFeatures.h b/Source/WebKit2/UIProcess/API/APIWindowFeatures.h new file mode 100644 index 000000000..ccedf79fd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/APIWindowFeatures.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIWindowFeatures_h +#define APIWindowFeatures_h + +#include "APIObject.h" +#include <WebCore/WindowFeatures.h> + +namespace API { + +class WindowFeatures final : public ObjectImpl<Object::Type::WindowFeatures> { +public: + static Ref<WindowFeatures> create(const WebCore::WindowFeatures&); + virtual ~WindowFeatures(); + + const WebCore::WindowFeatures& windowFeatures() const { return m_windowFeatures; } + +private: + explicit WindowFeatures(const WebCore::WindowFeatures&); + + const WebCore::WindowFeatures m_windowFeatures; +}; + +} + +#endif // APIWindowFeatures_h diff --git a/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.cpp b/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.cpp new file mode 100644 index 000000000..fab02b5e3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#if USE(COORDINATED_GRAPHICS) + +#include "WKView.h" + +#include "APIPageConfiguration.h" +#include "WKAPICast.h" +#include "WebView.h" + +using namespace WebCore; +using namespace WebKit; + +WKViewRef WKViewCreate(WKPageConfigurationRef pageConfiguration) +{ + auto webView = WebView::create(*toImpl(pageConfiguration)); + return toAPI(&webView.leakRef()); +} + +WKSize WKViewGetSize(WKViewRef viewRef) +{ + return toAPI(toImpl(viewRef)->size()); +} + +void WKViewSetSize(WKViewRef viewRef, WKSize size) +{ + toImpl(viewRef)->setSize(toIntSize(size)); +} + +void WKViewSetViewClient(WKViewRef viewRef, const WKViewClientBase* client) +{ + toImpl(viewRef)->initializeClient(client); +} + +bool WKViewIsActive(WKViewRef viewRef) +{ + return toImpl(viewRef)->isActive(); +} + +void WKViewSetIsActive(WKViewRef viewRef, bool isActive) +{ + toImpl(viewRef)->setActive(isActive); +} + +bool WKViewIsFocused(WKViewRef viewRef) +{ + return toImpl(viewRef)->isFocused(); +} + +void WKViewSetIsFocused(WKViewRef viewRef, bool isFocused) +{ + toImpl(viewRef)->setFocused(isFocused); +} + +bool WKViewIsVisible(WKViewRef viewRef) +{ + return toImpl(viewRef)->isVisible(); +} + +void WKViewSetIsVisible(WKViewRef viewRef, bool isVisible) +{ + toImpl(viewRef)->setVisible(isVisible); +} + +float WKViewGetContentScaleFactor(WKViewRef viewRef) +{ + return toImpl(viewRef)->contentScaleFactor(); +} + +void WKViewSetContentScaleFactor(WKViewRef viewRef, float scale) +{ + toImpl(viewRef)->setContentScaleFactor(scale); +} + +WKPoint WKViewGetContentPosition(WKViewRef viewRef) +{ + const WebCore::FloatPoint& result = toImpl(viewRef)->contentPosition(); + return WKPointMake(result.x(), result.y()); +} + +void WKViewSetContentPosition(WKViewRef viewRef, WKPoint position) +{ + toImpl(viewRef)->setContentPosition(WebCore::FloatPoint(position.x, position.y)); +} + +void WKViewSetUserViewportTranslation(WKViewRef viewRef, double tx, double ty) +{ + toImpl(viewRef)->setUserViewportTranslation(tx, ty); +} + +WKPoint WKViewUserViewportToContents(WKViewRef viewRef, WKPoint point) +{ + const WebCore::IntPoint& result = toImpl(viewRef)->userViewportToContents(toIntPoint(point)); + return WKPointMake(result.x(), result.y()); +} + +WKPoint WKViewUserViewportToScene(WKViewRef viewRef, WKPoint point) +{ + WebCore::IntPoint result = toImpl(viewRef)->userViewportToScene(toIntPoint(point)); + return WKPointMake(result.x(), result.y()); +} + +WKPoint WKViewContentsToUserViewport(WKViewRef viewRef, WKPoint point) +{ + WebCore::IntPoint result = toImpl(viewRef)->contentsToUserViewport(toIntPoint(point)); + return WKPointMake(result.x(), result.y()); +} + +void WKViewPaintToCurrentGLContext(WKViewRef viewRef) +{ + toImpl(viewRef)->paintToCurrentGLContext(); +} + +WKPageRef WKViewGetPage(WKViewRef viewRef) +{ + return toImpl(viewRef)->pageRef(); +} + +void WKViewSetDrawsBackground(WKViewRef viewRef, bool flag) +{ + toImpl(viewRef)->setDrawsBackground(flag); +} + +bool WKViewGetDrawsBackground(WKViewRef viewRef) +{ + return toImpl(viewRef)->drawsBackground(); +} + +void WKViewSetDrawsTransparentBackground(WKViewRef viewRef, bool flag) +{ + toImpl(viewRef)->setDrawsTransparentBackground(flag); +} + +bool WKViewGetDrawsTransparentBackground(WKViewRef viewRef) +{ + return toImpl(viewRef)->drawsTransparentBackground(); +} + +void WKViewSuspendActiveDOMObjectsAndAnimations(WKViewRef viewRef) +{ + toImpl(viewRef)->suspendActiveDOMObjectsAndAnimations(); +} + +void WKViewResumeActiveDOMObjectsAndAnimations(WKViewRef viewRef) +{ + toImpl(viewRef)->resumeActiveDOMObjectsAndAnimations(); +} + +bool WKViewExitFullScreen(WKViewRef viewRef) +{ +#if ENABLE(FULLSCREEN_API) + return toImpl(viewRef)->requestExitFullScreen(); +#else + UNUSED_PARAM(viewRef); + return false; +#endif +} + +void WKViewSetOpacity(WKViewRef view, double opacity) +{ + toImpl(view)->setOpacity(opacity); +} + +double WKViewOpacity(WKViewRef view) +{ + return toImpl(view)->opacity(); +} + +void WKViewFindZoomableAreaForRect(WKViewRef, WKRect) +{ +} + +WKSize WKViewGetContentsSize(WKViewRef viewRef) +{ + const WebCore::IntSize& size = toImpl(viewRef)->contentsSize(); + return WKSizeMake(size.width(), size.height()); +} + +#endif // USE(COORDINATED_GRAPHICS) diff --git a/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.h b/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.h new file mode 100644 index 000000000..729b26fc3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/CoordinatedGraphics/WKView.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WKView_h +#define WKView_h + +#include <WebKit/WKBase.h> +#include <WebKit/WKGeometry.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*WKViewCallback)(WKViewRef view, const void* clientInfo); +typedef void (*WKViewViewNeedsDisplayCallback)(WKViewRef view, WKRect area, const void* clientInfo); +typedef void (*WKViewPageDidChangeContentsSizeCallback)(WKViewRef view, WKSize size, const void* clientInfo); +typedef void (*WKViewWebProcessCrashedCallback)(WKViewRef view, WKURLRef url, const void* clientInfo); +typedef void (*WKViewPageDidChangeContentsPositionCallback)(WKViewRef view, WKPoint position, const void* clientInfo); +typedef void (*WKViewPageDidRenderFrameCallback)(WKViewRef view, WKSize contentsSize, WKRect coveredRect, const void* clientInfo); +typedef void (*WKViewPageDidChangeViewportAttributesCallback)(WKViewRef view, WKViewportAttributesRef, const void* clientInfo); +typedef void (*WKViewPageDidChangeTooltipCallback)(WKViewRef view, WKStringRef newTooltip, const void* clientInfo); +typedef void (*WKViewDidFindZoomableAreaCallback)(WKViewRef view, WKPoint point, WKRect area, const void* clientInfo); +typedef void (*WKViewDoneWithTouchEventCallback)(WKViewRef view, WKTouchEventRef touchEvent, bool wasEventHandled, const void* clientInfo); + +typedef struct WKViewClientBase { + int version; + const void* clientInfo; +} WKViewClientBase; + +typedef struct WKViewClientV0 { + WKViewClientBase base; + // Version 0 + WKViewViewNeedsDisplayCallback viewNeedsDisplay; + WKViewPageDidChangeContentsSizeCallback didChangeContentsSize; + WKViewWebProcessCrashedCallback webProcessCrashed; + WKViewCallback webProcessDidRelaunch; + WKViewPageDidChangeContentsPositionCallback didChangeContentsPosition; + WKViewPageDidRenderFrameCallback didRenderFrame; + WKViewCallback didCompletePageTransition; + WKViewPageDidChangeViewportAttributesCallback didChangeViewportAttributes; + WKViewPageDidChangeTooltipCallback didChangeTooltip; + WKViewDidFindZoomableAreaCallback didFindZoomableArea; + WKViewDoneWithTouchEventCallback doneWithTouchEvent; +} WKViewClientV0; + +WK_EXPORT WKViewRef WKViewCreate(WKPageConfigurationRef pageConfiguration); + +WK_EXPORT WKSize WKViewGetSize(WKViewRef); +WK_EXPORT void WKViewSetSize(WKViewRef, WKSize size); + +WK_EXPORT void WKViewSetViewClient(WKViewRef, const WKViewClientBase*); + +WK_EXPORT bool WKViewIsActive(WKViewRef); +WK_EXPORT void WKViewSetIsActive(WKViewRef, bool); + +WK_EXPORT bool WKViewIsFocused(WKViewRef); +WK_EXPORT void WKViewSetIsFocused(WKViewRef, bool); + +WK_EXPORT bool WKViewIsVisible(WKViewRef); +WK_EXPORT void WKViewSetIsVisible(WKViewRef, bool); + +WK_EXPORT float WKViewGetContentScaleFactor(WKViewRef); +WK_EXPORT void WKViewSetContentScaleFactor(WKViewRef, float); + +WK_EXPORT WKPoint WKViewGetContentPosition(WKViewRef); +WK_EXPORT void WKViewSetContentPosition(WKViewRef, WKPoint); + +WK_EXPORT void WKViewSetUserViewportTranslation(WKViewRef, double tx, double ty); +WK_EXPORT WKPoint WKViewUserViewportToContents(WKViewRef, WKPoint); +WK_EXPORT WKPoint WKViewUserViewportToScene(WKViewRef, WKPoint); +WK_EXPORT WKPoint WKViewContentsToUserViewport(WKViewRef, WKPoint); + +WK_EXPORT void WKViewPaintToCurrentGLContext(WKViewRef); + +WK_EXPORT WKPageRef WKViewGetPage(WKViewRef); + +WK_EXPORT void WKViewSetDrawsBackground(WKViewRef, bool); +WK_EXPORT bool WKViewGetDrawsBackground(WKViewRef); + +WK_EXPORT void WKViewSetDrawsTransparentBackground(WKViewRef, bool); +WK_EXPORT bool WKViewGetDrawsTransparentBackground(WKViewRef); + +WK_EXPORT void WKViewSuspendActiveDOMObjectsAndAnimations(WKViewRef); +WK_EXPORT void WKViewResumeActiveDOMObjectsAndAnimations(WKViewRef); + +WK_EXPORT bool WKViewExitFullScreen(WKViewRef); + +WK_EXPORT void WKViewSetOpacity(WKViewRef view, double opacity); +WK_EXPORT double WKViewOpacity(WKViewRef view); + +WK_EXPORT void WKViewFindZoomableAreaForRect(WKViewRef, WKRect); + +WK_EXPORT WKSize WKViewGetContentsSize(WKViewRef); + +#ifdef __cplusplus +} +#endif + +#endif /* WKView_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h index 71569bbb5..392a342b4 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,26 +32,43 @@ #include "HTTPCookieAcceptPolicy.h" #include "InjectedBundleHitTestResultMediaType.h" #include "PluginModuleInfo.h" -#include "ProcessModel.h" #include "ResourceCachesToClear.h" #include "WKBundleHitTestResult.h" #include "WKContext.h" #include "WKCookieManager.h" #include "WKCredentialTypes.h" #include "WKPage.h" -#include "WKPreferencesPrivate.h" #include "WKPreferencesRef.h" +#include "WKPreferencesRefPrivate.h" #include "WKProtectionSpaceTypes.h" #include "WKResourceCacheManager.h" #include "WKSharedAPICast.h" #include "WebGrammarDetail.h" #include <WebCore/Credential.h> #include <WebCore/FrameLoaderTypes.h> +#include <WebCore/PluginData.h> #include <WebCore/ProtectionSpace.h> #include <WebCore/Settings.h> namespace API { +class ExperimentalFeature; +class FrameHandle; +class FrameInfo; +class HitTestResult; +class Navigation; +class NavigationAction; class NavigationData; +class NavigationResponse; +class OpenPanelParameters; +class PageConfiguration; +class ProcessPoolConfiguration; +class SessionState; +class UserContentExtension; +class UserContentExtensionStore; +class UserScript; +class WebsiteDataStore; +class WebsitePolicies; +class WindowFeatures; } namespace WebKit { @@ -61,94 +78,99 @@ class AuthenticationDecisionListener; class DownloadProxy; class GeolocationPermissionRequestProxy; class NotificationPermissionRequest; -class WebApplicationCacheManagerProxy; +class UserMediaPermissionCheckProxy; +class UserMediaPermissionRequestProxy; class WebBackForwardList; class WebBackForwardListItem; -class WebBatteryManagerProxy; -class WebBatteryStatus; -class WebResourceCacheManagerProxy; class WebColorPickerResultListenerProxy; -class WebContext; +class WebContextMenuListenerProxy; class WebCookieManagerProxy; class WebCredential; -class WebDatabaseManagerProxy; class WebFormSubmissionListenerProxy; class WebFramePolicyListenerProxy; class WebFrameProxy; class WebGeolocationManagerProxy; class WebGeolocationPosition; class WebGrammarDetail; -class WebHitTestResult; class WebIconDatabase; class WebInspectorProxy; -class WebKeyValueStorageManager; -class WebMediaCacheManagerProxy; -class WebNetworkInfoManagerProxy; -class WebNetworkInfo; +class WebMediaSessionFocusManager; +class WebMediaSessionMetadata; class WebNotification; -class WebNotificationProvider; class WebNotificationManagerProxy; -class WebOpenPanelParameters; +class WebNotificationProvider; class WebOpenPanelResultListenerProxy; -class WebOriginDataManagerProxy; class WebPageGroup; class WebPageProxy; -class WebPluginSiteDataManager; class WebPreferences; +class WebProcessPool; class WebProtectionSpace; class WebRenderLayer; class WebRenderObject; +class WebResourceLoadStatisticsManager; class WebTextChecker; +class WebUserContentControllerProxy; class WebVibrationProxy; class WebViewportAttributes; +struct WebsitePolicies; -WK_ADD_API_MAPPING(WKApplicationCacheManagerRef, WebApplicationCacheManagerProxy) WK_ADD_API_MAPPING(WKAuthenticationChallengeRef, AuthenticationChallengeProxy) WK_ADD_API_MAPPING(WKAuthenticationDecisionListenerRef, AuthenticationDecisionListener) WK_ADD_API_MAPPING(WKBackForwardListItemRef, WebBackForwardListItem) WK_ADD_API_MAPPING(WKBackForwardListRef, WebBackForwardList) -WK_ADD_API_MAPPING(WKBatteryManagerRef, WebBatteryManagerProxy) -WK_ADD_API_MAPPING(WKBatteryStatusRef, WebBatteryStatus) WK_ADD_API_MAPPING(WKBundleHitTestResultMediaType, BundleHitTestResultMediaType) -WK_ADD_API_MAPPING(WKResourceCacheManagerRef, WebResourceCacheManagerProxy) WK_ADD_API_MAPPING(WKColorPickerResultListenerRef, WebColorPickerResultListenerProxy) -WK_ADD_API_MAPPING(WKContextRef, WebContext) +WK_ADD_API_MAPPING(WKContextRef, WebProcessPool) +WK_ADD_API_MAPPING(WKContextConfigurationRef, API::ProcessPoolConfiguration) +WK_ADD_API_MAPPING(WKContextMenuListenerRef, WebContextMenuListenerProxy) WK_ADD_API_MAPPING(WKCookieManagerRef, WebCookieManagerProxy) WK_ADD_API_MAPPING(WKCredentialRef, WebCredential) -WK_ADD_API_MAPPING(WKDatabaseManagerRef, WebDatabaseManagerProxy) WK_ADD_API_MAPPING(WKDownloadRef, DownloadProxy) WK_ADD_API_MAPPING(WKFormSubmissionListenerRef, WebFormSubmissionListenerProxy) WK_ADD_API_MAPPING(WKFramePolicyListenerRef, WebFramePolicyListenerProxy) +WK_ADD_API_MAPPING(WKFrameHandleRef, API::FrameHandle) +WK_ADD_API_MAPPING(WKFrameInfoRef, API::FrameInfo) WK_ADD_API_MAPPING(WKFrameRef, WebFrameProxy) WK_ADD_API_MAPPING(WKGeolocationManagerRef, WebGeolocationManagerProxy) WK_ADD_API_MAPPING(WKGeolocationPermissionRequestRef, GeolocationPermissionRequestProxy) WK_ADD_API_MAPPING(WKGeolocationPositionRef, WebGeolocationPosition) WK_ADD_API_MAPPING(WKGrammarDetailRef, WebGrammarDetail) -WK_ADD_API_MAPPING(WKHitTestResultRef, WebHitTestResult) +WK_ADD_API_MAPPING(WKHitTestResultRef, API::HitTestResult) WK_ADD_API_MAPPING(WKIconDatabaseRef, WebIconDatabase) -WK_ADD_API_MAPPING(WKKeyValueStorageManagerRef, WebKeyValueStorageManager) -WK_ADD_API_MAPPING(WKMediaCacheManagerRef, WebMediaCacheManagerProxy) +WK_ADD_API_MAPPING(WKInspectorRef, WebInspectorProxy) +WK_ADD_API_MAPPING(WKMediaSessionFocusManagerRef, WebMediaSessionFocusManager) +WK_ADD_API_MAPPING(WKMediaSessionMetadataRef, WebMediaSessionMetadata) +WK_ADD_API_MAPPING(WKNavigationActionRef, API::NavigationAction) WK_ADD_API_MAPPING(WKNavigationDataRef, API::NavigationData) -WK_ADD_API_MAPPING(WKNetworkInfoManagerRef, WebNetworkInfoManagerProxy) -WK_ADD_API_MAPPING(WKNetworkInfoRef, WebNetworkInfo) +WK_ADD_API_MAPPING(WKNavigationRef, API::Navigation) +WK_ADD_API_MAPPING(WKNavigationResponseRef, API::NavigationResponse) WK_ADD_API_MAPPING(WKNotificationManagerRef, WebNotificationManagerProxy) WK_ADD_API_MAPPING(WKNotificationPermissionRequestRef, NotificationPermissionRequest) WK_ADD_API_MAPPING(WKNotificationProviderRef, WebNotificationProvider) WK_ADD_API_MAPPING(WKNotificationRef, WebNotification) -WK_ADD_API_MAPPING(WKOpenPanelParametersRef, WebOpenPanelParameters) +WK_ADD_API_MAPPING(WKOpenPanelParametersRef, API::OpenPanelParameters) WK_ADD_API_MAPPING(WKOpenPanelResultListenerRef, WebOpenPanelResultListenerProxy) -WK_ADD_API_MAPPING(WKOriginDataManagerRef, WebOriginDataManagerProxy) WK_ADD_API_MAPPING(WKPageGroupRef, WebPageGroup) +WK_ADD_API_MAPPING(WKPageConfigurationRef, API::PageConfiguration) WK_ADD_API_MAPPING(WKPageRef, WebPageProxy) -WK_ADD_API_MAPPING(WKPluginSiteDataManagerRef, WebPluginSiteDataManager) WK_ADD_API_MAPPING(WKPreferencesRef, WebPreferences) WK_ADD_API_MAPPING(WKProtectionSpaceRef, WebProtectionSpace) WK_ADD_API_MAPPING(WKRenderLayerRef, WebRenderLayer) WK_ADD_API_MAPPING(WKRenderObjectRef, WebRenderObject) +WK_ADD_API_MAPPING(WKResourceLoadStatisticsManagerRef, WebResourceLoadStatisticsManager) +WK_ADD_API_MAPPING(WKSessionStateRef, API::SessionState) WK_ADD_API_MAPPING(WKTextCheckerRef, WebTextChecker) +WK_ADD_API_MAPPING(WKUserContentControllerRef, WebUserContentControllerProxy) +WK_ADD_API_MAPPING(WKUserContentExtensionStoreRef, API::UserContentExtensionStore) +WK_ADD_API_MAPPING(WKUserContentFilterRef, API::UserContentExtension) +WK_ADD_API_MAPPING(WKUserMediaPermissionCheckRef, UserMediaPermissionCheckProxy) +WK_ADD_API_MAPPING(WKUserMediaPermissionRequestRef, UserMediaPermissionRequestProxy) +WK_ADD_API_MAPPING(WKUserScriptRef, API::UserScript) WK_ADD_API_MAPPING(WKVibrationRef, WebVibrationProxy) WK_ADD_API_MAPPING(WKViewportAttributesRef, WebViewportAttributes) -WK_ADD_API_MAPPING(WKInspectorRef, WebInspectorProxy) +WK_ADD_API_MAPPING(WKWebsiteDataStoreRef, API::WebsiteDataStore) +WK_ADD_API_MAPPING(WKWebsitePoliciesRef, API::WebsitePolicies) +WK_ADD_API_MAPPING(WKWindowFeaturesRef, API::WindowFeatures) /* Enum conversions */ @@ -211,31 +233,6 @@ inline WKCacheModel toAPI(CacheModel cacheModel) return kWKCacheModelDocumentViewer; } -inline ProcessModel toProcessModel(WKProcessModel wkProcessModel) -{ - switch (wkProcessModel) { - case kWKProcessModelSharedSecondaryProcess: - return ProcessModelSharedSecondaryProcess; - case kWKProcessModelMultipleSecondaryProcesses: - return ProcessModelMultipleSecondaryProcesses; - } - - ASSERT_NOT_REACHED(); - return ProcessModelSharedSecondaryProcess; -} - -inline WKProcessModel toAPI(ProcessModel processModel) -{ - switch (processModel) { - case ProcessModelSharedSecondaryProcess: - return kWKProcessModelSharedSecondaryProcess; - case ProcessModelMultipleSecondaryProcesses: - return kWKProcessModelMultipleSecondaryProcesses; - } - - return kWKProcessModelSharedSecondaryProcess; -} - inline FontSmoothingLevel toFontSmoothingLevel(WKFontSmoothingLevel wkLevel) { switch (wkLevel) { @@ -454,40 +451,99 @@ inline WKPluginLoadPolicy toWKPluginLoadPolicy(PluginModuleLoadPolicy pluginModu return kWKPluginLoadPolicyLoadNormally; case PluginModuleLoadUnsandboxed: return kWKPluginLoadPolicyLoadUnsandboxed; - case PluginModuleBlocked: + case PluginModuleBlockedForSecurity: return kWKPluginLoadPolicyBlocked; + case PluginModuleBlockedForCompatibility: + return kWKPluginLoadPolicyBlockedForCompatibility; } ASSERT_NOT_REACHED(); return kWKPluginLoadPolicyBlocked; } +inline WKPluginLoadClientPolicy toWKPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy PluginLoadClientPolicy) +{ + switch (PluginLoadClientPolicy) { + case WebCore::PluginLoadClientPolicyUndefined: + return kWKPluginLoadClientPolicyUndefined; + case WebCore::PluginLoadClientPolicyBlock: + return kWKPluginLoadClientPolicyBlock; + case WebCore::PluginLoadClientPolicyAsk: + return kWKPluginLoadClientPolicyAsk; + case WebCore::PluginLoadClientPolicyAllow: + return kWKPluginLoadClientPolicyAllow; + case WebCore::PluginLoadClientPolicyAllowAlways: + return kWKPluginLoadClientPolicyAllowAlways; + } + + ASSERT_NOT_REACHED(); + return kWKPluginLoadClientPolicyBlock; +} + inline PluginModuleLoadPolicy toPluginModuleLoadPolicy(WKPluginLoadPolicy pluginLoadPolicy) { switch (pluginLoadPolicy) { case kWKPluginLoadPolicyLoadNormally: return PluginModuleLoadNormally; case kWKPluginLoadPolicyBlocked: - return PluginModuleBlocked; + return PluginModuleBlockedForSecurity; + case kWKPluginLoadPolicyBlockedForCompatibility: + return PluginModuleBlockedForCompatibility; case kWKPluginLoadPolicyLoadUnsandboxed: return PluginModuleLoadUnsandboxed; } ASSERT_NOT_REACHED(); - return PluginModuleBlocked; + return PluginModuleBlockedForSecurity; +} + +inline WebCore::PluginLoadClientPolicy toPluginLoadClientPolicy(WKPluginLoadClientPolicy pluginLoadClientPolicy) +{ + switch (pluginLoadClientPolicy) { + case kWKPluginLoadClientPolicyUndefined: + return WebCore::PluginLoadClientPolicyUndefined; + case kWKPluginLoadClientPolicyBlock: + return WebCore::PluginLoadClientPolicyBlock; + case kWKPluginLoadClientPolicyAsk: + return WebCore::PluginLoadClientPolicyAsk; + case kWKPluginLoadClientPolicyAllow: + return WebCore::PluginLoadClientPolicyAllow; + case kWKPluginLoadClientPolicyAllowAlways: + return WebCore::PluginLoadClientPolicyAllowAlways; + } + + ASSERT_NOT_REACHED(); + return WebCore::PluginLoadClientPolicyBlock; } inline WebCore::WebGLLoadPolicy toWebGLLoadPolicy(WKWebGLLoadPolicy webGLLoadPolicy) { switch (webGLLoadPolicy) { case kWKWebGLLoadPolicyLoadNormally: - return WebCore::WebGLAllow; + return WebCore::WebGLAllowCreation; case kWKWebGLLoadPolicyBlocked: - return WebCore::WebGLBlock; + return WebCore::WebGLBlockCreation; + case kWKWebGLLoadPolicyPending: + return WebCore::WebGLPendingCreation; } ASSERT_NOT_REACHED(); - return WebCore::WebGLAllow; + return WebCore::WebGLAllowCreation; +} + +inline WKWebGLLoadPolicy toAPI(WebCore::WebGLLoadPolicy webGLLoadPolicy) +{ + switch (webGLLoadPolicy) { + case WebCore::WebGLAllowCreation: + return kWKWebGLLoadPolicyLoadNormally; + case WebCore::WebGLBlockCreation: + return kWKWebGLLoadPolicyBlocked; + case WebCore::WebGLPendingCreation: + return kWKWebGLLoadPolicyPending; + } + + ASSERT_NOT_REACHED(); + return kWKWebGLLoadPolicyLoadNormally; } inline ProxyingRefPtr<WebGrammarDetail> toAPI(const WebCore::GrammarDetail& grammarDetail) @@ -501,12 +557,4 @@ inline ProxyingRefPtr<WebGrammarDetail> toAPI(const WebCore::GrammarDetail& gram #include "WKAPICastGtk.h" #endif -#if USE(SOUP) -#include "WKAPICastSoup.h" -#endif - -#if defined(BUILDING_EFL__) -#include "WKAPICastEfl.h" -#endif - #endif // WKAPICast_h diff --git a/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.cpp b/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.cpp index 2d95c6721..c67ffb0f2 100644 --- a/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.cpp @@ -26,27 +26,43 @@ #include "config.h" #include "WKApplicationCacheManager.h" +#include "APIWebsiteDataStore.h" #include "WKAPICast.h" -#include "WebApplicationCacheManagerProxy.h" +#include "WebsiteDataRecord.h" using namespace WebKit; WKTypeID WKApplicationCacheManagerGetTypeID() { - return toAPI(WebApplicationCacheManagerProxy::APIType); + return toAPI(API::WebsiteDataStore::APIType); } -void WKApplicationCacheManagerGetApplicationCacheOrigins(WKApplicationCacheManagerRef applicationCacheManagerRef, void* context, WKApplicationCacheManagerGetApplicationCacheOriginsFunction callback) +void WKApplicationCacheManagerGetApplicationCacheOrigins(WKApplicationCacheManagerRef applicationCacheManager, void* context, WKApplicationCacheManagerGetApplicationCacheOriginsFunction callback) { - toImpl(applicationCacheManagerRef)->getApplicationCacheOrigins(ArrayCallback::create(context, callback)); + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(applicationCacheManager))->websiteDataStore(); + websiteDataStore.fetchData(WebsiteDataType::OfflineWebApplicationCache, { }, [context, callback](auto dataRecords) { + Vector<RefPtr<API::Object>> securityOrigins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + securityOrigins.append(API::SecurityOrigin::create(origin.securityOrigin())); + } + + callback(toAPI(API::Array::create(WTFMove(securityOrigins)).ptr()), nullptr, context); + }); } -void WKApplicationCacheManagerDeleteEntriesForOrigin(WKApplicationCacheManagerRef applicationCacheManagerRef, WKSecurityOriginRef originRef) +void WKApplicationCacheManagerDeleteEntriesForOrigin(WKApplicationCacheManagerRef applicationCacheManager, WKSecurityOriginRef origin) { - toImpl(applicationCacheManagerRef)->deleteEntriesForOrigin(toImpl(originRef)); + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(applicationCacheManager))->websiteDataStore(); + + WebsiteDataRecord dataRecord; + dataRecord.add(WebsiteDataType::OfflineWebApplicationCache, WebCore::SecurityOriginData::fromSecurityOrigin(toImpl(origin)->securityOrigin())); + + websiteDataStore.removeData(WebsiteDataType::OfflineWebApplicationCache, { dataRecord }, [] { }); } -void WKApplicationCacheManagerDeleteAllEntries(WKApplicationCacheManagerRef applicationCacheManagerRef) +void WKApplicationCacheManagerDeleteAllEntries(WKApplicationCacheManagerRef applicationCacheManager) { - toImpl(applicationCacheManagerRef)->deleteAllEntries(); + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(applicationCacheManager))->websiteDataStore(); + websiteDataStore.removeData(WebsiteDataType::OfflineWebApplicationCache, std::chrono::system_clock::time_point::min(), [] { }); } diff --git a/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.h b/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.h index c40039e37..065a462d4 100644 --- a/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKApplicationCacheManager.h @@ -26,7 +26,7 @@ #ifndef WKApplicationCacheManager_h #define WKApplicationCacheManager_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.cpp b/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.cpp index c42b85732..17067cc32 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.cpp @@ -27,10 +27,11 @@ #include "WKAuthenticationChallenge.h" #include "AuthenticationChallengeProxy.h" +#include "AuthenticationDecisionListener.h" +#include "WKAPICast.h" #include "WebCertificateInfo.h" #include "WebCredential.h" #include "WebProtectionSpace.h" -#include "WKAPICast.h" using namespace WebKit; diff --git a/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.h b/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.h index 3802f417f..bc2cf2e7e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.h +++ b/Source/WebKit2/UIProcess/API/C/WKAuthenticationChallenge.h @@ -26,7 +26,7 @@ #ifndef WKAuthenticationChallenge_h #define WKAuthenticationChallenge_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.cpp b/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.cpp index bcb175dfd..db4adb421 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.cpp @@ -28,6 +28,7 @@ #include "AuthenticationDecisionListener.h" #include "WKAPICast.h" +#include "WebCredential.h" using namespace WebKit; @@ -45,3 +46,8 @@ void WKAuthenticationDecisionListenerCancel(WKAuthenticationDecisionListenerRef { toImpl(authenticationListener)->cancel(); } + +void WKAuthenticationDecisionListenerRejectProtectionSpaceAndContinue(WKAuthenticationDecisionListenerRef authenticationListener) +{ + toImpl(authenticationListener)->rejectProtectionSpaceAndContinue(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.h b/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.h index f0724610b..8c7969c86 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.h +++ b/Source/WebKit2/UIProcess/API/C/WKAuthenticationDecisionListener.h @@ -26,7 +26,7 @@ #ifndef WKAuthenticationDecisionListener_h #define WKAuthenticationDecisionListener_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -36,6 +36,7 @@ WK_EXPORT WKTypeID WKAuthenticationDecisionListenerGetTypeID(); WK_EXPORT void WKAuthenticationDecisionListenerUseCredential(WKAuthenticationDecisionListenerRef authenticationListener, WKCredentialRef credential); WK_EXPORT void WKAuthenticationDecisionListenerCancel(WKAuthenticationDecisionListenerRef authenticationListener); +WK_EXPORT void WKAuthenticationDecisionListenerRejectProtectionSpaceAndContinue(WKAuthenticationDecisionListenerRef); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItemRef.h b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItemRef.h index 7008e9a90..f63ba5f45 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBackForwardListItemRef.h +++ b/Source/WebKit2/UIProcess/API/C/WKBackForwardListItemRef.h @@ -26,7 +26,7 @@ #ifndef WKBackForwardListItemRef_h #define WKBackForwardListItemRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.cpp b/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.cpp index b3a1d0882..4be7fc369 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.cpp @@ -74,10 +74,10 @@ unsigned WKBackForwardListGetForwardListCount(WKBackForwardListRef listRef) WKArrayRef WKBackForwardListCopyBackListWithLimit(WKBackForwardListRef listRef, unsigned limit) { - return toAPI(toImpl(listRef)->backListAsAPIArrayWithLimit(limit).leakRef()); + return toAPI(&toImpl(listRef)->backListAsAPIArrayWithLimit(limit).leakRef()); } WKArrayRef WKBackForwardListCopyForwardListWithLimit(WKBackForwardListRef listRef, unsigned limit) { - return toAPI(toImpl(listRef)->forwardListAsAPIArrayWithLimit(limit).leakRef()); + return toAPI(&toImpl(listRef)->forwardListAsAPIArrayWithLimit(limit).leakRef()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.h b/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.h index 1c7643986..97b2209d2 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.h +++ b/Source/WebKit2/UIProcess/API/C/WKBackForwardListRef.h @@ -26,7 +26,7 @@ #ifndef WKBackForwardListRef_h #define WKBackForwardListRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKBatteryManager.cpp b/Source/WebKit2/UIProcess/API/C/WKBatteryManager.cpp deleted file mode 100644 index a9acfa0a4..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKBatteryManager.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WKBatteryManager.h" - -#include "WKAPICast.h" -#include <wtf/text/AtomicString.h> - -#if ENABLE(BATTERY_STATUS) -#include "WebBatteryManagerProxy.h" -#endif - -using namespace WebKit; - -WKTypeID WKBatteryManagerGetTypeID() -{ -#if ENABLE(BATTERY_STATUS) - return toAPI(WebBatteryManagerProxy::APIType); -#else - return 0; -#endif -} - -void WKBatteryManagerSetProvider(WKBatteryManagerRef batteryManager, const WKBatteryProviderBase* provider) -{ -#if ENABLE(BATTERY_STATUS) - toImpl(batteryManager)->initializeProvider(provider); -#else - UNUSED_PARAM(batteryManager); - UNUSED_PARAM(provider); -#endif -} - -void WKBatteryManagerProviderDidChangeBatteryStatus(WKBatteryManagerRef batteryManager, WKStringRef eventType, WKBatteryStatusRef status) -{ -#if ENABLE(BATTERY_STATUS) - toImpl(batteryManager)->providerDidChangeBatteryStatus(AtomicString(toImpl(eventType)->string()), toImpl(status)); -#else - UNUSED_PARAM(batteryManager); - UNUSED_PARAM(eventType); - UNUSED_PARAM(status); -#endif -} - -void WKBatteryManagerProviderUpdateBatteryStatus(WKBatteryManagerRef batteryManager, WKBatteryStatusRef status) -{ -#if ENABLE(BATTERY_STATUS) - toImpl(batteryManager)->providerUpdateBatteryStatus(toImpl(status)); -#else - UNUSED_PARAM(batteryManager); - UNUSED_PARAM(status); -#endif -} diff --git a/Source/WebKit2/UIProcess/API/C/WKContext.cpp b/Source/WebKit2/UIProcess/API/C/WKContext.cpp index f5a9cb635..2cce4da50 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContext.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKContext.cpp @@ -24,52 +24,64 @@ */ #include "config.h" -#include "WKContext.h" #include "WKContextPrivate.h" +#include "APIClient.h" +#include "APIDownloadClient.h" +#include "APILegacyContextHistoryClient.h" +#include "APINavigationData.h" +#include "APIProcessPoolConfiguration.h" #include "APIURLRequest.h" +#include "AuthenticationChallengeProxy.h" +#include "DownloadProxy.h" #include "WKAPICast.h" -#include "WebContext.h" -#include <wtf/PassRefPtr.h> +#include "WKContextConfigurationRef.h" +#include "WKRetainPtr.h" +#include "WebCertificateInfo.h" +#include "WebIconDatabase.h" +#include "WebProcessPool.h" #include <wtf/RefPtr.h> #include <wtf/text/WTFString.h> // Supplements -#include "WebApplicationCacheManagerProxy.h" #include "WebCookieManagerProxy.h" #include "WebGeolocationManagerProxy.h" -#include "WebKeyValueStorageManager.h" -#include "WebMediaCacheManagerProxy.h" #include "WebNotificationManagerProxy.h" -#include "WebOriginDataManagerProxy.h" -#include "WebResourceCacheManagerProxy.h" -#if ENABLE(SQL_DATABASE) -#include "WebDatabaseManagerProxy.h" -#endif -#if ENABLE(BATTERY_STATUS) -#include "WebBatteryManagerProxy.h" -#endif -#if ENABLE(NETWORK_INFO) -#include "WebNetworkInfoManagerProxy.h" -#endif +namespace API { +template<> struct ClientTraits<WKContextDownloadClientBase> { + typedef std::tuple<WKContextDownloadClientV0> Versions; +}; +template<> struct ClientTraits<WKContextHistoryClientBase> { + typedef std::tuple<WKContextHistoryClientV0> Versions; +}; +} + +using namespace WebCore; using namespace WebKit; WKTypeID WKContextGetTypeID() { - return toAPI(WebContext::APIType); + return toAPI(WebProcessPool::APIType); } WKContextRef WKContextCreate() { - RefPtr<WebContext> context = WebContext::create(String()); - return toAPI(context.release().leakRef()); + auto configuration = API::ProcessPoolConfiguration::createWithLegacyOptions(); + return toAPI(&WebProcessPool::create(configuration).leakRef()); } WKContextRef WKContextCreateWithInjectedBundlePath(WKStringRef pathRef) { - RefPtr<WebContext> context = WebContext::create(toImpl(pathRef)->string()); - return toAPI(context.release().leakRef()); + auto configuration = API::ProcessPoolConfiguration::createWithLegacyOptions(); + configuration->setInjectedBundlePath(toWTFString(pathRef)); + + return toAPI(&WebProcessPool::create(configuration).leakRef()); +} + +WKContextRef WKContextCreateWithConfiguration(WKContextConfigurationRef configuration) +{ + return toAPI(&WebProcessPool::create(*toImpl(configuration)).leakRef()); } void WKContextSetClient(WKContextRef contextRef, const WKContextClientBase* wkClient) @@ -84,12 +96,173 @@ void WKContextSetInjectedBundleClient(WKContextRef contextRef, const WKContextIn void WKContextSetHistoryClient(WKContextRef contextRef, const WKContextHistoryClientBase* wkClient) { - toImpl(contextRef)->initializeHistoryClient(wkClient); + class HistoryClient final : public API::Client<WKContextHistoryClientBase>, public API::LegacyContextHistoryClient { + public: + explicit HistoryClient(const WKContextHistoryClientBase* client) + { + initialize(client); + } + + private: + void didNavigateWithNavigationData(WebProcessPool& processPool, WebPageProxy& page, const WebNavigationDataStore& navigationDataStore, WebFrameProxy& frame) override + { + if (!m_client.didNavigateWithNavigationData) + return; + + RefPtr<API::NavigationData> navigationData = API::NavigationData::create(navigationDataStore); + m_client.didNavigateWithNavigationData(toAPI(&processPool), toAPI(&page), toAPI(navigationData.get()), toAPI(&frame), m_client.base.clientInfo); + } + + void didPerformClientRedirect(WebProcessPool& processPool, WebPageProxy& page, const String& sourceURL, const String& destinationURL, WebFrameProxy& frame) override + { + if (!m_client.didPerformClientRedirect) + return; + + m_client.didPerformClientRedirect(toAPI(&processPool), toAPI(&page), toURLRef(sourceURL.impl()), toURLRef(destinationURL.impl()), toAPI(&frame), m_client.base.clientInfo); + } + + void didPerformServerRedirect(WebProcessPool& processPool, WebPageProxy& page, const String& sourceURL, const String& destinationURL, WebFrameProxy& frame) override + { + if (!m_client.didPerformServerRedirect) + return; + + m_client.didPerformServerRedirect(toAPI(&processPool), toAPI(&page), toURLRef(sourceURL.impl()), toURLRef(destinationURL.impl()), toAPI(&frame), m_client.base.clientInfo); + } + + void didUpdateHistoryTitle(WebProcessPool& processPool, WebPageProxy& page, const String& title, const String& url, WebFrameProxy& frame) override + { + if (!m_client.didUpdateHistoryTitle) + return; + + m_client.didUpdateHistoryTitle(toAPI(&processPool), toAPI(&page), toAPI(title.impl()), toURLRef(url.impl()), toAPI(&frame), m_client.base.clientInfo); + } + + void populateVisitedLinks(WebProcessPool& processPool) override + { + if (!m_client.populateVisitedLinks) + return; + + m_client.populateVisitedLinks(toAPI(&processPool), m_client.base.clientInfo); + } + + bool addsVisitedLinks() const override + { + return m_client.populateVisitedLinks; + } + }; + + WebProcessPool& processPool = *toImpl(contextRef); + processPool.setHistoryClient(std::make_unique<HistoryClient>(wkClient)); + + bool addsVisitedLinks = processPool.historyClient().addsVisitedLinks(); + + for (auto& process : processPool.processes()) { + for (auto& page : process->pages()) + page->setAddsVisitedLinks(addsVisitedLinks); + } } void WKContextSetDownloadClient(WKContextRef contextRef, const WKContextDownloadClientBase* wkClient) { - toImpl(contextRef)->initializeDownloadClient(wkClient); + class DownloadClient final : public API::Client<WKContextDownloadClientBase>, public API::DownloadClient { + public: + explicit DownloadClient(const WKContextDownloadClientBase* client) + { + initialize(client); + } + private: + void didStart(WebProcessPool* processPool, DownloadProxy* downloadProxy) override + { + if (!m_client.didStart) + return; + + m_client.didStart(toAPI(processPool), toAPI(downloadProxy), m_client.base.clientInfo); + } + + void didReceiveAuthenticationChallenge(WebProcessPool* processPool, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallengeProxy) override + { + if (!m_client.didReceiveAuthenticationChallenge) + return; + + m_client.didReceiveAuthenticationChallenge(toAPI(processPool), toAPI(downloadProxy), toAPI(authenticationChallengeProxy), m_client.base.clientInfo); + } + + void didReceiveResponse(WebProcessPool* processPool, DownloadProxy* downloadProxy, const ResourceResponse& response) override + { + if (!m_client.didReceiveResponse) + return; + + m_client.didReceiveResponse(toAPI(processPool), toAPI(downloadProxy), toAPI(API::URLResponse::create(response).ptr()), m_client.base.clientInfo); + } + + void didReceiveData(WebProcessPool* processPool, DownloadProxy* downloadProxy, uint64_t length) override + { + if (!m_client.didReceiveData) + return; + + m_client.didReceiveData(toAPI(processPool), toAPI(downloadProxy), length, m_client.base.clientInfo); + } + + bool shouldDecodeSourceDataOfMIMEType(WebProcessPool* processPool, DownloadProxy* downloadProxy, const String& mimeType) override + { + if (!m_client.shouldDecodeSourceDataOfMIMEType) + return true; + + return m_client.shouldDecodeSourceDataOfMIMEType(toAPI(processPool), toAPI(downloadProxy), toAPI(mimeType.impl()), m_client.base.clientInfo); + } + + String decideDestinationWithSuggestedFilename(WebProcessPool* processPool, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwrite) override + { + if (!m_client.decideDestinationWithSuggestedFilename) + return String(); + + WKRetainPtr<WKStringRef> destination(AdoptWK, m_client.decideDestinationWithSuggestedFilename(toAPI(processPool), toAPI(downloadProxy), toAPI(filename.impl()), &allowOverwrite, m_client.base.clientInfo)); + return toWTFString(destination.get()); + } + + void didCreateDestination(WebProcessPool* processPool, DownloadProxy* downloadProxy, const String& path) override + { + if (!m_client.didCreateDestination) + return; + + m_client.didCreateDestination(toAPI(processPool), toAPI(downloadProxy), toAPI(path.impl()), m_client.base.clientInfo); + } + + void didFinish(WebProcessPool* processPool, DownloadProxy* downloadProxy) override + { + if (!m_client.didFinish) + return; + + m_client.didFinish(toAPI(processPool), toAPI(downloadProxy), m_client.base.clientInfo); + } + + void didFail(WebProcessPool* processPool, DownloadProxy* downloadProxy, const ResourceError& error) override + { + if (!m_client.didFail) + return; + + m_client.didFail(toAPI(processPool), toAPI(downloadProxy), toAPI(error), m_client.base.clientInfo); + } + + void didCancel(WebProcessPool* processPool, DownloadProxy* downloadProxy) override + { + if (!m_client.didCancel) + return; + + m_client.didCancel(toAPI(processPool), toAPI(downloadProxy), m_client.base.clientInfo); + } + + void processDidCrash(WebProcessPool* processPool, DownloadProxy* downloadProxy) override + { + if (!m_client.processDidCrash) + return; + + m_client.processDidCrash(toAPI(processPool), toAPI(downloadProxy), m_client.base.clientInfo); + } + + }; + + toImpl(contextRef)->setDownloadClient(std::make_unique<DownloadClient>(wkClient)); } void WKContextSetConnectionClient(WKContextRef contextRef, const WKContextConnectionClientBase* wkClient) @@ -97,11 +270,16 @@ void WKContextSetConnectionClient(WKContextRef contextRef, const WKContextConnec toImpl(contextRef)->initializeConnectionClient(wkClient); } -WKDownloadRef WKContextDownloadURLRequest(WKContextRef contextRef, const WKURLRequestRef requestRef) +WKDownloadRef WKContextDownloadURLRequest(WKContextRef contextRef, WKURLRequestRef requestRef) { return toAPI(toImpl(contextRef)->download(0, toImpl(requestRef)->resourceRequest())); } +WKDownloadRef WKContextResumeDownload(WKContextRef contextRef, WKDataRef resumeData, WKStringRef path) +{ + return toAPI(toImpl(contextRef)->resumeDownload(toImpl(resumeData), toWTFString(path))); +} + void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef contextRef, WKTypeRef userDataRef) { toImpl(contextRef)->setInjectedBundleInitializationUserData(toImpl(userDataRef)); @@ -114,7 +292,7 @@ void WKContextPostMessageToInjectedBundle(WKContextRef contextRef, WKStringRef m void WKContextGetGlobalStatistics(WKContextStatistics* statistics) { - const WebContext::Statistics& webContextStatistics = WebContext::statistics(); + const WebProcessPool::Statistics& webContextStatistics = WebProcessPool::statistics(); statistics->wkViewCount = webContextStatistics.wkViewCount; statistics->wkPageCount = webContextStatistics.wkPageCount; @@ -123,27 +301,26 @@ void WKContextGetGlobalStatistics(WKContextStatistics* statistics) void WKContextAddVisitedLink(WKContextRef contextRef, WKStringRef visitedURL) { - toImpl(contextRef)->addVisitedLink(toImpl(visitedURL)->string()); -} + String visitedURLString = toImpl(visitedURL)->string(); + if (visitedURLString.isEmpty()) + return; -void WKContextSetCacheModel(WKContextRef contextRef, WKCacheModel cacheModel) -{ - toImpl(contextRef)->setCacheModel(toCacheModel(cacheModel)); + toImpl(contextRef)->visitedLinkStore().addVisitedLinkHash(visitedLinkHash(visitedURLString)); } -WKCacheModel WKContextGetCacheModel(WKContextRef contextRef) +void WKContextClearVisitedLinks(WKContextRef contextRef) { - return toAPI(toImpl(contextRef)->cacheModel()); + toImpl(contextRef)->visitedLinkStore().removeAll(); } -void WKContextSetProcessModel(WKContextRef contextRef, WKProcessModel processModel) +void WKContextSetCacheModel(WKContextRef contextRef, WKCacheModel cacheModel) { - toImpl(contextRef)->setProcessModel(toProcessModel(processModel)); + toImpl(contextRef)->setCacheModel(toCacheModel(cacheModel)); } -WKProcessModel WKContextGetProcessModel(WKContextRef contextRef) +WKCacheModel WKContextGetCacheModel(WKContextRef contextRef) { - return toAPI(toImpl(contextRef)->processModel()); + return toAPI(toImpl(contextRef)->cacheModel()); } void WKContextSetMaximumNumberOfProcesses(WKContextRef contextRef, unsigned numberOfProcesses) @@ -176,6 +353,15 @@ void WKContextSetAdditionalPluginsDirectory(WKContextRef contextRef, WKStringRef #endif } +void WKContextRefreshPlugIns(WKContextRef context) +{ +#if ENABLE(NETSCAPE_PLUGIN_API) + toImpl(context)->refreshPlugins(); +#else + UNUSED_PARAM(context); +#endif +} + void WKContextRegisterURLSchemeAsEmptyDocument(WKContextRef contextRef, WKStringRef urlScheme) { toImpl(contextRef)->registerURLSchemeAsEmptyDocument(toImpl(urlScheme)->string()); @@ -186,94 +372,84 @@ void WKContextRegisterURLSchemeAsSecure(WKContextRef contextRef, WKStringRef url toImpl(contextRef)->registerURLSchemeAsSecure(toImpl(urlScheme)->string()); } -void WKContextSetDomainRelaxationForbiddenForURLScheme(WKContextRef contextRef, WKStringRef urlScheme) +void WKContextRegisterURLSchemeAsBypassingContentSecurityPolicy(WKContextRef contextRef, WKStringRef urlScheme) { - toImpl(contextRef)->setDomainRelaxationForbiddenForURLScheme(toImpl(urlScheme)->string()); + toImpl(contextRef)->registerURLSchemeAsBypassingContentSecurityPolicy(toImpl(urlScheme)->string()); } -WKCookieManagerRef WKContextGetCookieManager(WKContextRef contextRef) +void WKContextRegisterURLSchemeAsCachePartitioned(WKContextRef contextRef, WKStringRef urlScheme) { - return toAPI(toImpl(contextRef)->supplement<WebCookieManagerProxy>()); + toImpl(contextRef)->registerURLSchemeAsCachePartitioned(toImpl(urlScheme)->string()); } -WKApplicationCacheManagerRef WKContextGetApplicationCacheManager(WKContextRef contextRef) +void WKContextSetDomainRelaxationForbiddenForURLScheme(WKContextRef contextRef, WKStringRef urlScheme) { - return toAPI(toImpl(contextRef)->supplement<WebApplicationCacheManagerProxy>()); + toImpl(contextRef)->setDomainRelaxationForbiddenForURLScheme(toImpl(urlScheme)->string()); } -WKBatteryManagerRef WKContextGetBatteryManager(WKContextRef contextRef) +void WKContextSetCanHandleHTTPSServerTrustEvaluation(WKContextRef contextRef, bool value) { -#if ENABLE(BATTERY_STATUS) - return toAPI(toImpl(contextRef)->supplement<WebBatteryManagerProxy>()); -#else - UNUSED_PARAM(contextRef); - return 0; -#endif + toImpl(contextRef)->setCanHandleHTTPSServerTrustEvaluation(value); } -WKDatabaseManagerRef WKContextGetDatabaseManager(WKContextRef contextRef) +void WKContextSetDiskCacheSpeculativeValidationEnabled(WKContextRef contextRef, bool value) { -#if ENABLE(SQL_DATABASE) - return toAPI(toImpl(contextRef)->supplement<WebDatabaseManagerProxy>()); -#else - UNUSED_PARAM(contextRef); - return 0; -#endif + toImpl(contextRef)->configuration().setDiskCacheSpeculativeValidationEnabled(value); } -WKGeolocationManagerRef WKContextGetGeolocationManager(WKContextRef contextRef) +void WKContextSetUnresponsiveBackgroundProcessesTerminationEnabled(WKContextRef contextRef, bool value) { - return toAPI(toImpl(contextRef)->supplement<WebGeolocationManagerProxy>()); + toImpl(contextRef)->configuration().setUnresponsiveBackgroundProcessesTerminationEnabled(value); } -WKNetworkInfoManagerRef WKContextGetNetworkInfoManager(WKContextRef contextRef) +WKCookieManagerRef WKContextGetCookieManager(WKContextRef contextRef) { -#if ENABLE(NETWORK_INFO) - return toAPI(toImpl(contextRef)->supplement<WebNetworkInfoManagerProxy>()); -#else - UNUSED_PARAM(contextRef); - return 0; -#endif + return toAPI(toImpl(contextRef)->supplement<WebCookieManagerProxy>()); } -WKIconDatabaseRef WKContextGetIconDatabase(WKContextRef contextRef) +WKWebsiteDataStoreRef WKContextGetWebsiteDataStore(WKContextRef context) { - return toAPI(toImpl(contextRef)->iconDatabase()); + return toAPI(toImpl(context)->websiteDataStore()); } -WKKeyValueStorageManagerRef WKContextGetKeyValueStorageManager(WKContextRef contextRef) +WKApplicationCacheManagerRef WKContextGetApplicationCacheManager(WKContextRef context) { - return toAPI(toImpl(contextRef)->supplement<WebKeyValueStorageManager>()); + return reinterpret_cast<WKApplicationCacheManagerRef>(WKContextGetWebsiteDataStore(context)); } -WKMediaCacheManagerRef WKContextGetMediaCacheManager(WKContextRef contextRef) +WKGeolocationManagerRef WKContextGetGeolocationManager(WKContextRef contextRef) { - return toAPI(toImpl(contextRef)->supplement<WebMediaCacheManagerProxy>()); + return toAPI(toImpl(contextRef)->supplement<WebGeolocationManagerProxy>()); } -WKNotificationManagerRef WKContextGetNotificationManager(WKContextRef contextRef) +WKIconDatabaseRef WKContextGetIconDatabase(WKContextRef contextRef) { - return toAPI(toImpl(contextRef)->supplement<WebNotificationManagerProxy>()); + return toAPI(toImpl(contextRef)->iconDatabase()); } -WKPluginSiteDataManagerRef WKContextGetPluginSiteDataManager(WKContextRef contextRef) +WKKeyValueStorageManagerRef WKContextGetKeyValueStorageManager(WKContextRef context) { -#if ENABLE(NETSCAPE_PLUGIN_API) - return toAPI(toImpl(contextRef)->pluginSiteDataManager()); + return reinterpret_cast<WKKeyValueStorageManagerRef>(WKContextGetWebsiteDataStore(context)); +} + +WKMediaSessionFocusManagerRef WKContextGetMediaSessionFocusManager(WKContextRef context) +{ +#if ENABLE(MEDIA_SESSION) + return toAPI(toImpl(context)->supplement<WebMediaSessionFocusManager>()); #else - UNUSED_PARAM(contextRef); - return 0; + UNUSED_PARAM(context); + return nullptr; #endif } -WKResourceCacheManagerRef WKContextGetResourceCacheManager(WKContextRef contextRef) +WKNotificationManagerRef WKContextGetNotificationManager(WKContextRef contextRef) { - return toAPI(toImpl(contextRef)->supplement<WebResourceCacheManagerProxy>()); + return toAPI(toImpl(contextRef)->supplement<WebNotificationManagerProxy>()); } -WKOriginDataManagerRef WKContextGetOriginDataManager(WKContextRef contextRef) +WKResourceCacheManagerRef WKContextGetResourceCacheManager(WKContextRef context) { - return toAPI(toImpl(contextRef)->supplement<WebOriginDataManagerProxy>()); + return reinterpret_cast<WKResourceCacheManagerRef>(WKContextGetWebsiteDataStore(context)); } void WKContextStartMemorySampler(WKContextRef contextRef, WKDoubleRef interval) @@ -296,26 +472,6 @@ void WKContextAllowSpecificHTTPSCertificateForHost(WKContextRef contextRef, WKCe toImpl(contextRef)->allowSpecificHTTPSCertificateForHost(toImpl(certificateRef), toImpl(hostRef)->string()); } -WK_EXPORT void WKContextSetApplicationCacheDirectory(WKContextRef contextRef, WKStringRef applicationCacheDirectory) -{ - toImpl(contextRef)->setApplicationCacheDirectory(toImpl(applicationCacheDirectory)->string()); -} - -void WKContextSetDatabaseDirectory(WKContextRef contextRef, WKStringRef databaseDirectory) -{ - toImpl(contextRef)->setDatabaseDirectory(toImpl(databaseDirectory)->string()); -} - -void WKContextSetLocalStorageDirectory(WKContextRef contextRef, WKStringRef localStorageDirectory) -{ - toImpl(contextRef)->setLocalStorageDirectory(toImpl(localStorageDirectory)->string()); -} - -WK_EXPORT void WKContextSetDiskCacheDirectory(WKContextRef contextRef, WKStringRef diskCacheDirectory) -{ - toImpl(contextRef)->setDiskCacheDirectory(toImpl(diskCacheDirectory)->string()); -} - WK_EXPORT void WKContextSetCookieStorageDirectory(WKContextRef contextRef, WKStringRef cookieStorageDirectory) { toImpl(contextRef)->setCookieStorageDirectory(toImpl(cookieStorageDirectory)->string()); @@ -343,12 +499,12 @@ void WKContextWarmInitialProcess(WKContextRef contextRef) void WKContextGetStatistics(WKContextRef contextRef, void* context, WKContextGetStatisticsFunction callback) { - toImpl(contextRef)->getStatistics(0xFFFFFFFF, DictionaryCallback::create(context, callback)); + toImpl(contextRef)->getStatistics(0xFFFFFFFF, toGenericCallbackFunction(context, callback)); } void WKContextGetStatisticsWithOptions(WKContextRef contextRef, WKStatisticsOptions optionsMask, void* context, WKContextGetStatisticsFunction callback) { - toImpl(contextRef)->getStatistics(optionsMask, DictionaryCallback::create(context, callback)); + toImpl(contextRef)->getStatistics(optionsMask, toGenericCallbackFunction(context, callback)); } void WKContextGarbageCollectJavaScriptObjects(WKContextRef contextRef) @@ -361,14 +517,14 @@ void WKContextSetJavaScriptGarbageCollectorTimerEnabled(WKContextRef contextRef, toImpl(contextRef)->setJavaScriptGarbageCollectorTimerEnabled(enable); } -void WKContextSetUsesNetworkProcess(WKContextRef contextRef, bool usesNetworkProcess) +void WKContextUseTestingNetworkSession(WKContextRef context) { - toImpl(contextRef)->setUsesNetworkProcess(usesNetworkProcess); + toImpl(context)->useTestingNetworkSession(); } -void WKContextUseTestingNetworkSession(WKContextRef context) +void WKContextClearCachedCredentials(WKContextRef context) { - toImpl(context)->useTestingNetworkSession(); + toImpl(context)->clearCachedCredentials(); } WKDictionaryRef WKContextCopyPlugInAutoStartOriginHashes(WKContextRef contextRef) @@ -399,10 +555,25 @@ void WKContextSetPlugInAutoStartOrigins(WKContextRef contextRef, WKArrayRef arra void WKContextSetInvalidMessageFunction(WKContextInvalidMessageFunction invalidMessageFunction) { - WebContext::setInvalidMessageCallback(invalidMessageFunction); + WebProcessPool::setInvalidMessageCallback(invalidMessageFunction); } void WKContextSetMemoryCacheDisabled(WKContextRef contextRef, bool disabled) { toImpl(contextRef)->setMemoryCacheDisabled(disabled); } + +void WKContextSetFontWhitelist(WKContextRef contextRef, WKArrayRef arrayRef) +{ + toImpl(contextRef)->setFontWhitelist(toImpl(arrayRef)); +} + +pid_t WKContextGetNetworkProcessIdentifier(WKContextRef contextRef) +{ + return toImpl(contextRef)->networkProcessIdentifier(); +} + +pid_t WKContextGetDatabaseProcessIdentifier(WKContextRef contextRef) +{ + return toImpl(contextRef)->databaseProcessIdentifier(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKContext.h b/Source/WebKit2/UIProcess/API/C/WKContext.h index 82237a5b4..e5fb6e343 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContext.h +++ b/Source/WebKit2/UIProcess/API/C/WKContext.h @@ -26,11 +26,11 @@ #ifndef WKContext_h #define WKContext_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKContextConnectionClient.h> -#include <WebKit2/WKContextDownloadClient.h> -#include <WebKit2/WKContextHistoryClient.h> -#include <WebKit2/WKContextInjectedBundleClient.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKContextConnectionClient.h> +#include <WebKit/WKContextDownloadClient.h> +#include <WebKit/WKContextHistoryClient.h> +#include <WebKit/WKContextInjectedBundleClient.h> #ifdef __cplusplus extern "C" { @@ -45,8 +45,12 @@ typedef uint32_t WKCacheModel; // Context Client typedef void (*WKContextPlugInAutoStartOriginHashesChangedCallback)(WKContextRef context, const void *clientInfo); -typedef void (*WKContextNetworkProcessDidCrashCallback)(WKContextRef context, const void *clientInfo); typedef void (*WKContextPlugInInformationBecameAvailableCallback)(WKContextRef context, WKArrayRef plugIn, const void *clientInfo); +typedef WKDataRef (*WKContextCopyWebCryptoMasterKeyCallback)(WKContextRef context, const void *clientInfo); + +typedef void (*WKContextChildProcessDidCrashCallback)(WKContextRef context, const void *clientInfo); +typedef WKContextChildProcessDidCrashCallback WKContextNetworkProcessDidCrashCallback; +typedef WKContextChildProcessDidCrashCallback WKContextDatabaseProcessDidCrashCallback; typedef struct WKContextClientBase { int version; @@ -62,17 +66,34 @@ typedef struct WKContextClientV0 { WKContextPlugInInformationBecameAvailableCallback plugInInformationBecameAvailable; } WKContextClientV0; -enum { kWKContextClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKContextClient { - int version; - const void * clientInfo; +typedef struct WKContextClientV1 { + WKContextClientBase base; // Version 0. WKContextPlugInAutoStartOriginHashesChangedCallback plugInAutoStartOriginHashesChanged; WKContextNetworkProcessDidCrashCallback networkProcessDidCrash; WKContextPlugInInformationBecameAvailableCallback plugInInformationBecameAvailable; -} WKContextClient WK_DEPRECATED("Use an explicit versioned struct instead"); + // Version 1. + void (*copyWebCryptoMasterKey_unavailable)(void); +} WKContextClientV1; + +typedef struct WKContextClientV2 { + WKContextClientBase base; + + // Version 0. + WKContextPlugInAutoStartOriginHashesChangedCallback plugInAutoStartOriginHashesChanged; + WKContextNetworkProcessDidCrashCallback networkProcessDidCrash; + WKContextPlugInInformationBecameAvailableCallback plugInInformationBecameAvailable; + + // Version 1. + void (*copyWebCryptoMasterKey_unavailable)(void); + + // Version 2. + WKContextDatabaseProcessDidCrashCallback databaseProcessDidCrash; +} WKContextClientV2; + +// FIXME: Remove these once support for Mavericks has been dropped. enum { kWKProcessModelSharedSecondaryProcess = 0, kWKProcessModelMultipleSecondaryProcesses = 1 @@ -89,6 +110,7 @@ WK_EXPORT WKTypeID WKContextGetTypeID(); WK_EXPORT WKContextRef WKContextCreate(); WK_EXPORT WKContextRef WKContextCreateWithInjectedBundlePath(WKStringRef path); +WK_EXPORT WKContextRef WKContextCreateWithConfiguration(WKContextConfigurationRef configuration); WK_EXPORT void WKContextSetClient(WKContextRef context, const WKContextClientBase* client); WK_EXPORT void WKContextSetInjectedBundleClient(WKContextRef context, const WKContextInjectedBundleClientBase* client); @@ -96,18 +118,20 @@ WK_EXPORT void WKContextSetHistoryClient(WKContextRef context, const WKContextHi WK_EXPORT void WKContextSetDownloadClient(WKContextRef context, const WKContextDownloadClientBase* client); WK_EXPORT void WKContextSetConnectionClient(WKContextRef context, const WKContextConnectionClientBase* client); -WK_EXPORT WKDownloadRef WKContextDownloadURLRequest(WKContextRef context, const WKURLRequestRef request); +WK_EXPORT WKDownloadRef WKContextDownloadURLRequest(WKContextRef context, WKURLRequestRef request); +WK_EXPORT WKDownloadRef WKContextResumeDownload(WKContextRef context, WKDataRef resumeData, WKStringRef path); WK_EXPORT void WKContextSetInitializationUserDataForInjectedBundle(WKContextRef context, WKTypeRef userData); WK_EXPORT void WKContextPostMessageToInjectedBundle(WKContextRef context, WKStringRef messageName, WKTypeRef messageBody); WK_EXPORT void WKContextAddVisitedLink(WKContextRef context, WKStringRef visitedURL); +WK_EXPORT void WKContextClearVisitedLinks(WKContextRef contextRef); WK_EXPORT void WKContextSetCacheModel(WKContextRef context, WKCacheModel cacheModel); WK_EXPORT WKCacheModel WKContextGetCacheModel(WKContextRef context); -WK_EXPORT void WKContextSetProcessModel(WKContextRef context, WKProcessModel processModel); -WK_EXPORT WKProcessModel WKContextGetProcessModel(WKContextRef context); +// FIXME: Move these to WKDeprecatedFunctions.cpp once support for Mavericks has been dropped. +WK_EXPORT void WKContextSetProcessModel(WKContextRef, WKProcessModel); WK_EXPORT void WKContextSetMaximumNumberOfProcesses(WKContextRef context, unsigned numberOfProcesses); WK_EXPORT unsigned WKContextGetMaximumNumberOfProcesses(WKContextRef context); @@ -115,19 +139,16 @@ WK_EXPORT unsigned WKContextGetMaximumNumberOfProcesses(WKContextRef context); WK_EXPORT void WKContextStartMemorySampler(WKContextRef context, WKDoubleRef interval); WK_EXPORT void WKContextStopMemorySampler(WKContextRef context); +WK_EXPORT WKWebsiteDataStoreRef WKContextGetWebsiteDataStore(WKContextRef context); + WK_EXPORT WKApplicationCacheManagerRef WKContextGetApplicationCacheManager(WKContextRef context); -WK_EXPORT WKBatteryManagerRef WKContextGetBatteryManager(WKContextRef context); WK_EXPORT WKCookieManagerRef WKContextGetCookieManager(WKContextRef context); -WK_EXPORT WKDatabaseManagerRef WKContextGetDatabaseManager(WKContextRef context); WK_EXPORT WKGeolocationManagerRef WKContextGetGeolocationManager(WKContextRef context); WK_EXPORT WKIconDatabaseRef WKContextGetIconDatabase(WKContextRef context); WK_EXPORT WKKeyValueStorageManagerRef WKContextGetKeyValueStorageManager(WKContextRef context); -WK_EXPORT WKMediaCacheManagerRef WKContextGetMediaCacheManager(WKContextRef context); -WK_EXPORT WKNetworkInfoManagerRef WKContextGetNetworkInfoManager(WKContextRef context); +WK_EXPORT WKMediaSessionFocusManagerRef WKContextGetMediaSessionFocusManager(WKContextRef context); WK_EXPORT WKNotificationManagerRef WKContextGetNotificationManager(WKContextRef context); -WK_EXPORT WKPluginSiteDataManagerRef WKContextGetPluginSiteDataManager(WKContextRef context); WK_EXPORT WKResourceCacheManagerRef WKContextGetResourceCacheManager(WKContextRef context); -WK_EXPORT WKOriginDataManagerRef WKContextGetOriginDataManager(WKContextRef context); typedef void (*WKContextGetStatisticsFunction)(WKDictionaryRef statistics, WKErrorRef error, void* functionContext); WK_EXPORT void WKContextGetStatistics(WKContextRef context, void* functionContext, WKContextGetStatisticsFunction function); @@ -140,6 +161,7 @@ WK_EXPORT WKDictionaryRef WKContextCopyPlugInAutoStartOriginHashes(WKContextRef WK_EXPORT void WKContextSetPlugInAutoStartOriginHashes(WKContextRef context, WKDictionaryRef dictionary); WK_EXPORT void WKContextSetPlugInAutoStartOrigins(WKContextRef contextRef, WKArrayRef arrayRef); WK_EXPORT void WKContextSetPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(WKContextRef contextRef, WKDictionaryRef dictionaryRef, double time); +WK_EXPORT void WKContextRefreshPlugIns(WKContextRef context); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.cpp b/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.cpp new file mode 100644 index 000000000..fe4f9139a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKContextConfigurationRef.h" + +#include "APIProcessPoolConfiguration.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKContextConfigurationRef WKContextConfigurationCreate() +{ + auto configuration = API::ProcessPoolConfiguration::create(); + + // FIXME: A context created like this shouldn't have a data store, + // instead there should be a WKPageConfigurationRef object that specifies the data store. + configuration->setShouldHaveLegacyDataStore(true); + + return toAPI(&configuration.leakRef()); +} + +WKStringRef WKContextConfigurationCopyDiskCacheDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->diskCacheDirectory()); +} + +void WKContextConfigurationSetDiskCacheDirectory(WKContextConfigurationRef configuration, WKStringRef diskCacheDirectory) +{ + toImpl(configuration)->setDiskCacheDirectory(toImpl(diskCacheDirectory)->string()); +} + +WKStringRef WKContextConfigurationCopyApplicationCacheDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->applicationCacheDirectory()); +} + +void WKContextConfigurationSetApplicationCacheDirectory(WKContextConfigurationRef configuration, WKStringRef applicationCacheDirectory) +{ + toImpl(configuration)->setApplicationCacheDirectory(toImpl(applicationCacheDirectory)->string()); +} + +WKStringRef WKContextConfigurationCopyIndexedDBDatabaseDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->indexedDBDatabaseDirectory()); +} + +void WKContextConfigurationSetIndexedDBDatabaseDirectory(WKContextConfigurationRef configuration, WKStringRef indexedDBDatabaseDirectory) +{ + toImpl(configuration)->setIndexedDBDatabaseDirectory(toImpl(indexedDBDatabaseDirectory)->string()); +} + +WKStringRef WKContextConfigurationCopyInjectedBundlePath(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->injectedBundlePath()); +} + +void WKContextConfigurationSetInjectedBundlePath(WKContextConfigurationRef configuration, WKStringRef injectedBundlePath) +{ + toImpl(configuration)->setInjectedBundlePath(toImpl(injectedBundlePath)->string()); +} + +WKStringRef WKContextConfigurationCopyLocalStorageDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->localStorageDirectory()); +} + +void WKContextConfigurationSetLocalStorageDirectory(WKContextConfigurationRef configuration, WKStringRef localStorageDirectory) +{ + toImpl(configuration)->setLocalStorageDirectory(toImpl(localStorageDirectory)->string()); +} + +WKStringRef WKContextConfigurationCopyWebSQLDatabaseDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->webSQLDatabaseDirectory()); +} + +void WKContextConfigurationSetWebSQLDatabaseDirectory(WKContextConfigurationRef configuration, WKStringRef webSQLDatabaseDirectory) +{ + toImpl(configuration)->setWebSQLDatabaseDirectory(toImpl(webSQLDatabaseDirectory)->string()); +} + +WKStringRef WKContextConfigurationCopyMediaKeysStorageDirectory(WKContextConfigurationRef configuration) +{ + return toCopiedAPI(toImpl(configuration)->mediaKeysStorageDirectory()); +} + +void WKContextConfigurationSetMediaKeysStorageDirectory(WKContextConfigurationRef configuration, WKStringRef mediaKeysStorageDirectory) +{ + toImpl(configuration)->setMediaKeysStorageDirectory(toImpl(mediaKeysStorageDirectory)->string()); +} + +bool WKContextConfigurationFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration) +{ + return toImpl(configuration)->fullySynchronousModeIsAllowedForTesting(); +} + +void WKContextConfigurationSetFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration, bool allowed) +{ + toImpl(configuration)->setFullySynchronousModeIsAllowedForTesting(allowed); +} + +WKArrayRef WKContextConfigurationCopyOverrideLanguages(WKContextConfigurationRef configuration) +{ + return toAPI(&API::Array::createStringArray(toImpl(configuration)->overrideLanguages()).leakRef()); +} + +void WKContextConfigurationSetOverrideLanguages(WKContextConfigurationRef configuration, WKArrayRef overrideLanguages) +{ + toImpl(configuration)->setOverrideLanguages(toImpl(overrideLanguages)->toStringVector()); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.h b/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.h new file mode 100644 index 000000000..1ee343a47 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKContextConfigurationRef_h +#define WKContextConfigurationRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKContextConfigurationRef WKContextConfigurationCreate(); + +WK_EXPORT WKStringRef WKContextConfigurationCopyApplicationCacheDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetApplicationCacheDirectory(WKContextConfigurationRef configuration, WKStringRef applicationCacheDirectory); + +WK_EXPORT WKStringRef WKContextConfigurationCopyDiskCacheDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetDiskCacheDirectory(WKContextConfigurationRef configuration, WKStringRef diskCacheDirectory); + +WK_EXPORT WKStringRef WKContextConfigurationCopyIndexedDBDatabaseDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetIndexedDBDatabaseDirectory(WKContextConfigurationRef configuration, WKStringRef indexedDBDatabaseDirectory); + +WK_EXPORT WKStringRef WKContextConfigurationCopyInjectedBundlePath(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetInjectedBundlePath(WKContextConfigurationRef configuration, WKStringRef injectedBundlePath); + +WK_EXPORT WKStringRef WKContextConfigurationCopyLocalStorageDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetLocalStorageDirectory(WKContextConfigurationRef configuration, WKStringRef localStorageDirectory); + +WK_EXPORT WKStringRef WKContextConfigurationCopyWebSQLDatabaseDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetWebSQLDatabaseDirectory(WKContextConfigurationRef configuration, WKStringRef webSQLDatabaseDirectory); + +WK_EXPORT WKStringRef WKContextConfigurationCopyMediaKeysStorageDirectory(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetMediaKeysStorageDirectory(WKContextConfigurationRef configuration, WKStringRef mediaKeysStorageDirectory); + +WK_EXPORT bool WKContextConfigurationFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration, bool allowed); + +WK_EXPORT WKArrayRef WKContextConfigurationCopyOverrideLanguages(WKContextConfigurationRef configuration); +WK_EXPORT void WKContextConfigurationSetOverrideLanguages(WKContextConfigurationRef configuration, WKArrayRef overrideLanguages); + +#ifdef __cplusplus +} +#endif + + +#endif // WKContextConfigurationRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKContextConnectionClient.h b/Source/WebKit2/UIProcess/API/C/WKContextConnectionClient.h index 82f79d63e..e7c576310 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextConnectionClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextConnectionClient.h @@ -26,7 +26,7 @@ #ifndef WKContextConnectionClient_h #define WKContextConnectionClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> typedef void (*WKContextDidCreateConnection)(WKContextRef context, WKConnectionRef connection, const void* clientInfo); @@ -42,13 +42,4 @@ typedef struct WKContextConnectionClientV0 { WKContextDidCreateConnection didCreateConnection; } WKContextConnectionClientV0; -enum { kWKContextConnectionClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKContextConnectionClient { - int version; - const void * clientInfo; - - // Version 0. - WKContextDidCreateConnection didCreateConnection; -} WKContextConnectionClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #endif // WKContextConnectionClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKContextDownloadClient.h b/Source/WebKit2/UIProcess/API/C/WKContextDownloadClient.h index 0aede7fb6..5bb8d83a8 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextDownloadClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextDownloadClient.h @@ -26,7 +26,7 @@ #ifndef WKContextDownloadClient_h #define WKContextDownloadClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> typedef void (*WKContextDownloadDidStartCallback)(WKContextRef context, WKDownloadRef download, const void *clientInfo); typedef void (*WKContextDownloadDidReceiveAuthenticationChallengeCallback)(WKContextRef context, WKDownloadRef download, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo); @@ -62,23 +62,4 @@ typedef struct WKContextDownloadClientV0 { WKContextDownloadProcessDidCrashCallback processDidCrash; } WKContextDownloadClientV0; -enum { kWKContextDownloadClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKContextDownloadClient { - int version; - const void * clientInfo; - - // Version 0. - WKContextDownloadDidStartCallback didStart; - WKContextDownloadDidReceiveAuthenticationChallengeCallback didReceiveAuthenticationChallenge; - WKContextDownloadDidReceiveResponseCallback didReceiveResponse; - WKContextDownloadDidReceiveDataCallback didReceiveData; - WKContextDownloadShouldDecodeSourceDataOfMIMETypeCallback shouldDecodeSourceDataOfMIMEType; - WKContextDownloadDecideDestinationWithSuggestedFilenameCallback decideDestinationWithSuggestedFilename; - WKContextDownloadDidCreateDestinationCallback didCreateDestination; - WKContextDownloadDidFinishCallback didFinish; - WKContextDownloadDidFailCallback didFail; - WKContextDownloadDidCancel didCancel; - WKContextDownloadProcessDidCrashCallback processDidCrash; -} WKContextDownloadClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #endif // WKContextDownloadClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKContextHistoryClient.h b/Source/WebKit2/UIProcess/API/C/WKContextHistoryClient.h index 821b0ab42..0558efdba 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextHistoryClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextHistoryClient.h @@ -26,7 +26,7 @@ #ifndef WKContextHistoryClient_h #define WKContextHistoryClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> typedef void (*WKContextDidNavigateWithNavigationDataCallback)(WKContextRef context, WKPageRef page, WKNavigationDataRef navigationData, WKFrameRef frame, const void *clientInfo); typedef void (*WKContextDidPerformClientRedirectCallback)(WKContextRef context, WKPageRef page, WKURLRef sourceURL, WKURLRef destinationURL, WKFrameRef frame, const void *clientInfo); @@ -50,17 +50,4 @@ typedef struct WKContextHistoryClientV0 { WKContextPopulateVisitedLinksCallback populateVisitedLinks; } WKContextHistoryClientV0; -enum { kWKContextHistoryClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKContextHistoryClient { - int version; - const void * clientInfo; - - // Version 0. - WKContextDidNavigateWithNavigationDataCallback didNavigateWithNavigationData; - WKContextDidPerformClientRedirectCallback didPerformClientRedirect; - WKContextDidPerformServerRedirectCallback didPerformServerRedirect; - WKContextDidUpdateHistoryTitleCallback didUpdateHistoryTitle; - WKContextPopulateVisitedLinksCallback populateVisitedLinks; -} WKContextHistoryClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #endif // WKContextHistoryClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKContextInjectedBundleClient.h b/Source/WebKit2/UIProcess/API/C/WKContextInjectedBundleClient.h index d48f8e7bc..d3456aa68 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextInjectedBundleClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextInjectedBundleClient.h @@ -26,7 +26,7 @@ #ifndef WKContextInjectedBundleClient_h #define WKContextInjectedBundleClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> // Injected Bundle Client typedef void (*WKContextDidReceiveMessageFromInjectedBundleCallback)(WKContextRef page, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo); @@ -57,17 +57,4 @@ typedef struct WKContextInjectedBundleClientV1 { WKContextGetInjectedBundleInitializationUserDataCallback getInjectedBundleInitializationUserData; } WKContextInjectedBundleClientV1; -enum { kWKContextInjectedBundleClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 1 }; -typedef struct WKContextInjectedBundleClient { - int version; - const void * clientInfo; - - // Version 0. - WKContextDidReceiveMessageFromInjectedBundleCallback didReceiveMessageFromInjectedBundle; - WKContextDidReceiveSynchronousMessageFromInjectedBundleCallback didReceiveSynchronousMessageFromInjectedBundle; - - // Version 1. - WKContextGetInjectedBundleInitializationUserDataCallback getInjectedBundleInitializationUserData; -} WKContextInjectedBundleClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #endif // WKContextInjectedBundleClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKColorPickerResultListener.cpp b/Source/WebKit2/UIProcess/API/C/WKContextMenuListener.cpp index 07bfe3c9e..4d067a7c9 100644 --- a/Source/WebKit2/UIProcess/API/C/WKColorPickerResultListener.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKContextMenuListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS @@ -24,28 +24,28 @@ */ #include "config.h" -#include "WKColorPickerResultListener.h" +#include "WKContextMenuListener.h" #include "WKAPICast.h" -#include "WebColorPickerResultListenerProxy.h" +#include "WebContextMenuListenerProxy.h" using namespace WebKit; -WKTypeID WKColorPickerResultListenerGetTypeID() +WKTypeID WKContextMenuListenerGetTypeID() { -#if ENABLE(INPUT_TYPE_COLOR) - return toAPI(WebColorPickerResultListenerProxy::APIType); +#if ENABLE(CONTEXT_MENUS) + return toAPI(WebContextMenuListenerProxy::APIType); #else - return 0; + return toAPI(API::Object::Type::Null); #endif } -void WKColorPickerResultListenerSetColor(WKColorPickerResultListenerRef listenerRef, const WKStringRef color) +void WKContextMenuListenerUseContextMenuItems(WKContextMenuListenerRef listenerRef, WKArrayRef items) { -#if ENABLE(INPUT_TYPE_COLOR) - toImpl(listenerRef)->setColor(toWTFString(color)); +#if ENABLE(CONTEXT_MENUS) + toImpl(listenerRef)->useContextMenuItems(items); #else UNUSED_PARAM(listenerRef); - UNUSED_PARAM(color); + UNUSED_PARAM(items); #endif } diff --git a/Source/WebKit2/UIProcess/API/C/WKContextMenuListener.h b/Source/WebKit2/UIProcess/API/C/WKContextMenuListener.h new file mode 100644 index 000000000..2b50d7dc2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKContextMenuListener.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKContextMenuListenerGetTypeID(); + +WK_EXPORT void WKContextMenuListenerUseContextMenuItems(WKContextMenuListenerRef, WKArrayRef); + +#ifdef __cplusplus +} +#endif diff --git a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h index 9189163fd..4d8048afc 100644 --- a/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKContextPrivate.h @@ -26,8 +26,8 @@ #ifndef WKContextPrivate_h #define WKContextPrivate_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKContext.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKContext.h> #ifdef __cplusplus extern "C" { @@ -52,18 +52,22 @@ WK_EXPORT void WKContextSetShouldUseFontSmoothing(WKContextRef context, bool use WK_EXPORT void WKContextRegisterURLSchemeAsSecure(WKContextRef context, WKStringRef urlScheme); +WK_EXPORT void WKContextRegisterURLSchemeAsBypassingContentSecurityPolicy(WKContextRef context, WKStringRef urlScheme); + +WK_EXPORT void WKContextRegisterURLSchemeAsCachePartitioned(WKContextRef context, WKStringRef urlScheme); + WK_EXPORT void WKContextSetDomainRelaxationForbiddenForURLScheme(WKContextRef context, WKStringRef urlScheme); +WK_EXPORT void WKContextSetCanHandleHTTPSServerTrustEvaluation(WKContextRef context, bool value); + +WK_EXPORT void WKContextSetDiskCacheSpeculativeValidationEnabled(WKContextRef context, bool value); + +WK_EXPORT void WKContextSetUnresponsiveBackgroundProcessesTerminationEnabled(WKContextRef context, bool value); + WK_EXPORT void WKContextSetIconDatabasePath(WKContextRef context, WKStringRef iconDatabasePath); WK_EXPORT void WKContextAllowSpecificHTTPSCertificateForHost(WKContextRef context, WKCertificateInfoRef certificate, WKStringRef host); -// FIXME: These functions are only effective if called before the Web process is launched. But -// we should really change these settings to be on WebPreferences and changeable at runtime. -WK_EXPORT void WKContextSetApplicationCacheDirectory(WKContextRef context, WKStringRef applicationCacheDirectory); -WK_EXPORT void WKContextSetDatabaseDirectory(WKContextRef context, WKStringRef databaseDirectory); -WK_EXPORT void WKContextSetLocalStorageDirectory(WKContextRef context, WKStringRef localStorageDirectory); -WK_EXPORT void WKContextSetDiskCacheDirectory(WKContextRef context, WKStringRef diskCacheDirectory); WK_EXPORT void WKContextSetCookieStorageDirectory(WKContextRef context, WKStringRef cookieStorageDirectory); // FIXME: This is a workaround for testing purposes only and should be removed once a better @@ -77,16 +81,24 @@ WK_EXPORT void WKContextWarmInitialProcess(WKContextRef context); // FIXME: This function is temporary and useful during the development of the NetworkProcess feature. // At some point it should be removed. -WK_EXPORT void WKContextSetUsesNetworkProcess(WKContextRef context, bool usesNetworkProcess); +WK_EXPORT void WKContextSetUsesNetworkProcess(WKContextRef, bool); // Test only. Should be called before any secondary processes are started. WK_EXPORT void WKContextUseTestingNetworkSession(WKContextRef context); +// Test only. Should be called before running a test. +WK_EXPORT void WKContextClearCachedCredentials(WKContextRef context); + typedef void (*WKContextInvalidMessageFunction)(WKStringRef messageName); WK_EXPORT void WKContextSetInvalidMessageFunction(WKContextInvalidMessageFunction invalidMessageFunction); WK_EXPORT void WKContextSetMemoryCacheDisabled(WKContextRef, bool disabled); +WK_EXPORT void WKContextSetFontWhitelist(WKContextRef, WKArrayRef); + +WK_EXPORT pid_t WKContextGetNetworkProcessIdentifier(WKContextRef context); +WK_EXPORT pid_t WKContextGetDatabaseProcessIdentifier(WKContextRef context); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKCookieManager.cpp b/Source/WebKit2/UIProcess/API/C/WKCookieManager.cpp index ed2770f5d..7624beee9 100644 --- a/Source/WebKit2/UIProcess/API/C/WKCookieManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKCookieManager.cpp @@ -43,17 +43,25 @@ void WKCookieManagerSetClient(WKCookieManagerRef cookieManagerRef, const WKCooki void WKCookieManagerGetHostnamesWithCookies(WKCookieManagerRef cookieManagerRef, void* context, WKCookieManagerGetCookieHostnamesFunction callback) { - toImpl(cookieManagerRef)->getHostnamesWithCookies(ArrayCallback::create(context, callback)); + toImpl(cookieManagerRef)->getHostnamesWithCookies(WebCore::SessionID::defaultSessionID(), toGenericCallbackFunction(context, callback)); } void WKCookieManagerDeleteCookiesForHostname(WKCookieManagerRef cookieManagerRef, WKStringRef hostname) { - toImpl(cookieManagerRef)->deleteCookiesForHostname(toImpl(hostname)->string()); + toImpl(cookieManagerRef)->deleteCookiesForHostname(WebCore::SessionID::defaultSessionID(), toImpl(hostname)->string()); } void WKCookieManagerDeleteAllCookies(WKCookieManagerRef cookieManagerRef) { - toImpl(cookieManagerRef)->deleteAllCookies(); + toImpl(cookieManagerRef)->deleteAllCookies(WebCore::SessionID::defaultSessionID()); +} + +void WKCookieManagerDeleteAllCookiesModifiedAfterDate(WKCookieManagerRef cookieManagerRef, double date) +{ + using namespace std::chrono; + + auto time = system_clock::time_point(duration_cast<system_clock::duration>(duration<double>(date))); + toImpl(cookieManagerRef)->deleteAllCookiesModifiedSince(WebCore::SessionID::defaultSessionID(), time); } void WKCookieManagerSetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, WKHTTPCookieAcceptPolicy policy) @@ -63,15 +71,15 @@ void WKCookieManagerSetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, void WKCookieManagerGetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, void* context, WKCookieManagerGetHTTPCookieAcceptPolicyFunction callback) { - toImpl(cookieManager)->getHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicyCallback::create(context, callback)); + toImpl(cookieManager)->getHTTPCookieAcceptPolicy(toGenericCallbackFunction<WKHTTPCookieAcceptPolicy, HTTPCookieAcceptPolicy>(context, callback)); } void WKCookieManagerStartObservingCookieChanges(WKCookieManagerRef cookieManager) { - toImpl(cookieManager)->startObservingCookieChanges(); + toImpl(cookieManager)->startObservingCookieChanges(WebCore::SessionID::defaultSessionID()); } void WKCookieManagerStopObservingCookieChanges(WKCookieManagerRef cookieManager) { - toImpl(cookieManager)->stopObservingCookieChanges(); + toImpl(cookieManager)->stopObservingCookieChanges(WebCore::SessionID::defaultSessionID()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKCookieManager.h b/Source/WebKit2/UIProcess/API/C/WKCookieManager.h index 6f302a2ce..8f4111c3f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKCookieManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKCookieManager.h @@ -26,7 +26,7 @@ #ifndef WKCookieManager_h #define WKCookieManager_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -55,15 +55,6 @@ typedef struct WKCookieManagerClientV0 { WKCookieManagerCookiesDidChangeCallback cookiesDidChange; } WKCookieManagerClientV0; -enum { kWKCookieManagerClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKCookieManagerClient { - int version; - const void * clientInfo; - - // Version 0. - WKCookieManagerCookiesDidChangeCallback cookiesDidChange; -} WKCookieManagerClient WK_DEPRECATED("Use an explicit versioned struct instead"); - WK_EXPORT WKTypeID WKCookieManagerGetTypeID(); WK_EXPORT void WKCookieManagerSetClient(WKCookieManagerRef cookieManager, const WKCookieManagerClientBase* client); @@ -74,6 +65,9 @@ WK_EXPORT void WKCookieManagerGetHostnamesWithCookies(WKCookieManagerRef cookieM WK_EXPORT void WKCookieManagerDeleteCookiesForHostname(WKCookieManagerRef cookieManager, WKStringRef hostname); WK_EXPORT void WKCookieManagerDeleteAllCookies(WKCookieManagerRef cookieManager); +// The time here is relative to the Unix epoch. +WK_EXPORT void WKCookieManagerDeleteAllCookiesModifiedAfterDate(WKCookieManagerRef cookieManager, double); + WK_EXPORT void WKCookieManagerSetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, WKHTTPCookieAcceptPolicy policy); typedef void (*WKCookieManagerGetHTTPCookieAcceptPolicyFunction)(WKHTTPCookieAcceptPolicy, WKErrorRef, void*); WK_EXPORT void WKCookieManagerGetHTTPCookieAcceptPolicy(WKCookieManagerRef cookieManager, void* context, WKCookieManagerGetHTTPCookieAcceptPolicyFunction callback); diff --git a/Source/WebKit2/UIProcess/API/C/WKCredential.cpp b/Source/WebKit2/UIProcess/API/C/WKCredential.cpp index 6a956003b..35ecb203b 100644 --- a/Source/WebKit2/UIProcess/API/C/WKCredential.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKCredential.cpp @@ -40,18 +40,16 @@ WKTypeID WKCredentialGetTypeID() WKCredentialRef WKCredentialCreate(WKStringRef username, WKStringRef password, WKCredentialPersistence persistence) { - RefPtr<WebCredential> credential = WebCredential::create(toImpl(username), toImpl(password), toCredentialPersistence(persistence)); - return toAPI(credential.release().leakRef()); + return toAPI(&WebCredential::create(WebCore::Credential(toImpl(username)->string(), toImpl(password)->string(), toCredentialPersistence(persistence))).leakRef()); } WKCredentialRef WKCredentialCreateWithCertificateInfo(WKCertificateInfoRef certificateInfo) { - RefPtr<WebCredential> credential = WebCredential::create(toImpl(certificateInfo)); - return toAPI(credential.release().leakRef()); + return toAPI(&WebCredential::create(toImpl(certificateInfo)).leakRef()); } WKStringRef WKCredentialCopyUser(WKCredentialRef credentialRef) { - return toCopiedAPI(toImpl(credentialRef)->user()); + return toCopiedAPI(toImpl(credentialRef)->credential().user()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKCredential.h b/Source/WebKit2/UIProcess/API/C/WKCredential.h index 560fc419a..57842fbda 100644 --- a/Source/WebKit2/UIProcess/API/C/WKCredential.h +++ b/Source/WebKit2/UIProcess/API/C/WKCredential.h @@ -26,8 +26,8 @@ #ifndef WKCredential_h #define WKCredential_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKCredentialTypes.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKCredentialTypes.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.cpp b/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.cpp deleted file mode 100644 index 5aa9dcf6b..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WKDatabaseManager.h" - -#include "WebDatabaseManagerProxy.h" -#include "WKAPICast.h" - -using namespace WebKit; - -WKTypeID WKDatabaseManagerGetTypeID() -{ -#if ENABLE(SQL_DATABASE) - return toAPI(WebDatabaseManagerProxy::APIType); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetOriginKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::originKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetOriginQuotaKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::originQuotaKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetOriginUsageKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::originUsageKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsNameKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsNameKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsDisplayNameKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsDisplayNameKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsExpectedUsageKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsExpectedUsageKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsCurrentUsageKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsCurrentUsageKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsCreationTimeKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsCreationTimeKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -WKStringRef WKDatabaseManagerGetDatabaseDetailsModificationTimeKey() -{ -#if ENABLE(SQL_DATABASE) - static API::String* key = API::String::create(WebDatabaseManagerProxy::databaseDetailsModificationTimeKey()).leakRef(); - return toAPI(key); -#else - return 0; -#endif -} - -void WKDatabaseManagerSetClient(WKDatabaseManagerRef databaseManagerRef, const WKDatabaseManagerClientBase* wkClient) -{ -#if ENABLE(SQL_DATABASE) - if (wkClient && wkClient->version) - return; - toImpl(databaseManagerRef)->initializeClient(wkClient); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(wkClient); -#endif -} - -void WKDatabaseManagerGetDatabasesByOrigin(WKDatabaseManagerRef databaseManagerRef, void* context, WKDatabaseManagerGetDatabasesByOriginFunction callback) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->getDatabasesByOrigin(ArrayCallback::create(context, callback)); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(context); - UNUSED_PARAM(callback); -#endif -} - -void WKDatabaseManagerGetDatabaseOrigins(WKDatabaseManagerRef databaseManagerRef, void* context, WKDatabaseManagerGetDatabaseOriginsFunction callback) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->getDatabaseOrigins(ArrayCallback::create(context, callback)); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(context); - UNUSED_PARAM(callback); -#endif -} - -void WKDatabaseManagerDeleteDatabasesWithNameForOrigin(WKDatabaseManagerRef databaseManagerRef, WKStringRef databaseNameRef, WKSecurityOriginRef originRef) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->deleteDatabaseWithNameForOrigin(toWTFString(databaseNameRef), toImpl(originRef)); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(databaseNameRef); - UNUSED_PARAM(originRef); -#endif -} - -void WKDatabaseManagerDeleteDatabasesForOrigin(WKDatabaseManagerRef databaseManagerRef, WKSecurityOriginRef originRef) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->deleteDatabasesForOrigin(toImpl(originRef)); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(originRef); -#endif -} - -void WKDatabaseManagerDeleteAllDatabases(WKDatabaseManagerRef databaseManagerRef) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->deleteAllDatabases(); -#else - UNUSED_PARAM(databaseManagerRef); -#endif -} - -void WKDatabaseManagerSetQuotaForOrigin(WKDatabaseManagerRef databaseManagerRef, WKSecurityOriginRef originRef, uint64_t quota) -{ -#if ENABLE(SQL_DATABASE) - toImpl(databaseManagerRef)->setQuotaForOrigin(toImpl(originRef), quota); -#else - UNUSED_PARAM(databaseManagerRef); - UNUSED_PARAM(originRef); - UNUSED_PARAM(quota); -#endif -} diff --git a/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.h b/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.h deleted file mode 100644 index 12f2dbc83..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKDatabaseManager.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKDatabaseManager_h -#define WKDatabaseManager_h - -#include <WebKit2/WKBase.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* Value type: WKSecurityOriginRef */ -WK_EXPORT WKStringRef WKDatabaseManagerGetOriginKey(); - -/* Value type: WKUInt64Ref */ -WK_EXPORT WKStringRef WKDatabaseManagerGetOriginQuotaKey(); - -/* Value type: WKUInt64Ref */ -WK_EXPORT WKStringRef WKDatabaseManagerGetOriginUsageKey(); - -/* Value type: WKArrayRef (array of WKDictionaryRef's with keys that include: - - WKDatabaseManagerGetDatabaseNameKey() - - WKDatabaseManagerGetDatabaseDisplayNameKey() - - WKDatabaseManagerGetDatabaseExpectedUsageKey() - - WKDatabaseManagerGetDatabaseCurrentUsageKey() - */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsKey(); - -/* Value type: WKStringRef */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsNameKey(); - -/* Value type: WKStringRef */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsDisplayNameKey(); - -/* Value type: WKUInt64Ref */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsExpectedUsageKey(); - -/* Value type: WKUInt64Ref */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsCurrentUsageKey(); - -/* Value type: WKDoubleRef, seconds since January 1st, 1970 UTC */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsCreationTimeKey(); - -/* Value type: WKDoubleRef, seconds since January 1st, 1970 UTC */ -WK_EXPORT WKStringRef WKDatabaseManagerGetDatabaseDetailsModificationTimeKey(); - - -// Database Manager Client -typedef void (*WKDatabaseManagerDidModifyOriginCallback)(WKDatabaseManagerRef databaseManager, WKSecurityOriginRef origin, const void *clientInfo); -typedef void (*WKDatabaseManagerDidModifyDatabaseCallback)(WKDatabaseManagerRef databaseManager, WKSecurityOriginRef origin, WKStringRef databaseIdentifier, const void *clientInfo); - -typedef struct WKDatabaseManagerClientBase { - int version; - const void * clientInfo; -} WKDatabaseManagerClientBase; - -typedef struct WKDatabaseManagerClientV0 { - WKDatabaseManagerClientBase base; - - // Version 0. - WKDatabaseManagerDidModifyOriginCallback didModifyOrigin; - WKDatabaseManagerDidModifyDatabaseCallback didModifyDatabase; -} WKDatabaseManagerClientV0; - -enum { kWKDatabaseManagerClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKDatabaseManagerClient { - int version; - const void * clientInfo; - - // Version 0. - WKDatabaseManagerDidModifyOriginCallback didModifyOrigin; - WKDatabaseManagerDidModifyDatabaseCallback didModifyDatabase; -} WKDatabaseManagerClient WK_DEPRECATED("Use an explicit versioned struct instead"); - -WK_EXPORT WKTypeID WKDatabaseManagerGetTypeID(); - -WK_EXPORT void WKDatabaseManagerSetClient(WKDatabaseManagerRef databaseManager, const WKDatabaseManagerClientBase* client); - -typedef void (*WKDatabaseManagerGetDatabasesByOriginFunction)(WKArrayRef, WKErrorRef, void*); -WK_EXPORT void WKDatabaseManagerGetDatabasesByOrigin(WKDatabaseManagerRef databaseManager, void* context, WKDatabaseManagerGetDatabasesByOriginFunction function); - -typedef void (*WKDatabaseManagerGetDatabaseOriginsFunction)(WKArrayRef, WKErrorRef, void*); -WK_EXPORT void WKDatabaseManagerGetDatabaseOrigins(WKDatabaseManagerRef contextRef, void* context, WKDatabaseManagerGetDatabaseOriginsFunction function); - -WK_EXPORT void WKDatabaseManagerDeleteDatabasesWithNameForOrigin(WKDatabaseManagerRef databaseManager, WKStringRef databaseName, WKSecurityOriginRef origin); -WK_EXPORT void WKDatabaseManagerDeleteDatabasesForOrigin(WKDatabaseManagerRef databaseManager, WKSecurityOriginRef origin); -WK_EXPORT void WKDatabaseManagerDeleteAllDatabases(WKDatabaseManagerRef databaseManager); - -WK_EXPORT void WKDatabaseManagerSetQuotaForOrigin(WKDatabaseManagerRef databaseManager, WKSecurityOriginRef origin, uint64_t quota); - -#ifdef __cplusplus -} -#endif - -#endif // WKDatabaseManager_h diff --git a/Source/WebKit2/UIProcess/API/C/WKDownload.cpp b/Source/WebKit2/UIProcess/API/C/WKDownload.cpp index 84e9103c4..abf93f12f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKDownload.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKDownload.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "WKDownload.h" +#include "APIData.h" #include "APIURLRequest.h" #include "DownloadProxy.h" #include "WKAPICast.h" @@ -39,12 +40,12 @@ WKTypeID WKDownloadGetTypeID() uint64_t WKDownloadGetID(WKDownloadRef download) { - return toImpl(download)->downloadID(); + return toImpl(download)->downloadID().downloadID(); } WKURLRequestRef WKDownloadCopyRequest(WKDownloadRef download) { - return toAPI(API::URLRequest::create(toImpl(download)->request()).leakRef()); + return toAPI(&API::URLRequest::create(toImpl(download)->request()).leakRef()); } WKDataRef WKDownloadGetResumeData(WKDownloadRef download) diff --git a/Source/WebKit2/UIProcess/API/C/WKDownload.h b/Source/WebKit2/UIProcess/API/C/WKDownload.h index 8acc9106d..5dbea7e44 100644 --- a/Source/WebKit2/UIProcess/API/C/WKDownload.h +++ b/Source/WebKit2/UIProcess/API/C/WKDownload.h @@ -26,7 +26,7 @@ #ifndef WKDownload_h #define WKDownload_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifndef __cplusplus #include <stdbool.h> diff --git a/Source/WebKit2/UIProcess/API/C/WKFormSubmissionListener.h b/Source/WebKit2/UIProcess/API/C/WKFormSubmissionListener.h index 4b9b79acb..c320b68d4 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFormSubmissionListener.h +++ b/Source/WebKit2/UIProcess/API/C/WKFormSubmissionListener.h @@ -26,7 +26,7 @@ #ifndef WKFormSubmissionListener_h #define WKFormSubmissionListener_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKFrame.cpp b/Source/WebKit2/UIProcess/API/C/WKFrame.cpp index 2f74c6df7..a8562ea7f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFrame.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKFrame.cpp @@ -26,8 +26,13 @@ #include "config.h" #include "WKFrame.h" +#include "APIData.h" +#include "APIFrameHandle.h" +#include "APIFrameInfo.h" #include "WKAPICast.h" +#include "WebCertificateInfo.h" #include "WebFrameProxy.h" +#include "WebPageProxy.h" using namespace WebKit; @@ -44,7 +49,7 @@ bool WKFrameIsMainFrame(WKFrameRef frameRef) WKFrameLoadState WKFrameGetFrameLoadState(WKFrameRef frameRef) { WebFrameProxy* frame = toImpl(frameRef); - switch (frame->frameLoadState().m_state) { + switch (frame->frameLoadState().state()) { case FrameLoadState::State::Provisional: return kWKFrameLoadStateProvisional; case FrameLoadState::State::Committed: @@ -122,29 +127,27 @@ bool WKFrameIsFrameSet(WKFrameRef frameRef) return toImpl(frameRef)->isFrameSet(); } -void WKFrameGetMainResourceData(WKFrameRef frameRef, WKFrameGetResourceDataFunction callback, void* context) +WKFrameHandleRef WKFrameCreateFrameHandle(WKFrameRef frameRef) { - toImpl(frameRef)->getMainResourceData(DataCallback::create(context, callback)); + return toAPI(&API::FrameHandle::create(toImpl(frameRef)->frameID()).leakRef()); } -void WKFrameGetResourceData(WKFrameRef frameRef, WKURLRef resourceURL, WKFrameGetResourceDataFunction callback, void* context) +WKFrameInfoRef WKFrameCreateFrameInfo(WKFrameRef frameRef) { - toImpl(frameRef)->getResourceData(toImpl(resourceURL), DataCallback::create(context, callback)); + return toAPI(&API::FrameInfo::create(*toImpl(frameRef), WebCore::SecurityOrigin::createFromString(toImpl(frameRef)->url())).leakRef()); } -void WKFrameGetWebArchive(WKFrameRef frameRef, WKFrameGetWebArchiveFunction callback, void* context) +void WKFrameGetMainResourceData(WKFrameRef frameRef, WKFrameGetResourceDataFunction callback, void* context) { - toImpl(frameRef)->getWebArchive(DataCallback::create(context, callback)); + toImpl(frameRef)->getMainResourceData(toGenericCallbackFunction(context, callback)); } -// NOTE: These are deprecated and should be removed. They currently do nothing. - -WKArrayRef WKFrameCopyChildFrames(WKFrameRef) +void WKFrameGetResourceData(WKFrameRef frameRef, WKURLRef resourceURL, WKFrameGetResourceDataFunction callback, void* context) { - return 0; + toImpl(frameRef)->getResourceData(toImpl(resourceURL), toGenericCallbackFunction(context, callback)); } -WKFrameRef WKFrameGetParentFrame(WKFrameRef) +void WKFrameGetWebArchive(WKFrameRef frameRef, WKFrameGetWebArchiveFunction callback, void* context) { - return 0; + toImpl(frameRef)->getWebArchive(toGenericCallbackFunction(context, callback)); } diff --git a/Source/WebKit2/UIProcess/API/C/WKFrame.h b/Source/WebKit2/UIProcess/API/C/WKFrame.h index 5f169e48e..b987ddc63 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFrame.h +++ b/Source/WebKit2/UIProcess/API/C/WKFrame.h @@ -26,7 +26,7 @@ #ifndef WKFrame_h #define WKFrame_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifndef __cplusplus #include <stdbool.h> @@ -68,6 +68,9 @@ WK_EXPORT bool WKFrameIsDisplayingMarkupDocument(WKFrameRef frame); WK_EXPORT bool WKFrameIsFrameSet(WKFrameRef frame); +WK_EXPORT WKFrameHandleRef WKFrameCreateFrameHandle(WKFrameRef frame); +WK_EXPORT WKFrameInfoRef WKFrameCreateFrameInfo(WKFrameRef frame); + typedef void (*WKFrameGetResourceDataFunction)(WKDataRef data, WKErrorRef error, void* functionContext); WK_EXPORT void WKFrameGetMainResourceData(WKFrameRef frame, WKFrameGetResourceDataFunction function, void* functionContext); WK_EXPORT void WKFrameGetResourceData(WKFrameRef frame, WKURLRef resourceURL, WKFrameGetResourceDataFunction function, void* functionContext); @@ -75,11 +78,6 @@ WK_EXPORT void WKFrameGetResourceData(WKFrameRef frame, WKURLRef resourceURL, WK typedef void (*WKFrameGetWebArchiveFunction)(WKDataRef archiveData, WKErrorRef error, void* functionContext); WK_EXPORT void WKFrameGetWebArchive(WKFrameRef frame, WKFrameGetWebArchiveFunction function, void* functionContext); -// NOTE: These are deprecated and should be removed. They currently do nothing. - -WK_EXPORT WKArrayRef WKFrameCopyChildFrames(WKFrameRef frame); -WK_EXPORT WKFrameRef WKFrameGetParentFrame(WKFrameRef frame); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/WebOriginDataManagerProxyChangeClient.cpp b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.cpp index f1ee820e8..b39fca1be 100644 --- a/Source/WebKit2/UIProcess/WebOriginDataManagerProxyChangeClient.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,18 +24,19 @@ */ #include "config.h" -#include "WebOriginDataManagerProxyChangeClient.h" +#include "WKFrameHandleRef.h" +#include "APIFrameHandle.h" #include "WKAPICast.h" -namespace WebKit { +using namespace WebKit; -void WebOriginDataManagerProxyChangeClient::didChange(WebOriginDataManagerProxy* originDataManager) +WKTypeID WKFrameHandleGetTypeID() { - if (!m_client.didChange) - return; - - m_client.didChange(toAPI(originDataManager), m_client.base.clientInfo); + return toAPI(API::FrameHandle::APIType); } -} // namespace WebKit +uint64_t WKFrameHandleGetFrameID(WKFrameHandleRef frameHandleRef) +{ + return toImpl(frameHandleRef)->frameID(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKNetworkInfo.h b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.h index cff864a75..30791a97e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNetworkInfo.h +++ b/Source/WebKit2/UIProcess/API/C/WKFrameHandleRef.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,21 +23,21 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKNetworkInfo_h -#define WKNetworkInfo_h +#ifndef WKFrameHandleRef_h +#define WKFrameHandleRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT WKTypeID WKNetworkInfoGetTypeID(); +WK_EXPORT WKTypeID WKFrameHandleGetTypeID(); -WK_EXPORT WKNetworkInfoRef WKNetworkInfoCreate(double bandwidth, bool isMetered); +WK_EXPORT uint64_t WKFrameHandleGetFrameID(WKFrameHandleRef); #ifdef __cplusplus } #endif -#endif // WKNetworkInfo_h +#endif // WKFrameHandleRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.cpp b/Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.cpp new file mode 100644 index 000000000..6ba5175bf --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKFrameInfoRef.h" + +#include "APIFrameHandle.h" +#include "APIFrameInfo.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKTypeID WKFrameInfoGetTypeID() +{ + return toAPI(API::FrameInfo::APIType); +} + +WKFrameHandleRef WKFrameInfoGetFrameHandleRef(WKFrameInfoRef frameInfoRef) +{ + return toAPI(&toImpl(frameInfoRef)->handle()); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKBatteryStatus.h b/Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.h index afa1dd931..e95472ecb 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBatteryStatus.h +++ b/Source/WebKit2/UIProcess/API/C/WKFrameInfoRef.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,21 +23,21 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKBatteryStatus_h -#define WKBatteryStatus_h +#ifndef WKFrameInfoRef_h +#define WKFrameInfoRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT WKTypeID WKBatteryStatusGetTypeID(); +WK_EXPORT WKTypeID WKFrameInfoGetTypeID(); -WK_EXPORT WKBatteryStatusRef WKBatteryStatusCreate(bool isCharging, double chargingTime, double dischargingTime, double level); +WK_EXPORT WKFrameHandleRef WKFrameInfoGetFrameHandleRef(WKFrameInfoRef); #ifdef __cplusplus } #endif -#endif // WKBatteryStatus_h +#endif // WKFrameInfoRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.cpp b/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.cpp index 3bb673099..b654beb8b 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,9 +26,11 @@ #include "config.h" #include "WKFramePolicyListener.h" +#include "APIWebsitePolicies.h" #include "WKAPICast.h" #include "WebFramePolicyListenerProxy.h" #include "WebFrameProxy.h" +#include "WebsitePolicies.h" using namespace WebKit; @@ -39,7 +41,12 @@ WKTypeID WKFramePolicyListenerGetTypeID() void WKFramePolicyListenerUse(WKFramePolicyListenerRef policyListenerRef) { - toImpl(policyListenerRef)->use(); + toImpl(policyListenerRef)->use({ }); +} + +void WKFramePolicyListenerUseWithPolicies(WKFramePolicyListenerRef policyListenerRef, WKWebsitePoliciesRef websitePolicies) +{ + toImpl(policyListenerRef)->use(toImpl(websitePolicies)->websitePolicies()); } void WKFramePolicyListenerDownload(WKFramePolicyListenerRef policyListenerRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.h b/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.h index 99b013d54..9d2ccfcad 100644 --- a/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.h +++ b/Source/WebKit2/UIProcess/API/C/WKFramePolicyListener.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,10 +23,9 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKFramePolicyListener_h -#define WKFramePolicyListener_h +#pragma once -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -34,12 +33,11 @@ extern "C" { WK_EXPORT WKTypeID WKFramePolicyListenerGetTypeID(); -WK_EXPORT void WKFramePolicyListenerUse(WKFramePolicyListenerRef policyListener); -WK_EXPORT void WKFramePolicyListenerDownload(WKFramePolicyListenerRef policyListener); -WK_EXPORT void WKFramePolicyListenerIgnore(WKFramePolicyListenerRef policyListener); +WK_EXPORT void WKFramePolicyListenerUse(WKFramePolicyListenerRef); +WK_EXPORT void WKFramePolicyListenerDownload(WKFramePolicyListenerRef); +WK_EXPORT void WKFramePolicyListenerIgnore(WKFramePolicyListenerRef); +WK_EXPORT void WKFramePolicyListenerUseWithPolicies(WKFramePolicyListenerRef, WKWebsitePoliciesRef); #ifdef __cplusplus } #endif - -#endif /* WKFramePolicyListener_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.cpp b/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.cpp index 968bd920a..18b1a09bc 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.cpp @@ -28,6 +28,7 @@ #include "WKAPICast.h" #include "WebGeolocationManagerProxy.h" +#include "WebGeolocationPosition.h" using namespace WebKit; diff --git a/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.h b/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.h index f8c191790..581ae0472 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKGeolocationManager.h @@ -26,7 +26,7 @@ #ifndef WKGeolocationManager_h #define WKGeolocationManager_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -61,17 +61,6 @@ typedef struct WKGeolocationProviderV1 { WKGeolocationProviderSetEnableHighAccuracyCallback setEnableHighAccuracy; } WKGeolocationProviderV1; -enum { kWKGeolocationProviderCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 1 }; -typedef struct WKGeolocationProvider { - int version; - const void * clientInfo; - WKGeolocationProviderStartUpdatingCallback startUpdating; - WKGeolocationProviderStopUpdatingCallback stopUpdating; - - // Version 1. - WKGeolocationProviderSetEnableHighAccuracyCallback setEnableHighAccuracy; -} WKGeolocationProvider WK_DEPRECATED("Use an explicit versioned struct instead"); - WK_EXPORT WKTypeID WKGeolocationManagerGetTypeID(); diff --git a/Source/WebKit2/UIProcess/API/C/WKGeolocationPermissionRequest.h b/Source/WebKit2/UIProcess/API/C/WKGeolocationPermissionRequest.h index ee27b66ec..b1391813a 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGeolocationPermissionRequest.h +++ b/Source/WebKit2/UIProcess/API/C/WKGeolocationPermissionRequest.h @@ -26,7 +26,7 @@ #ifndef WKGeolocationPermissionRequest_h #define WKGeolocationPermissionRequest_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.cpp b/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.cpp index 5d94f3e86..8b4c5b650 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.cpp @@ -43,6 +43,6 @@ WKGeolocationPositionRef WKGeolocationPositionCreate(double timestamp, double la WKGeolocationPositionRef WKGeolocationPositionCreate_b(double timestamp, double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed) { - RefPtr<WebGeolocationPosition> position = WebGeolocationPosition::create(timestamp, latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); - return toAPI(position.release().leakRef()); + auto position = WebGeolocationPosition::create(timestamp, latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed); + return toAPI(position.leakRef()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.h b/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.h index 4727e9763..6d67f1d1e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.h +++ b/Source/WebKit2/UIProcess/API/C/WKGeolocationPosition.h @@ -26,7 +26,7 @@ #ifndef WKGeolocationPosition_h #define WKGeolocationPosition_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.cpp b/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.cpp index 193af2eb7..afd9895dd 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.cpp @@ -40,8 +40,8 @@ WKTypeID WKGrammarDetailGetTypeID() WKGrammarDetailRef WKGrammarDetailCreate(int location, int length, WKArrayRef guesses, WKStringRef userDescription) { - RefPtr<WebGrammarDetail> detail = WebGrammarDetail::create(location, length, toImpl(guesses), toWTFString(userDescription)); - return toAPI(detail.release().leakRef()); + auto detail = WebGrammarDetail::create(location, length, toImpl(guesses), toWTFString(userDescription)); + return toAPI(detail.leakRef()); } int WKGrammarDetailGetLocation(WKGrammarDetailRef grammarDetailRef) @@ -56,7 +56,7 @@ int WKGrammarDetailGetLength(WKGrammarDetailRef grammarDetailRef) WKArrayRef WKGrammarDetailCopyGuesses(WKGrammarDetailRef grammarDetailRef) { - return toAPI(toImpl(grammarDetailRef)->guesses().leakRef()); + return toAPI(&toImpl(grammarDetailRef)->guesses().leakRef()); } WKStringRef WKGrammarDetailCopyUserDescription(WKGrammarDetailRef grammarDetailRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.h b/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.h index c187ce6ad..2493c44d4 100644 --- a/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.h +++ b/Source/WebKit2/UIProcess/API/C/WKGrammarDetail.h @@ -26,7 +26,7 @@ #ifndef WKGrammarDetail_h #define WKGrammarDetail_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp index 5949091bb..4082002b0 100644 --- a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.cpp @@ -27,14 +27,14 @@ #include "config.h" #include "WKHitTestResult.h" +#include "APIHitTestResult.h" #include "WKAPICast.h" -#include "WebHitTestResult.h" using namespace WebKit; WKTypeID WKHitTestResultGetTypeID() { - return toAPI(WebHitTestResult::APIType); + return toAPI(API::HitTestResult::APIType); } WKURLRef WKHitTestResultCopyAbsoluteImageURL(WKHitTestResultRef hitTestResultRef) @@ -67,7 +67,17 @@ WKStringRef WKHitTestResultCopyLinkTitle(WKHitTestResultRef hitTestResultRef) return toCopiedAPI(toImpl(hitTestResultRef)->linkTitle()); } +WKStringRef WKHitTestResultCopyLookupText(WKHitTestResultRef hitTestResult) +{ + return toCopiedAPI(toImpl(hitTestResult)->lookupText()); +} + bool WKHitTestResultIsContentEditable(WKHitTestResultRef hitTestResultRef) { return toImpl(hitTestResultRef)->isContentEditable(); } + +WKRect WKHitTestResultGetElementBoundingBox(WKHitTestResultRef hitTestResultRef) +{ + return toAPI(toImpl(hitTestResultRef)->elementBoundingBox()); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h index 55fd13768..3c7081362 100644 --- a/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h +++ b/Source/WebKit2/UIProcess/API/C/WKHitTestResult.h @@ -27,7 +27,8 @@ #ifndef WKHitTestResult_h #define WKHitTestResult_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKGeometry.h> #ifdef __cplusplus extern "C" { @@ -42,9 +43,12 @@ WK_EXPORT WKURLRef WKHitTestResultCopyAbsoluteMediaURL(WKHitTestResultRef hitTes WK_EXPORT WKStringRef WKHitTestResultCopyLinkLabel(WKHitTestResultRef hitTestResult); WK_EXPORT WKStringRef WKHitTestResultCopyLinkTitle(WKHitTestResultRef hitTestResult); +WK_EXPORT WKStringRef WKHitTestResultCopyLookupText(WKHitTestResultRef hitTestResult); WK_EXPORT bool WKHitTestResultIsContentEditable(WKHitTestResultRef hitTestResult); +WK_EXPORT WKRect WKHitTestResultGetElementBoundingBox(WKHitTestResultRef hitTestResultRef); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp index a47290073..39006631f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.cpp @@ -57,6 +57,23 @@ void WKIconDatabaseSetIconDataForIconURL(WKIconDatabaseRef iconDatabaseRef, WKDa toImpl(iconDatabaseRef)->setIconDataForIconURL(toImpl(iconDataRef)->dataReference(), toWTFString(iconURLRef)); } +void WKIconDatabaseSetIconURLForPageURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef iconURLRef, WKURLRef pageURLRef) +{ + toImpl(iconDatabaseRef)->setIconURLForPageURL(toWTFString(iconURLRef), toWTFString(pageURLRef)); +} + +WKURLRef WKIconDatabaseCopyIconURLForPageURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef pageURLRef) +{ + String iconURLString; + toImpl(iconDatabaseRef)->synchronousIconURLForPageURL(toWTFString(pageURLRef), iconURLString); + return toCopiedURLAPI(iconURLString); +} + +WKDataRef WKIconDatabaseCopyIconDataForPageURL(WKIconDatabaseRef iconDatabaseRef, WKURLRef pageURL) +{ + return toAPI(toImpl(iconDatabaseRef)->iconDataForPageURL(toWTFString(pageURL)).leakRef()); +} + void WKIconDatabaseEnableDatabaseCleanup(WKIconDatabaseRef iconDatabaseRef) { toImpl(iconDatabaseRef)->enableDatabaseCleanup(); diff --git a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h index 0a10f6596..847414179 100644 --- a/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h +++ b/Source/WebKit2/UIProcess/API/C/WKIconDatabase.h @@ -26,7 +26,7 @@ #ifndef WKIconDatabase_h #define WKIconDatabase_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -61,19 +61,6 @@ typedef struct WKIconDatabaseClientV1 { WKIconDatabaseIconDataReadyForPageURLCallback iconDataReadyForPageURL; } WKIconDatabaseClientV1; -enum { kWKIconDatabaseClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 1 }; -typedef struct WKIconDatabaseClient { - int version; - const void * clientInfo; - - // Version 0. - WKIconDatabaseDidChangeIconForPageURLCallback didChangeIconForPageURL; - WKIconDatabaseDidRemoveAllIconsCallback didRemoveAllIcons; - - // Version 1. - WKIconDatabaseIconDataReadyForPageURLCallback iconDataReadyForPageURL; -} WKIconDatabaseClient WK_DEPRECATED("Use an explicit versioned struct instead"); - WK_EXPORT WKTypeID WKIconDatabaseGetTypeID(); WK_EXPORT void WKIconDatabaseSetIconDatabaseClient(WKIconDatabaseRef iconDatabase, const WKIconDatabaseClientBase* client); @@ -81,6 +68,10 @@ WK_EXPORT void WKIconDatabaseSetIconDatabaseClient(WKIconDatabaseRef iconDatabas WK_EXPORT void WKIconDatabaseRetainIconForURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); WK_EXPORT void WKIconDatabaseReleaseIconForURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); WK_EXPORT void WKIconDatabaseSetIconDataForIconURL(WKIconDatabaseRef iconDatabase, WKDataRef iconData, WKURLRef iconURL); +WK_EXPORT void WKIconDatabaseSetIconURLForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef iconURL, WKURLRef pageURL); +WK_EXPORT WKURLRef WKIconDatabaseCopyIconURLForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); +WK_EXPORT WKDataRef WKIconDatabaseCopyIconDataForPageURL(WKIconDatabaseRef iconDatabase, WKURLRef pageURL); + WK_EXPORT void WKIconDatabaseEnableDatabaseCleanup(WKIconDatabaseRef iconDatabase); WK_EXPORT void WKIconDatabaseRemoveAllIcons(WKIconDatabaseRef iconDatabase); diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp index e638609bb..aeb8d57cb 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,205 +26,109 @@ #include "config.h" #include "WKInspector.h" +#if !PLATFORM(IOS) + #include "WKAPICast.h" #include "WebInspectorProxy.h" +#include "WebPageProxy.h" using namespace WebKit; WKTypeID WKInspectorGetTypeID() { -#if ENABLE(INSPECTOR) return toAPI(WebInspectorProxy::APIType); -#else - return 0; -#endif } WKPageRef WKInspectorGetPage(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - return toAPI(toImpl(inspectorRef)->page()); -#else - UNUSED_PARAM(inspectorRef); - return 0; -#endif + return toAPI(toImpl(inspectorRef)->inspectedPage()); } bool WKInspectorIsConnected(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) return toImpl(inspectorRef)->isConnected(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif } bool WKInspectorIsVisible(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) return toImpl(inspectorRef)->isVisible(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif } bool WKInspectorIsFront(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) return toImpl(inspectorRef)->isFront(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif } void WKInspectorConnect(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->connect(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorShow(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->show(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorHide(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->hide(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorClose(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->close(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorShowConsole(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->showConsole(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorShowResources(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->showResources(); -#else - UNUSED_PARAM(inspectorRef); -#endif } void WKInspectorShowMainResourceForFrame(WKInspectorRef inspectorRef, WKFrameRef frameRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->showMainResourceForFrame(toImpl(frameRef)); -#else - UNUSED_PARAM(inspectorRef); - UNUSED_PARAM(frameRef); -#endif } bool WKInspectorIsAttached(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) return toImpl(inspectorRef)->isAttached(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif } void WKInspectorAttach(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - toImpl(inspectorRef)->attach(); -#else - UNUSED_PARAM(inspectorRef); -#endif + auto inspector = toImpl(inspectorRef); + inspector->attach(inspector->attachmentSide()); } void WKInspectorDetach(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) toImpl(inspectorRef)->detach(); -#else - UNUSED_PARAM(inspectorRef); -#endif -} - -bool WKInspectorIsDebuggingJavaScript(WKInspectorRef inspectorRef) -{ -#if ENABLE(INSPECTOR) - return toImpl(inspectorRef)->isDebuggingJavaScript(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif } -void WKInspectorToggleJavaScriptDebugging(WKInspectorRef inspectorRef) +bool WKInspectorIsProfilingPage(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - toImpl(inspectorRef)->toggleJavaScriptDebugging(); -#else - UNUSED_PARAM(inspectorRef); -#endif + return toImpl(inspectorRef)->isProfilingPage(); } -bool WKInspectorIsProfilingJavaScript(WKInspectorRef inspectorRef) +void WKInspectorTogglePageProfiling(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - return toImpl(inspectorRef)->isProfilingJavaScript(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif + toImpl(inspectorRef)->showTimelines(); + toImpl(inspectorRef)->togglePageProfiling(); } -void WKInspectorToggleJavaScriptProfiling(WKInspectorRef inspectorRef) +bool WKInspectorIsElementSelectionActive(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - toImpl(inspectorRef)->toggleJavaScriptProfiling(); -#else - UNUSED_PARAM(inspectorRef); -#endif + return toImpl(inspectorRef)->isElementSelectionActive(); } -bool WKInspectorIsProfilingPage(WKInspectorRef inspectorRef) +void WKInspectorToggleElementSelection(WKInspectorRef inspectorRef) { -#if ENABLE(INSPECTOR) - return toImpl(inspectorRef)->isProfilingPage(); -#else - UNUSED_PARAM(inspectorRef); - return false; -#endif + toImpl(inspectorRef)->toggleElementSelection(); } -void WKInspectorTogglePageProfiling(WKInspectorRef inspectorRef) -{ -#if ENABLE(INSPECTOR) - toImpl(inspectorRef)->togglePageProfiling(); -#else - UNUSED_PARAM(inspectorRef); -#endif -} +#endif // !PLATFORM(IOS) diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.h b/Source/WebKit2/UIProcess/API/C/WKInspector.h index 203e1b3cf..d0364de5b 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.h +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.h @@ -26,7 +26,7 @@ #ifndef WKInspector_h #define WKInspector_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifndef __cplusplus #include <stdbool.h> @@ -58,15 +58,12 @@ WK_EXPORT bool WKInspectorIsAttached(WKInspectorRef inspector); WK_EXPORT void WKInspectorAttach(WKInspectorRef inspector); WK_EXPORT void WKInspectorDetach(WKInspectorRef inspector); -WK_EXPORT bool WKInspectorIsDebuggingJavaScript(WKInspectorRef inspector); -WK_EXPORT void WKInspectorToggleJavaScriptDebugging(WKInspectorRef inspector); - -WK_EXPORT bool WKInspectorIsProfilingJavaScript(WKInspectorRef inspector); -WK_EXPORT void WKInspectorToggleJavaScriptProfiling(WKInspectorRef inspector); - WK_EXPORT bool WKInspectorIsProfilingPage(WKInspectorRef inspector); WK_EXPORT void WKInspectorTogglePageProfiling(WKInspectorRef inspector); +WK_EXPORT bool WKInspectorIsElementSelectionActive(WKInspectorRef inspector); +WK_EXPORT void WKInspectorToggleElementSelection(WKInspectorRef inspector); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.cpp b/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.cpp index d33c056bf..b322e4319 100644 --- a/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.cpp @@ -26,27 +26,106 @@ #include "config.h" #include "WKKeyValueStorageManager.h" +#include "APIDictionary.h" +#include "APIWebsiteDataStore.h" +#include "StorageManager.h" #include "WKAPICast.h" -#include "WebKeyValueStorageManager.h" +#include "WebsiteDataStore.h" +#include <wtf/RunLoop.h> using namespace WebKit; WKTypeID WKKeyValueStorageManagerGetTypeID() { - return toAPI(WebKeyValueStorageManager::APIType); + return toAPI(API::WebsiteDataStore::APIType); } -void WKKeyValueStorageManagerGetKeyValueStorageOrigins(WKKeyValueStorageManagerRef keyValueStorageManagerRef, void* context, WKKeyValueStorageManagerGetKeyValueStorageOriginsFunction callback) +WKStringRef WKKeyValueStorageManagerGetOriginKey() { - toImpl(keyValueStorageManagerRef)->getKeyValueStorageOrigins(ArrayCallback::create(context, callback)); + static API::String& key = API::String::create("WebKeyValueStorageManagerStorageDetailsOriginKey").leakRef(); + return toAPI(&key); } -void WKKeyValueStorageManagerDeleteEntriesForOrigin(WKKeyValueStorageManagerRef keyValueStorageManagerRef, WKSecurityOriginRef originRef) +WKStringRef WKKeyValueStorageManagerGetCreationTimeKey() { - toImpl(keyValueStorageManagerRef)->deleteEntriesForOrigin(toImpl(originRef)); + static API::String& key = API::String::create("WebKeyValueStorageManagerStorageDetailsCreationTimeKey").leakRef(); + return toAPI(&key); } -void WKKeyValueStorageManagerDeleteAllEntries(WKKeyValueStorageManagerRef keyValueStorageManagerRef) +WKStringRef WKKeyValueStorageManagerGetModificationTimeKey() { - toImpl(keyValueStorageManagerRef)->deleteAllEntries(); + static API::String& key = API::String::create("WebKeyValueStorageManagerStorageDetailsModificationTimeKey").leakRef(); + return toAPI(&key); +} + +void WKKeyValueStorageManagerGetKeyValueStorageOrigins(WKKeyValueStorageManagerRef keyValueStorageManager, void* context, WKKeyValueStorageManagerGetKeyValueStorageOriginsFunction callback) + +{ + StorageManager* storageManager = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(keyValueStorageManager))->websiteDataStore().storageManager(); + if (!storageManager) { + RunLoop::main().dispatch([context, callback] { + callback(toAPI(API::Array::create().ptr()), nullptr, context); + }); + return; + } + + storageManager->getLocalStorageOrigins([context, callback](auto&& securityOrigins) { + Vector<RefPtr<API::Object>> webSecurityOrigins; + webSecurityOrigins.reserveInitialCapacity(securityOrigins.size()); + for (auto& origin : securityOrigins) + webSecurityOrigins.uncheckedAppend(API::SecurityOrigin::create(origin.securityOrigin())); + + callback(toAPI(API::Array::create(WTFMove(webSecurityOrigins)).ptr()), nullptr, context); + }); +} + +void WKKeyValueStorageManagerGetStorageDetailsByOrigin(WKKeyValueStorageManagerRef keyValueStorageManager, void* context, WKKeyValueStorageManagerGetStorageDetailsByOriginFunction callback) +{ + StorageManager* storageManager = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(keyValueStorageManager))->websiteDataStore().storageManager(); + if (!storageManager) { + RunLoop::main().dispatch([context, callback] { + callback(toAPI(API::Array::create().ptr()), nullptr, context); + }); + return; + } + + storageManager->getLocalStorageOriginDetails([context, callback](auto storageDetails) { + HashMap<String, RefPtr<API::Object>> detailsMap; + Vector<RefPtr<API::Object>> result; + result.reserveInitialCapacity(storageDetails.size()); + + for (const auto& originDetails : storageDetails) { + HashMap<String, RefPtr<API::Object>> detailsMap; + + RefPtr<API::Object> origin = API::SecurityOrigin::create(WebCore::SecurityOriginData::fromDatabaseIdentifier(originDetails.originIdentifier)->securityOrigin()); + + detailsMap.set(toImpl(WKKeyValueStorageManagerGetOriginKey())->string(), origin); + if (originDetails.creationTime) + detailsMap.set(toImpl(WKKeyValueStorageManagerGetCreationTimeKey())->string(), API::Double::create(originDetails.creationTime.value_or(0))); + if (originDetails.modificationTime) + detailsMap.set(toImpl(WKKeyValueStorageManagerGetModificationTimeKey())->string(), API::Double::create(originDetails.modificationTime.value_or(0))); + + result.uncheckedAppend(API::Dictionary::create(WTFMove(detailsMap))); + } + + callback(toAPI(API::Array::create(WTFMove(result)).ptr()), nullptr, context); + }); +} + +void WKKeyValueStorageManagerDeleteEntriesForOrigin(WKKeyValueStorageManagerRef keyValueStorageManager, WKSecurityOriginRef origin) +{ + StorageManager* storageManager = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(keyValueStorageManager))->websiteDataStore().storageManager(); + if (!storageManager) + return; + + storageManager->deleteLocalStorageEntriesForOrigin(WebCore::SecurityOriginData::fromSecurityOrigin(toImpl(origin)->securityOrigin())); +} + +void WKKeyValueStorageManagerDeleteAllEntries(WKKeyValueStorageManagerRef keyValueStorageManager) +{ + StorageManager* storageManager = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(keyValueStorageManager))->websiteDataStore().storageManager(); + if (!storageManager) + return; + + storageManager->deleteLocalStorageOriginsModifiedSince(std::chrono::system_clock::time_point::min(), [] { }); } diff --git a/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.h b/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.h index a0ee27825..d92adadad 100644 --- a/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKKeyValueStorageManager.h @@ -26,7 +26,7 @@ #ifndef WKKeyValueStorageManager_h #define WKKeyValueStorageManager_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -34,9 +34,21 @@ extern "C" { WK_EXPORT WKTypeID WKKeyValueStorageManagerGetTypeID(); +/* Value type: WKSecurityOriginRef */ +WK_EXPORT WKStringRef WKKeyValueStorageManagerGetOriginKey(); + +/* Value type: WKDoubleRef, seconds since January 1st, 1970 UTC */ +WK_EXPORT WKStringRef WKKeyValueStorageManagerGetCreationTimeKey(); + +/* Value type: WKDoubleRef, seconds since January 1st, 1970 UTC */ +WK_EXPORT WKStringRef WKKeyValueStorageManagerGetModificationTimeKey(); + typedef void (*WKKeyValueStorageManagerGetKeyValueStorageOriginsFunction)(WKArrayRef, WKErrorRef, void*); WK_EXPORT void WKKeyValueStorageManagerGetKeyValueStorageOrigins(WKKeyValueStorageManagerRef keyValueStorageManager, void* context, WKKeyValueStorageManagerGetKeyValueStorageOriginsFunction function); +typedef void (*WKKeyValueStorageManagerGetStorageDetailsByOriginFunction)(WKArrayRef, WKErrorRef, void*); +WK_EXPORT void WKKeyValueStorageManagerGetStorageDetailsByOrigin(WKKeyValueStorageManagerRef keyValueStorageManager, void* context, WKKeyValueStorageManagerGetStorageDetailsByOriginFunction function); + WK_EXPORT void WKKeyValueStorageManagerDeleteEntriesForOrigin(WKKeyValueStorageManagerRef keyValueStorageManager, WKSecurityOriginRef origin); WK_EXPORT void WKKeyValueStorageManagerDeleteAllEntries(WKKeyValueStorageManagerRef keyValueStorageManager); diff --git a/Source/WebKit2/UIProcess/API/C/WKLayoutMode.h b/Source/WebKit2/UIProcess/API/C/WKLayoutMode.h new file mode 100644 index 000000000..bb75f17f9 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKLayoutMode.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKLayoutMode_h +#define WKLayoutMode_h + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + kWKLayoutModeViewSize = 0, + kWKLayoutModeFixedSize = 1, + kWKLayoutModeDynamicSizeComputedFromViewScale = 2, + kWKLayoutModeDynamicSizeComputedFromMinimumDocumentSize = 4 +}; +typedef uint32_t WKLayoutMode; + +#ifdef __cplusplus +} +#endif + +#endif /* WKLayoutMode_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKNetworkInfoManager.cpp b/Source/WebKit2/UIProcess/API/C/WKMediaSessionFocusManager.cpp index 6c278a8d9..9603bf072 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNetworkInfoManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKMediaSessionFocusManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,39 +24,49 @@ */ #include "config.h" -#include "WKNetworkInfoManager.h" +#include "WKMediaSessionFocusManager.h" #include "WKAPICast.h" -#include "WebNetworkInfoManagerProxy.h" +#include "WebMediaSessionFocusManager.h" using namespace WebKit; -WKTypeID WKNetworkInfoManagerGetTypeID() +WKTypeID WKMediaSessionFocusManagerGetTypeID() { -#if ENABLE(NETWORK_INFO) - return toAPI(WebNetworkInfoManagerProxy::APIType); +#if ENABLE(MEDIA_SESSION) + return toAPI(WebMediaSessionFocusManager::APIType); #else - return 0; + return toAPI(API::Object::Type::Null); #endif } -void WKNetworkInfoManagerSetProvider(WKNetworkInfoManagerRef networkInfoManager, const WKNetworkInfoProviderBase* provider) +void WKMediaSessionFocusManagerSetClient(WKMediaSessionFocusManagerRef manager, const WKMediaSessionFocusManagerClientBase* client) { -#if ENABLE(NETWORK_INFO) - toImpl(networkInfoManager)->initializeProvider(provider); +#if ENABLE(MEDIA_SESSION) + toImpl(manager)->initializeClient(client); #else - UNUSED_PARAM(networkInfoManager); - UNUSED_PARAM(provider); + UNUSED_PARAM(manager); + UNUSED_PARAM(client); #endif } -void WKNetworkInfoManagerProviderDidChangeNetworkInformation(WKNetworkInfoManagerRef networkInfoManager, WKStringRef eventType, WKNetworkInfoRef networkInfo) +bool WKMediaSessionFocusManagerValueForPlaybackAttribute(WKMediaSessionFocusManagerRef manager, WKMediaSessionFocusManagerPlaybackAttribute attribute) { -#if ENABLE(NETWORK_INFO) - toImpl(networkInfoManager)->providerDidChangeNetworkInformation(AtomicString(toImpl(eventType)->string()), toImpl(networkInfo)); +#if ENABLE(MEDIA_SESSION) + return toImpl(manager)->valueForPlaybackAttribute(attribute); #else - UNUSED_PARAM(networkInfoManager); - UNUSED_PARAM(eventType); - UNUSED_PARAM(networkInfo); + UNUSED_PARAM(manager); + UNUSED_PARAM(attribute); + return false; +#endif +} + +void WKMediaSessionFocusManagerSetVolumeOfFocusedMediaElement(WKMediaSessionFocusManagerRef manager, double volume) +{ +#if ENABLE(MEDIA_SESSION) + toImpl(manager)->setVolumeOfFocusedMediaElement(volume); +#else + UNUSED_PARAM(manager); + UNUSED_PARAM(volume); #endif } diff --git a/Source/WebKit2/UIProcess/API/C/WKMediaSessionFocusManager.h b/Source/WebKit2/UIProcess/API/C/WKMediaSessionFocusManager.h new file mode 100644 index 000000000..ed39e705a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKMediaSessionFocusManager.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKMediaSessionFocusManager_h +#define WKMediaSessionFocusManager_h + +#include <WebKit/WKBase.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +enum WKMediaSessionFocusManagerPlaybackAttribute { + IsPlaying = 1 << 0, + IsPreviousTrackControlEnabled = 1 << 1, + IsNextTrackControlEnabled = 1 << 2, +}; +typedef uint32_t WKMediaSessionFocusManagerPlaybackAttributes; + +// Media Session Focus Manager Client +typedef void (*WKMediaSessionFocusManagerDidChangePlaybackAttribute)(WKMediaSessionFocusManagerRef manager, WKMediaSessionFocusManagerPlaybackAttribute playbackAttribute, bool value, const void *clientInfo); + +typedef struct WKMediaSessionFocusManagerClientBase { + int version; + const void * clientInfo; +} WKMediaSessionFocusManagerClientBase; + +typedef struct WKMediaSessionFocusManagerClientV0 { + WKMediaSessionFocusManagerClientBase base; + + // Version 0. + WKMediaSessionFocusManagerDidChangePlaybackAttribute didChangePlaybackAttribute; +} WKMediaSessionFocusManagerClientV0; + +WK_EXPORT WKTypeID WKMediaSessionFocusManagerGetTypeID(); + +WK_EXPORT void WKMediaSessionFocusManagerSetClient(WKMediaSessionFocusManagerRef manager, const WKMediaSessionFocusManagerClientBase* client); + +WK_EXPORT bool WKMediaSessionFocusManagerValueForPlaybackAttribute(WKMediaSessionFocusManagerRef, WKMediaSessionFocusManagerPlaybackAttribute); +WK_EXPORT void WKMediaSessionFocusManagerSetVolumeOfFocusedMediaElement(WKMediaSessionFocusManagerRef, double); + +#ifdef __cplusplus +} +#endif + +#endif /* WKMediaSessionFocusManager_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.cpp b/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.cpp new file mode 100644 index 000000000..330ca53aa --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKMediaSessionMetadata.h" + +#include "WKAPICast.h" +#include "WebMediaSessionMetadata.h" + +using namespace WebKit; + +WKTypeID WKMediaSessionMetadataGetTypeID() +{ +#if ENABLE(MEDIA_SESSION) + return toAPI(WebMediaSessionMetadata::APIType); +#else + return toAPI(API::Object::Type::Null); +#endif +} + +WKStringRef WKMediaSessionMetadataCopyTitle(WKMediaSessionMetadataRef metadata) +{ +#if ENABLE(MEDIA_SESSION) + return toCopiedAPI(toImpl(metadata)->title()); +#else + UNUSED_PARAM(metadata); + return nullptr; +#endif +} + +WKStringRef WKMediaSessionMetadataCopyArtist(WKMediaSessionMetadataRef metadata) +{ +#if ENABLE(MEDIA_SESSION) + return toCopiedAPI(toImpl(metadata)->artist()); +#else + UNUSED_PARAM(metadata); + return nullptr; +#endif +} + +WKStringRef WKMediaSessionMetadataCopyAlbum(WKMediaSessionMetadataRef metadata) +{ +#if ENABLE(MEDIA_SESSION) + return toCopiedAPI(toImpl(metadata)->album()); +#else + UNUSED_PARAM(metadata); + return nullptr; +#endif +} + +WKURLRef WKMediaSessionMetadataCopyArtworkURL(WKMediaSessionMetadataRef metadata) +{ +#if ENABLE(MEDIA_SESSION) + return toCopiedURLAPI(toImpl(metadata)->artworkURL()); +#else + UNUSED_PARAM(metadata); + return nullptr; +#endif +} diff --git a/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.h b/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.h new file mode 100644 index 000000000..b9430f7e4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKMediaSessionMetadata.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKMediaSessionMetadata_h +#define WKMediaSessionMetadata_h + +#include <WebKit/WKBase.h> + +#ifndef __cplusplus +#include <stdbool.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKMediaSessionMetadataGetTypeID(); + +WK_EXPORT WKStringRef WKMediaSessionMetadataCopyTitle(WKMediaSessionMetadataRef metadata); +WK_EXPORT WKStringRef WKMediaSessionMetadataCopyArtist(WKMediaSessionMetadataRef metadata); +WK_EXPORT WKStringRef WKMediaSessionMetadataCopyAlbum(WKMediaSessionMetadataRef metadata); +WK_EXPORT WKURLRef WKMediaSessionMetadataCopyArtworkURL(WKMediaSessionMetadataRef metadata); + +#ifdef __cplusplus +} +#endif + +#endif /* WKMediaSessionMetadata_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h b/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h index 349582628..7d8b6b9dc 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h +++ b/Source/WebKit2/UIProcess/API/C/WKNativeEvent.h @@ -34,7 +34,7 @@ extern "C" { #endif -#if defined(__APPLE__) && !TARGET_OS_IPHONE +#if defined(__APPLE__) && !TARGET_OS_IPHONE && !defined(BUILDING_GTK__) #ifdef __OBJC__ @class NSEvent; #elif __cplusplus diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.cpp b/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.cpp new file mode 100644 index 000000000..14a235157 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKNavigationActionRef.h" + +#include "APINavigationAction.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKTypeID WKNavigationActionGetTypeID() +{ + return toAPI(API::NavigationAction::APIType); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.h b/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.h new file mode 100644 index 000000000..5691eabcd --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationActionRef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKNavigationActionRef_h +#define WKNavigationActionRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKNavigationActionGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif // WKNavigationActionRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.cpp b/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.cpp index 86840e33e..0a815bb82 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.cpp @@ -55,5 +55,5 @@ WKURLRef WKNavigationDataCopyNavigationDestinationURL(WKNavigationDataRef naviga WKURLRequestRef WKNavigationDataCopyOriginalRequest(WKNavigationDataRef navigationData) { - return toAPI(API::URLRequest::create(toImpl(navigationData)->originalRequest()).leakRef()); + return toAPI(&API::URLRequest::create(toImpl(navigationData)->originalRequest()).leakRef()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.h b/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.h index 8d70b76fa..b2c5f5b2b 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.h +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationDataRef.h @@ -26,7 +26,7 @@ #ifndef WKNavigationDataRef_h #define WKNavigationDataRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationRef.cpp b/Source/WebKit2/UIProcess/API/C/WKNavigationRef.cpp new file mode 100644 index 000000000..591c14660 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationRef.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKNavigationRef.h" + +#include "APINavigation.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKTypeID WKNavigationGetTypeID() +{ + return toAPI(API::Navigation::APIType); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationRef.h b/Source/WebKit2/UIProcess/API/C/WKNavigationRef.h new file mode 100644 index 000000000..ae9a19074 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationRef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKNavigationRef_h +#define WKNavigationRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKNavigationGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif // WKNavigationRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.cpp b/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.cpp new file mode 100644 index 000000000..ed6f21b0f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKNavigationResponseRef.h" + +#include "APINavigationResponse.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKTypeID WKNavigationResponseGetTypeID() +{ + return toAPI(API::NavigationResponse::APIType); +} + +bool WKNavigationResponseCanShowMIMEType(WKNavigationResponseRef response) +{ + return toImpl(response)->canShowMIMEType(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.h b/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.h new file mode 100644 index 000000000..c82b14dc3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKNavigationResponseRef.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKNavigationResponseRef_h +#define WKNavigationResponseRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKNavigationResponseGetTypeID(); + +WK_EXPORT bool WKNavigationResponseCanShowMIMEType(WKNavigationResponseRef); + +#ifdef __cplusplus +} +#endif + +#endif // WKNavigationResponseRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKNetworkInfoManager.h b/Source/WebKit2/UIProcess/API/C/WKNetworkInfoManager.h deleted file mode 100644 index e3bdca671..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKNetworkInfoManager.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKNetworkInfoManager_h -#define WKNetworkInfoManager_h - -#include <WebKit2/WKBase.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Provider. -typedef void (*WKNetworkInfoProviderStartUpdatingCallback)(WKNetworkInfoManagerRef networkInfoManager, const void* clientInfo); -typedef void (*WKNetworkInfoProviderStopUpdatingCallback)(WKNetworkInfoManagerRef networkInfoManager, const void* clientInfo); -typedef double (*WKNetworkInfoProviderGetBandwidthCallback)(WKNetworkInfoManagerRef networkInfoManager, const void* clientInfo); -typedef bool (*WKNetworkInfoProviderIsMeteredCallback)(WKNetworkInfoManagerRef networkInfoManager, const void* clientInfo); - -typedef struct WKNetworkInfoProviderBase { - int version; - const void * clientInfo; -} WKNetworkInfoProviderBase; - -typedef struct WKNetworkInfoProvider { - WKNetworkInfoProviderBase base; - - WKNetworkInfoProviderStartUpdatingCallback startUpdating; - WKNetworkInfoProviderStopUpdatingCallback stopUpdating; - WKNetworkInfoProviderGetBandwidthCallback bandwidth; - WKNetworkInfoProviderIsMeteredCallback isMetered; -} WKNetworkInfoProviderV0; - -WK_EXPORT WKTypeID WKNetworkInfoManagerGetTypeID(); - -WK_EXPORT void WKNetworkInfoManagerSetProvider(WKNetworkInfoManagerRef networkInfoManager, const WKNetworkInfoProviderBase* provider); - -WK_EXPORT void WKNetworkInfoManagerProviderDidChangeNetworkInformation(WKNetworkInfoManagerRef networkInfoManager, WKStringRef eventType, WKNetworkInfoRef networkInfo); - -#ifdef __cplusplus -} -#endif - -#endif // WKNetworkInfoManager_h diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp index 78b09e09e..3d1805730 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "WKNotification.h" +#include "APISecurityOrigin.h" #include "WKAPICast.h" #include "WebNotification.h" -#include "WebSecurityOrigin.h" using namespace WebKit; diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.h b/Source/WebKit2/UIProcess/API/C/WKNotification.h index 7035ef3f8..d3ae98bf7 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.h @@ -26,7 +26,7 @@ #ifndef WKNotification_h #define WKNotification_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKNotificationManager.cpp b/Source/WebKit2/UIProcess/API/C/WKNotificationManager.cpp index 1e050a6e6..70f15f02e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotificationManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKNotificationManager.cpp @@ -27,6 +27,7 @@ #include "WKNotificationManager.h" #include "WKAPICast.h" +#include "WebNotification.h" #include "WebNotificationManagerProxy.h" using namespace WebKit; @@ -65,3 +66,8 @@ void WKNotificationManagerProviderDidRemoveNotificationPolicies(WKNotificationMa { toImpl(managerRef)->providerDidRemoveNotificationPolicies(toImpl(origins)); } + +uint64_t WKNotificationManagerGetLocalIDForTesting(WKNotificationManagerRef manager, WKNotificationRef notification) +{ + return toImpl(manager)->notificationLocalIDForTesting(toImpl(notification)); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKNotificationManager.h b/Source/WebKit2/UIProcess/API/C/WKNotificationManager.h index 50f50d747..b78909c6c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotificationManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotificationManager.h @@ -27,7 +27,7 @@ #define WKNotificationManager_h #include "WKNotificationProvider.h" -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -41,6 +41,7 @@ WK_EXPORT void WKNotificationManagerProviderDidClickNotification(WKNotificationM WK_EXPORT void WKNotificationManagerProviderDidCloseNotifications(WKNotificationManagerRef managerRef, WKArrayRef notificationIDs); WK_EXPORT void WKNotificationManagerProviderDidUpdateNotificationPolicy(WKNotificationManagerRef managerRef, WKSecurityOriginRef origin, bool allowed); WK_EXPORT void WKNotificationManagerProviderDidRemoveNotificationPolicies(WKNotificationManagerRef managerRef, WKArrayRef origins); +WK_EXPORT uint64_t WKNotificationManagerGetLocalIDForTesting(WKNotificationManagerRef managerRef, WKNotificationRef notification); #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKNotificationPermissionRequest.h b/Source/WebKit2/UIProcess/API/C/WKNotificationPermissionRequest.h index 1947a06aa..02be0e63c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotificationPermissionRequest.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotificationPermissionRequest.h @@ -26,7 +26,7 @@ #ifndef WKNotificationPermissionRequest_h #define WKNotificationPermissionRequest_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKNotificationProvider.h b/Source/WebKit2/UIProcess/API/C/WKNotificationProvider.h index 920e297b3..8a416c57c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotificationProvider.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotificationProvider.h @@ -26,7 +26,7 @@ #ifndef WKNotificationProvider_h #define WKNotificationProvider_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -58,21 +58,6 @@ typedef struct WKNotificationProviderV0 { WKNotificationProviderClearNotificationsCallback clearNotifications; } WKNotificationProviderV0; -enum { kWKNotificationProviderCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0, }; -typedef struct WKNotificationProvider { - int version; - const void* clientInfo; - - // Version 0. - WKNotificationProviderShowCallback show; - WKNotificationProviderCancelCallback cancel; - WKNotificationProviderDidDestroyNotificationCallback didDestroyNotification; - WKNotificationProviderAddNotificationManagerCallback addNotificationManager; - WKNotificationProviderRemoveNotificationManagerCallback removeNotificationManager; - WKNotificationProviderNotificationPermissionsCallback notificationPermissions; - WKNotificationProviderClearNotificationsCallback clearNotifications; -} WKNotificationProvider WK_DEPRECATED("Use an explicit versioned struct instead"); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKOpenPanelParameters.cpp b/Source/WebKit2/UIProcess/API/C/WKOpenPanelParametersRef.cpp index aa3e0b58a..c8ad8da0f 100644 --- a/Source/WebKit2/UIProcess/API/C/WKOpenPanelParameters.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKOpenPanelParametersRef.cpp @@ -25,17 +25,17 @@ */ #include "config.h" -#include "WKOpenPanelParameters.h" +#include "WKOpenPanelParametersRef.h" #include "APIArray.h" +#include "APIOpenPanelParameters.h" #include "WKAPICast.h" -#include "WebOpenPanelParameters.h" using namespace WebKit; WKTypeID WKOpenPanelParametersGetTypeID() { - return toAPI(WebOpenPanelParameters::APIType); + return toAPI(API::OpenPanelParameters::APIType); } bool WKOpenPanelParametersGetAllowsMultipleFiles(WKOpenPanelParametersRef parametersRef) @@ -45,20 +45,26 @@ bool WKOpenPanelParametersGetAllowsMultipleFiles(WKOpenPanelParametersRef parame WKArrayRef WKOpenPanelParametersCopyAcceptedMIMETypes(WKOpenPanelParametersRef parametersRef) { - return toAPI(toImpl(parametersRef)->acceptMIMETypes().leakRef()); + return toAPI(&toImpl(parametersRef)->acceptMIMETypes().leakRef()); } -WKStringRef WKOpenPanelParametersCopyCapture(WKOpenPanelParametersRef parametersRef) +// Deprecated. +WKStringRef WKOpenPanelParametersCopyCapture(WKOpenPanelParametersRef) +{ + return 0; +} + +bool WKOpenPanelParametersGetMediaCaptureType(WKOpenPanelParametersRef parametersRef) { #if ENABLE(MEDIA_CAPTURE) - return toCopiedAPI(toImpl(parametersRef)->capture()); + return toImpl(parametersRef)->mediaCaptureType(); #else UNUSED_PARAM(parametersRef); - return 0; + return false; #endif } WKArrayRef WKOpenPanelParametersCopySelectedFileNames(WKOpenPanelParametersRef parametersRef) { - return toAPI(toImpl(parametersRef)->selectedFileNames().leakRef()); + return toAPI(&toImpl(parametersRef)->selectedFileNames().leakRef()); } diff --git a/Source/WebKit2/UIProcess/API/C/WKOpenPanelParameters.h b/Source/WebKit2/UIProcess/API/C/WKOpenPanelParametersRef.h index 3801c2f7b..d8ca7c40d 100644 --- a/Source/WebKit2/UIProcess/API/C/WKOpenPanelParameters.h +++ b/Source/WebKit2/UIProcess/API/C/WKOpenPanelParametersRef.h @@ -24,10 +24,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKOpenPanelParameters_h -#define WKOpenPanelParameters_h +#ifndef WKOpenPanelParametersRef_h +#define WKOpenPanelParametersRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifndef __cplusplus #include <stdbool.h> @@ -43,12 +43,15 @@ WK_EXPORT bool WKOpenPanelParametersGetAllowsMultipleFiles(WKOpenPanelParameters WK_EXPORT WKArrayRef WKOpenPanelParametersCopyAcceptedMIMETypes(WKOpenPanelParametersRef parameters); +/* DEPRECATED - Please use WKOpenPanelParametersGetCaptureEnabled() instead. */ WK_EXPORT WKStringRef WKOpenPanelParametersCopyCapture(WKOpenPanelParametersRef parameters); +WK_EXPORT bool WKOpenPanelParametersGetMediaCaptureType(WKOpenPanelParametersRef parametersRef); + WK_EXPORT WKArrayRef WKOpenPanelParametersCopySelectedFileNames(WKOpenPanelParametersRef parametersRef); #ifdef __cplusplus } #endif -#endif /* WKOpenPanelParameters_h */ +#endif /* WKOpenPanelParametersRef_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.cpp b/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.cpp index 8c793182d..b5c48afc6 100644 --- a/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.cpp @@ -28,6 +28,7 @@ #include "WKAPICast.h" #include "WebOpenPanelResultListenerProxy.h" +#include <WebCore/URL.h> using namespace WebKit; @@ -36,9 +37,25 @@ WKTypeID WKOpenPanelResultListenerGetTypeID() return toAPI(WebOpenPanelResultListenerProxy::APIType); } +static Vector<String> filePathsFromFileURLs(const API::Array& fileURLs) +{ + Vector<String> filePaths; + + size_t size = fileURLs.size(); + filePaths.reserveInitialCapacity(size); + + for (size_t i = 0; i < size; ++i) { + API::URL* apiURL = fileURLs.at<API::URL>(i); + if (apiURL) + filePaths.uncheckedAppend(WebCore::URL(WebCore::URL(), apiURL->string()).fileSystemPath()); + } + + return filePaths; +} + void WKOpenPanelResultListenerChooseFiles(WKOpenPanelResultListenerRef listenerRef, WKArrayRef fileURLsRef) { - toImpl(listenerRef)->chooseFiles(toImpl(fileURLsRef)); + toImpl(listenerRef)->chooseFiles(filePathsFromFileURLs(*toImpl(fileURLsRef))); } void WKOpenPanelResultListenerCancel(WKOpenPanelResultListenerRef listenerRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.h b/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.h index d581738a5..21c92ee24 100644 --- a/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.h +++ b/Source/WebKit2/UIProcess/API/C/WKOpenPanelResultListener.h @@ -26,7 +26,7 @@ #ifndef WKOpenPanelResultListener_h #define WKOpenPanelResultListener_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.cpp b/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.cpp deleted file mode 100644 index 8ab0f37d7..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WKOriginDataManager.h" - -#include "WKAPICast.h" -#include "WebOriginDataManagerProxy.h" - -using namespace WebKit; - -WKTypeID WKOriginDataManagerGetTypeID() -{ - return toAPI(WebOriginDataManagerProxy::APIType); -} - -void WKOriginDataManagerGetOrigins(WKOriginDataManagerRef originDataManagerRef, WKOriginDataTypes types, void* context, WKOriginDataManagerGetOriginsFunction callback) -{ - toImpl(originDataManagerRef)->getOrigins(types, ArrayCallback::create(context, callback)); -} - -void WKOriginDataManagerDeleteEntriesForOrigin(WKOriginDataManagerRef originDataManagerRef, WKOriginDataTypes types, WKSecurityOriginRef originRef) -{ - toImpl(originDataManagerRef)->deleteEntriesForOrigin(types, toImpl(originRef)); -} - -void WKOriginDataManagerDeleteAllEntries(WKOriginDataManagerRef originDataManagerRef, WKOriginDataTypes types) -{ - toImpl(originDataManagerRef)->deleteAllEntries(types); -} - -void WKOriginDataManagerStartObservingChanges(WKOriginDataManagerRef originDataManagerRef, WKOriginDataTypes types) -{ - toImpl(originDataManagerRef)->startObservingChanges(types); -} - -void WKOriginDataManagerStopObservingChanges(WKOriginDataManagerRef originDataManagerRef, WKOriginDataTypes types) -{ - toImpl(originDataManagerRef)->stopObservingChanges(types); -} - -void WKOriginDataManagerSetChangeClient(WKOriginDataManagerRef originDataManagerRef, const WKOriginDataManagerChangeClientBase *client) -{ - toImpl(originDataManagerRef)->setChangeClient(client); -} diff --git a/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.h b/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.h deleted file mode 100644 index f6300593b..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKOriginDataManager.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKOriginDataManager_h -#define WKOriginDataManager_h - -#include <WebKit2/WKBase.h> - -#ifdef __cplusplus -extern "C" { -#endif - -enum { - kWKApplicationCacheOriginData = 1 << 0, - kWKCookieOriginData = 1 << 1, - kWKDatabaseOriginData = 1 << 2, - kWKKeyValueStorageOriginData = 1 << 3, - kWKMediaCacheOriginData = 1 << 4, - kWKPluginDataOriginData = 1 << 5, - kWKResourceCacheOriginData = 1 << 6, - - kWKAllOriginData = (1 << 7) - 1 -}; -typedef uint32_t WKOriginDataTypes; - -WK_EXPORT WKTypeID WKOriginDataManagerGetTypeID(); - -typedef void (*WKOriginDataManagerGetOriginsFunction)(WKArrayRef, WKErrorRef, void*); -WK_EXPORT void WKOriginDataManagerGetOrigins(WKOriginDataManagerRef originDataManager, WKOriginDataTypes types, void* context, WKOriginDataManagerGetOriginsFunction function); - -WK_EXPORT void WKOriginDataManagerDeleteEntriesForOrigin(WKOriginDataManagerRef originDataManager, WKOriginDataTypes types, WKSecurityOriginRef origin); -WK_EXPORT void WKOriginDataManagerDeleteAllEntries(WKOriginDataManagerRef originDataManager, WKOriginDataTypes types); - -// OriginDataManager Client -typedef void (*WKOriginDataManagerChangeCallback)(WKOriginDataManagerRef originDataManager, const void *clientInfo); - -typedef struct WKOriginDataManagerChangeClientBase { - const void * clientInfo; - int version; -} WKOriginDataManagerChangeClientBase; - -typedef struct WKOriginDataManagerChangeClientV0 { - WKOriginDataManagerChangeClientBase base; - - // Version 0. - WKOriginDataManagerChangeCallback didChange; -} WKOriginDataManagerChangeClientV0; - -enum { kWKOriginDataManagerChangeClientVersion = 0 }; -typedef struct WKOriginDataManagerChangeClient { - int version; - const void * clientInfo; - - // Version 0. - WKOriginDataManagerChangeCallback didChange; -} WKOriginDataManagerChangeClient WK_DEPRECATED("Use an explicit versioned struct instead"); - -WK_EXPORT void WKOriginDataManagerStartObservingChanges(WKOriginDataManagerRef originDataManager, WKOriginDataTypes types); -WK_EXPORT void WKOriginDataManagerStopObservingChanges(WKOriginDataManagerRef originDataManager, WKOriginDataTypes types); -WK_EXPORT void WKOriginDataManagerSetChangeClient(WKOriginDataManagerRef originDataManger, const WKOriginDataManagerChangeClientBase* client); -#ifdef __cplusplus -} -#endif - -#endif // WKOriginDataManager_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.cpp b/Source/WebKit2/UIProcess/API/C/WKPage.cpp index c398b7060..562bc4a1a 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,21 +28,53 @@ #include "WKPagePrivate.h" #include "APIArray.h" +#include "APIContextMenuClient.h" #include "APIData.h" +#include "APIDictionary.h" +#include "APIFindClient.h" +#include "APIFindMatchesClient.h" +#include "APIFrameHandle.h" +#include "APIFrameInfo.h" +#include "APIGeometry.h" +#include "APIHitTestResult.h" #include "APILoaderClient.h" +#include "APINavigationAction.h" +#include "APINavigationClient.h" +#include "APINavigationResponse.h" +#include "APIOpenPanelParameters.h" +#include "APIPageConfiguration.h" #include "APIPolicyClient.h" -#include "ImmutableDictionary.h" +#include "APISessionState.h" +#include "APIUIClient.h" +#include "APIWebsitePolicies.h" +#include "APIWindowFeatures.h" +#include "AuthenticationChallengeProxy.h" +#include "LegacySessionStateCoding.h" +#include "Logging.h" +#include "NativeWebKeyboardEvent.h" +#include "NativeWebWheelEvent.h" #include "NavigationActionData.h" #include "PluginInformation.h" #include "PrintInfo.h" #include "WKAPICast.h" #include "WKPagePolicyClientInternal.h" +#include "WKPageRenderingProgressEventsInternal.h" #include "WKPluginInformation.h" #include "WebBackForwardList.h" +#include "WebFormClient.h" +#include "WebImage.h" +#include "WebInspectorProxy.h" +#include "WebOpenPanelResultListenerProxy.h" +#include "WebPageGroup.h" #include "WebPageMessages.h" #include "WebPageProxy.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" +#include "WebProtectionSpace.h" #include <WebCore/Page.h> +#include <WebCore/SecurityOriginData.h> +#include <WebCore/SerializedCryptoKeyWrap.h> +#include <WebCore/WindowFeatures.h> #ifdef __BLOCKS__ #include <Block.h> @@ -52,17 +84,49 @@ #include "WebContextMenuItem.h" #endif +#if ENABLE(VIBRATION) +#include "WebVibrationProxy.h" +#endif + +#if ENABLE(MEDIA_SESSION) +#include "WebMediaSessionMetadata.h" +#include <WebCore/MediaSessionEvents.h> +#endif + using namespace WebCore; using namespace WebKit; namespace API { template<> struct ClientTraits<WKPageLoaderClientBase> { - typedef std::tuple<WKPageLoaderClientV0, WKPageLoaderClientV1, WKPageLoaderClientV2, WKPageLoaderClientV3, WKPageLoaderClientV4> Versions; + typedef std::tuple<WKPageLoaderClientV0, WKPageLoaderClientV1, WKPageLoaderClientV2, WKPageLoaderClientV3, WKPageLoaderClientV4, WKPageLoaderClientV5, WKPageLoaderClientV6> Versions; +}; + +template<> struct ClientTraits<WKPageNavigationClientBase> { + typedef std::tuple<WKPageNavigationClientV0> Versions; }; template<> struct ClientTraits<WKPagePolicyClientBase> { typedef std::tuple<WKPagePolicyClientV0, WKPagePolicyClientV1, WKPagePolicyClientInternal> Versions; }; + +template<> struct ClientTraits<WKPageUIClientBase> { + typedef std::tuple<WKPageUIClientV0, WKPageUIClientV1, WKPageUIClientV2, WKPageUIClientV3, WKPageUIClientV4, WKPageUIClientV5, WKPageUIClientV6, WKPageUIClientV7, WKPageUIClientV8, WKPageUIClientV9> Versions; +}; + +#if ENABLE(CONTEXT_MENUS) +template<> struct ClientTraits<WKPageContextMenuClientBase> { + typedef std::tuple<WKPageContextMenuClientV0, WKPageContextMenuClientV1, WKPageContextMenuClientV2, WKPageContextMenuClientV3, WKPageContextMenuClientV4> Versions; +}; +#endif + +template<> struct ClientTraits<WKPageFindClientBase> { + typedef std::tuple<WKPageFindClientV0> Versions; +}; + +template<> struct ClientTraits<WKPageFindMatchesClientBase> { + typedef std::tuple<WKPageFindMatchesClientV0> Versions; +}; + } WKTypeID WKPageGetTypeID() @@ -72,7 +136,7 @@ WKTypeID WKPageGetTypeID() WKContextRef WKPageGetContext(WKPageRef pageRef) { - return toAPI(&toImpl(pageRef)->process().context()); + return toAPI(&toImpl(pageRef)->process().processPool()); } WKPageGroupRef WKPageGetPageGroup(WKPageRef pageRef) @@ -80,14 +144,25 @@ WKPageGroupRef WKPageGetPageGroup(WKPageRef pageRef) return toAPI(&toImpl(pageRef)->pageGroup()); } +WKPageConfigurationRef WKPageCopyPageConfiguration(WKPageRef pageRef) +{ + return toAPI(&toImpl(pageRef)->configuration().copy().leakRef()); +} + void WKPageLoadURL(WKPageRef pageRef, WKURLRef URLRef) { - toImpl(pageRef)->loadRequest(toWTFString(URLRef)); + toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef))); +} + +void WKPageLoadURLWithShouldOpenExternalURLsPolicy(WKPageRef pageRef, WKURLRef URLRef, bool shouldOpenExternalURLs) +{ + ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = shouldOpenExternalURLs ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow; + toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)), shouldOpenExternalURLsPolicy); } void WKPageLoadURLWithUserData(WKPageRef pageRef, WKURLRef URLRef, WKTypeRef userDataRef) { - toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)), toImpl(userDataRef)); + toImpl(pageRef)->loadRequest(URL(URL(), toWTFString(URLRef)), ShouldOpenExternalURLsPolicy::ShouldNotAllow, toImpl(userDataRef)); } void WKPageLoadURLRequest(WKPageRef pageRef, WKURLRequestRef urlRequestRef) @@ -97,7 +172,7 @@ void WKPageLoadURLRequest(WKPageRef pageRef, WKURLRequestRef urlRequestRef) void WKPageLoadURLRequestWithUserData(WKPageRef pageRef, WKURLRequestRef urlRequestRef, WKTypeRef userDataRef) { - toImpl(pageRef)->loadRequest(toImpl(urlRequestRef)->resourceRequest(), toImpl(userDataRef)); + toImpl(pageRef)->loadRequest(toImpl(urlRequestRef)->resourceRequest(), ShouldOpenExternalURLsPolicy::ShouldNotAllow, toImpl(userDataRef)); } void WKPageLoadFile(WKPageRef pageRef, WKURLRef fileURL, WKURLRef resourceDirectoryURL) @@ -167,12 +242,23 @@ void WKPageStopLoading(WKPageRef pageRef) void WKPageReload(WKPageRef pageRef) { - toImpl(pageRef)->reload(false); + const bool reloadFromOrigin = false; + const bool contentBlockersEnabled = true; + toImpl(pageRef)->reload(reloadFromOrigin, contentBlockersEnabled); +} + +void WKPageReloadWithoutContentBlockers(WKPageRef pageRef) +{ + const bool reloadFromOrigin = false; + const bool contentBlockersEnabled = false; + toImpl(pageRef)->reload(reloadFromOrigin, contentBlockersEnabled); } void WKPageReloadFromOrigin(WKPageRef pageRef) { - toImpl(pageRef)->reload(true); + const bool reloadFromOrigin = true; + const bool contentBlockersEnabled = true; + toImpl(pageRef)->reload(reloadFromOrigin, contentBlockersEnabled); } bool WKPageTryClose(WKPageRef pageRef) @@ -230,6 +316,11 @@ bool WKPageWillHandleHorizontalScrollEvents(WKPageRef pageRef) return toImpl(pageRef)->willHandleHorizontalScrollEvents(); } +void WKPageUpdateWebsitePolicies(WKPageRef pageRef, WKWebsitePoliciesRef websitePoliciesRef) +{ + toImpl(pageRef)->updateWebsitePolicies(toImpl(websitePoliciesRef)->websitePolicies()); +} + WKStringRef WKPageCopyTitle(WKPageRef pageRef) { return toCopiedAPI(toImpl(pageRef)->pageLoadState().title()); @@ -257,12 +348,7 @@ uint64_t WKPageGetRenderTreeSize(WKPageRef page) WKInspectorRef WKPageGetInspector(WKPageRef pageRef) { -#if defined(ENABLE_INSPECTOR) && ENABLE_INSPECTOR return toAPI(toImpl(pageRef)->inspector()); -#else - UNUSED_PARAM(pageRef); - return 0; -#endif } WKVibrationRef WKPageGetVibration(WKPageRef page) @@ -280,11 +366,6 @@ double WKPageGetEstimatedProgress(WKPageRef pageRef) return toImpl(pageRef)->estimatedProgress(); } -void WKPageSetMemoryCacheClientCallsEnabled(WKPageRef pageRef, bool memoryCacheClientCallsEnabled) -{ - toImpl(pageRef)->setMemoryCacheClientCallsEnabled(memoryCacheClientCallsEnabled); -} - WKStringRef WKPageCopyUserAgent(WKPageRef pageRef) { return toCopiedAPI(toImpl(pageRef)->userAgent()); @@ -310,6 +391,11 @@ void WKPageSetCustomUserAgent(WKPageRef pageRef, WKStringRef userAgentRef) toImpl(pageRef)->setCustomUserAgent(toWTFString(userAgentRef)); } +void WKPageSetUserContentExtensionsEnabled(WKPageRef pageRef, bool enabled) +{ + // FIXME: Remove this function once it is no longer used. +} + bool WKPageSupportsTextEncoding(WKPageRef pageRef) { return toImpl(pageRef)->supportsTextEncoding(); @@ -332,24 +418,65 @@ void WKPageTerminate(WKPageRef pageRef) WKStringRef WKPageGetSessionHistoryURLValueType() { - static API::String* sessionHistoryURLValueType = API::String::create("SessionHistoryURL").leakRef(); - return toAPI(sessionHistoryURLValueType); + static API::String& sessionHistoryURLValueType = API::String::create("SessionHistoryURL").leakRef(); + return toAPI(&sessionHistoryURLValueType); } WKStringRef WKPageGetSessionBackForwardListItemValueType() { - static API::String* sessionBackForwardListValueType = API::String::create("SessionBackForwardListItem").leakRef(); - return toAPI(sessionBackForwardListValueType); + static API::String& sessionBackForwardListValueType = API::String::create("SessionBackForwardListItem").leakRef(); + return toAPI(&sessionBackForwardListValueType); +} + +WKTypeRef WKPageCopySessionState(WKPageRef pageRef, void* context, WKPageSessionStateFilterCallback filter) +{ + // FIXME: This is a hack to make sure we return a WKDataRef to maintain compatibility with older versions of Safari. + bool shouldReturnData = !(reinterpret_cast<uintptr_t>(context) & 1); + context = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(context) & ~1); + + auto sessionState = toImpl(pageRef)->sessionState([pageRef, context, filter](WebBackForwardListItem& item) { + if (filter) { + if (!filter(pageRef, WKPageGetSessionBackForwardListItemValueType(), toAPI(&item), context)) + return false; + + if (!filter(pageRef, WKPageGetSessionHistoryURLValueType(), toURLRef(item.originalURL().impl()), context)) + return false; + } + + return true; + }); + + if (shouldReturnData) + return toAPI(encodeLegacySessionState(sessionState).leakRef()); + + return toAPI(&API::SessionState::create(WTFMove(sessionState)).leakRef()); +} + +static void restoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef, bool navigate) +{ + SessionState sessionState; + + // FIXME: This is for backwards compatibility with Safari. Remove it once Safari no longer depends on it. + if (toImpl(sessionStateRef)->type() == API::Object::Type::Data) { + if (!decodeLegacySessionState(toImpl(static_cast<WKDataRef>(sessionStateRef))->bytes(), toImpl(static_cast<WKDataRef>(sessionStateRef))->size(), sessionState)) + return; + } else { + ASSERT(toImpl(sessionStateRef)->type() == API::Object::Type::SessionState); + + sessionState = toImpl(static_cast<WKSessionStateRef>(sessionStateRef))->sessionState(); + } + + toImpl(pageRef)->restoreFromSessionState(WTFMove(sessionState), navigate); } -WKDataRef WKPageCopySessionState(WKPageRef pageRef, void *context, WKPageSessionStateFilterCallback filter) +void WKPageRestoreFromSessionState(WKPageRef pageRef, WKTypeRef sessionStateRef) { - return toAPI(toImpl(pageRef)->sessionStateData(filter, context).leakRef()); + restoreFromSessionState(pageRef, sessionStateRef, true); } -void WKPageRestoreFromSessionState(WKPageRef pageRef, WKDataRef sessionStateData) +void WKPageRestoreFromSessionStateWithoutNavigation(WKPageRef pageRef, WKTypeRef sessionStateRef) { - toImpl(pageRef)->restoreFromSessionStateData(toImpl(sessionStateData)); + restoreFromSessionState(pageRef, sessionStateRef, false); } double WKPageGetTextZoomFactor(WKPageRef pageRef) @@ -427,12 +554,6 @@ void WKPageListenForLayoutMilestones(WKPageRef pageRef, WKLayoutMilestones miles toImpl(pageRef)->listenForLayoutMilestones(toLayoutMilestones(milestones)); } -void WKPageSetVisibilityState(WKPageRef pageRef, WKPageVisibilityState state, bool) -{ - if (state == kWKPageVisibilityStatePrerender) - toImpl(pageRef)->setVisibilityStatePrerender(); -} - bool WKPageHasHorizontalScrollbar(WKPageRef pageRef) { return toImpl(pageRef)->hasHorizontalScrollbar(); @@ -513,6 +634,26 @@ void WKPageSetRubberBandsAtBottom(WKPageRef pageRef, bool rubberBandsAtBottom) toImpl(pageRef)->setRubberBandsAtBottom(rubberBandsAtBottom); } +bool WKPageVerticalRubberBandingIsEnabled(WKPageRef pageRef) +{ + return toImpl(pageRef)->verticalRubberBandingIsEnabled(); +} + +void WKPageSetEnableVerticalRubberBanding(WKPageRef pageRef, bool enableVerticalRubberBanding) +{ + toImpl(pageRef)->setEnableVerticalRubberBanding(enableVerticalRubberBanding); +} + +bool WKPageHorizontalRubberBandingIsEnabled(WKPageRef pageRef) +{ + return toImpl(pageRef)->horizontalRubberBandingIsEnabled(); +} + +void WKPageSetEnableHorizontalRubberBanding(WKPageRef pageRef, bool enableHorizontalRubberBanding) +{ + toImpl(pageRef)->setEnableHorizontalRubberBanding(enableHorizontalRubberBanding); +} + void WKPageSetBackgroundExtendsBeyondPage(WKPageRef pageRef, bool backgroundExtendsBeyondPage) { toImpl(pageRef)->setBackgroundExtendsBeyondPage(backgroundExtendsBeyondPage); @@ -597,6 +738,16 @@ double WKPageGetGapBetweenPages(WKPageRef pageRef) return toImpl(pageRef)->gapBetweenPages(); } +void WKPageSetPaginationLineGridEnabled(WKPageRef pageRef, bool lineGridEnabled) +{ + toImpl(pageRef)->setPaginationLineGridEnabled(lineGridEnabled); +} + +bool WKPageGetPaginationLineGridEnabled(WKPageRef pageRef) +{ + return toImpl(pageRef)->paginationLineGridEnabled(); +} + unsigned WKPageGetPageCount(WKPageRef pageRef) { return toImpl(pageRef)->pageCount(); @@ -660,26 +811,206 @@ void WKPageCountStringMatches(WKPageRef pageRef, WKStringRef string, WKFindOptio void WKPageSetPageContextMenuClient(WKPageRef pageRef, const WKPageContextMenuClientBase* wkClient) { #if ENABLE(CONTEXT_MENUS) - toImpl(pageRef)->initializeContextMenuClient(wkClient); + class ContextMenuClient final : public API::Client<WKPageContextMenuClientBase>, public API::ContextMenuClient { + public: + explicit ContextMenuClient(const WKPageContextMenuClientBase* client) + { + initialize(client); + } + + private: + bool getContextMenuFromProposedMenu(WebPageProxy& page, const Vector<RefPtr<WebKit::WebContextMenuItem>>& proposedMenuVector, Vector<RefPtr<WebKit::WebContextMenuItem>>& customMenu, const WebHitTestResultData& hitTestResultData, API::Object* userData) override + { + if (!m_client.getContextMenuFromProposedMenu && !m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0) + return false; + + if (m_client.base.version >= 2 && !m_client.getContextMenuFromProposedMenu) + return false; + + Vector<RefPtr<API::Object>> proposedMenuItems; + proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size()); + + for (const auto& menuItem : proposedMenuVector) + proposedMenuItems.uncheckedAppend(menuItem); + + WKArrayRef newMenu = nullptr; + if (m_client.base.version >= 2) { + RefPtr<API::HitTestResult> webHitTestResult = API::HitTestResult::create(hitTestResultData); + m_client.getContextMenuFromProposedMenu(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(webHitTestResult.get()), toAPI(userData), m_client.base.clientInfo); + } else + m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), &newMenu, toAPI(userData), m_client.base.clientInfo); + + RefPtr<API::Array> array = adoptRef(toImpl(newMenu)); + + customMenu.clear(); + + size_t newSize = array ? array->size() : 0; + for (size_t i = 0; i < newSize; ++i) { + WebContextMenuItem* item = array->at<WebContextMenuItem>(i); + if (!item) { + LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i); + continue; + } + + customMenu.append(item); + } + + return true; + } + + bool getContextMenuFromProposedMenuAsync(WebPageProxy& page, const Vector<RefPtr<WebKit::WebContextMenuItem>>& proposedMenuVector, WebKit::WebContextMenuListenerProxy* contextMenuListener, const WebHitTestResultData& hitTestResultData, API::Object* userData) override + { + if (m_client.base.version < 4 || !m_client.getContextMenuFromProposedMenuAsync) + return false; + + Vector<RefPtr<API::Object>> proposedMenuItems; + proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size()); + + for (const auto& menuItem : proposedMenuVector) + proposedMenuItems.uncheckedAppend(menuItem); + + RefPtr<API::HitTestResult> webHitTestResult = API::HitTestResult::create(hitTestResultData); + m_client.getContextMenuFromProposedMenuAsync(toAPI(&page), toAPI(API::Array::create(WTFMove(proposedMenuItems)).ptr()), toAPI(contextMenuListener), toAPI(webHitTestResult.get()), toAPI(userData), m_client.base.clientInfo); + + return true; + } + + void customContextMenuItemSelected(WebPageProxy& page, const WebContextMenuItemData& itemData) override + { + if (!m_client.customContextMenuItemSelected) + return; + + m_client.customContextMenuItemSelected(toAPI(&page), toAPI(WebContextMenuItem::create(itemData).ptr()), m_client.base.clientInfo); + } + + bool showContextMenu(WebPageProxy& page, const WebCore::IntPoint& menuLocation, const Vector<RefPtr<WebContextMenuItem>>& menuItemsVector) override + { + if (!m_client.showContextMenu) + return false; + + Vector<RefPtr<API::Object>> menuItems; + menuItems.reserveInitialCapacity(menuItemsVector.size()); + + for (const auto& menuItem : menuItemsVector) + menuItems.uncheckedAppend(menuItem); + + m_client.showContextMenu(toAPI(&page), toAPI(menuLocation), toAPI(API::Array::create(WTFMove(menuItems)).ptr()), m_client.base.clientInfo); + + return true; + } + + bool hideContextMenu(WebPageProxy& page) override + { + if (!m_client.hideContextMenu) + return false; + + m_client.hideContextMenu(toAPI(&page), m_client.base.clientInfo); + + return true; + } + }; + + toImpl(pageRef)->setContextMenuClient(std::make_unique<ContextMenuClient>(wkClient)); #else UNUSED_PARAM(pageRef); UNUSED_PARAM(wkClient); #endif } +void WKPageSetPageDiagnosticLoggingClient(WKPageRef pageRef, const WKPageDiagnosticLoggingClientBase* wkClient) +{ + toImpl(pageRef)->setDiagnosticLoggingClient(std::make_unique<WebPageDiagnosticLoggingClient>(wkClient)); +} + void WKPageSetPageFindClient(WKPageRef pageRef, const WKPageFindClientBase* wkClient) { - toImpl(pageRef)->initializeFindClient(wkClient); + class FindClient : public API::Client<WKPageFindClientBase>, public API::FindClient { + public: + explicit FindClient(const WKPageFindClientBase* client) + { + initialize(client); + } + + private: + void didFindString(WebPageProxy* page, const String& string, const Vector<WebCore::IntRect>&, uint32_t matchCount, int32_t) override + { + if (!m_client.didFindString) + return; + + m_client.didFindString(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo); + } + + void didFailToFindString(WebPageProxy* page, const String& string) override + { + if (!m_client.didFailToFindString) + return; + + m_client.didFailToFindString(toAPI(page), toAPI(string.impl()), m_client.base.clientInfo); + } + + void didCountStringMatches(WebPageProxy* page, const String& string, uint32_t matchCount) override + { + if (!m_client.didCountStringMatches) + return; + + m_client.didCountStringMatches(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo); + } + }; + + toImpl(pageRef)->setFindClient(std::make_unique<FindClient>(wkClient)); } void WKPageSetPageFindMatchesClient(WKPageRef pageRef, const WKPageFindMatchesClientBase* wkClient) { - toImpl(pageRef)->initializeFindMatchesClient(wkClient); + class FindMatchesClient : public API::Client<WKPageFindMatchesClientBase>, public API::FindMatchesClient { + public: + explicit FindMatchesClient(const WKPageFindMatchesClientBase* client) + { + initialize(client); + } + + private: + void didFindStringMatches(WebPageProxy* page, const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t index) override + { + if (!m_client.didFindStringMatches) + return; + + Vector<RefPtr<API::Object>> matches; + matches.reserveInitialCapacity(matchRects.size()); + + for (const auto& rects : matchRects) { + Vector<RefPtr<API::Object>> apiRects; + apiRects.reserveInitialCapacity(rects.size()); + + for (const auto& rect : rects) + apiRects.uncheckedAppend(API::Rect::create(toAPI(rect))); + + matches.uncheckedAppend(API::Array::create(WTFMove(apiRects))); + } + + m_client.didFindStringMatches(toAPI(page), toAPI(string.impl()), toAPI(API::Array::create(WTFMove(matches)).ptr()), index, m_client.base.clientInfo); + } + + void didGetImageForMatchResult(WebPageProxy* page, WebImage* image, int32_t index) override + { + if (!m_client.didGetImageForMatchResult) + return; + + m_client.didGetImageForMatchResult(toAPI(page), toAPI(image), index, m_client.base.clientInfo); + } + }; + + toImpl(pageRef)->setFindMatchesClient(std::make_unique<FindMatchesClient>(wkClient)); +} + +void WKPageSetPageInjectedBundleClient(WKPageRef pageRef, const WKPageInjectedBundleClientBase* wkClient) +{ + toImpl(pageRef)->setInjectedBundleClient(wkClient); } void WKPageSetPageFormClient(WKPageRef pageRef, const WKPageFormClientBase* wkClient) { - toImpl(pageRef)->initializeFormClient(wkClient); + toImpl(pageRef)->setFormClient(std::make_unique<WebFormClient>(wkClient)); } void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* wkClient) @@ -692,255 +1023,271 @@ void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* } private: - virtual void didStartProvisionalLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didStartProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override { if (!m_client.didStartProvisionalLoadForFrame) return; - m_client.didStartProvisionalLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didStartProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override { if (!m_client.didReceiveServerRedirectForProvisionalLoadForFrame) return; - m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didReceiveServerRedirectForProvisionalLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFailProvisionalLoadWithErrorForFrame(WebPageProxy* page, WebFrameProxy* frame, const ResourceError& error, API::Object* userData) override + void didFailProvisionalLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const ResourceError& error, API::Object* userData) override { if (!m_client.didFailProvisionalLoadWithErrorForFrame) return; - m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); + m_client.didFailProvisionalLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); } - virtual void didCommitLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didCommitLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override { if (!m_client.didCommitLoadForFrame) return; - m_client.didCommitLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didCommitLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFinishDocumentLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didFinishDocumentLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override { if (!m_client.didFinishDocumentLoadForFrame) return; - m_client.didFinishDocumentLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didFinishDocumentLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFinishLoadForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didFinishLoadForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, API::Object* userData) override { if (!m_client.didFinishLoadForFrame) return; - m_client.didFinishLoadForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didFinishLoadForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFailLoadWithErrorForFrame(WebPageProxy* page, WebFrameProxy* frame, const ResourceError& error, API::Object* userData) override + void didFailLoadWithErrorForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, const ResourceError& error, API::Object* userData) override { if (!m_client.didFailLoadWithErrorForFrame) return; - m_client.didFailLoadWithErrorForFrame(toAPI(page), toAPI(frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); + m_client.didFailLoadWithErrorForFrame(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); } - virtual void didSameDocumentNavigationForFrame(WebPageProxy* page, WebFrameProxy* frame, SameDocumentNavigationType type, API::Object* userData) override + void didSameDocumentNavigationForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Navigation*, SameDocumentNavigationType type, API::Object* userData) override { if (!m_client.didSameDocumentNavigationForFrame) return; - m_client.didSameDocumentNavigationForFrame(toAPI(page), toAPI(frame), toAPI(type), toAPI(userData), m_client.base.clientInfo); + m_client.didSameDocumentNavigationForFrame(toAPI(&page), toAPI(&frame), toAPI(type), toAPI(userData), m_client.base.clientInfo); } - virtual void didReceiveTitleForFrame(WebPageProxy* page, const String& title, WebFrameProxy* frame, API::Object* userData) override + void didReceiveTitleForFrame(WebPageProxy& page, const String& title, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didReceiveTitleForFrame) return; - m_client.didReceiveTitleForFrame(toAPI(page), toAPI(title.impl()), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didReceiveTitleForFrame(toAPI(&page), toAPI(title.impl()), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFirstLayoutForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didFirstLayoutForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didFirstLayoutForFrame) return; - m_client.didFirstLayoutForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didFirstLayoutForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didFirstVisuallyNonEmptyLayoutForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didFirstVisuallyNonEmptyLayoutForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didFirstVisuallyNonEmptyLayoutForFrame) return; - m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didFirstVisuallyNonEmptyLayoutForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didLayout(WebPageProxy* page, LayoutMilestones milestones, API::Object* userData) override + void didReachLayoutMilestone(WebPageProxy& page, LayoutMilestones milestones) override { if (!m_client.didLayout) return; - m_client.didLayout(toAPI(page), toWKLayoutMilestones(milestones), toAPI(userData), m_client.base.clientInfo); + m_client.didLayout(toAPI(&page), toWKLayoutMilestones(milestones), nullptr, m_client.base.clientInfo); } - virtual void didRemoveFrameFromHierarchy(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override - { - if (!m_client.didRemoveFrameFromHierarchy) - return; - - m_client.didRemoveFrameFromHierarchy(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); - } - - virtual void didDisplayInsecureContentForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didDisplayInsecureContentForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didDisplayInsecureContentForFrame) return; - m_client.didDisplayInsecureContentForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didDisplayInsecureContentForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didRunInsecureContentForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didRunInsecureContentForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didRunInsecureContentForFrame) return; - m_client.didRunInsecureContentForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didRunInsecureContentForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual void didDetectXSSForFrame(WebPageProxy* page, WebFrameProxy* frame, API::Object* userData) override + void didDetectXSSForFrame(WebPageProxy& page, WebFrameProxy& frame, API::Object* userData) override { if (!m_client.didDetectXSSForFrame) return; - m_client.didDetectXSSForFrame(toAPI(page), toAPI(frame), toAPI(userData), m_client.base.clientInfo); + m_client.didDetectXSSForFrame(toAPI(&page), toAPI(&frame), toAPI(userData), m_client.base.clientInfo); } - virtual bool canAuthenticateAgainstProtectionSpaceInFrame(WebPageProxy* page, WebFrameProxy* frame, WebProtectionSpace* protectionSpace) override + bool canAuthenticateAgainstProtectionSpaceInFrame(WebPageProxy& page, WebFrameProxy& frame, WebProtectionSpace* protectionSpace) override { if (!m_client.canAuthenticateAgainstProtectionSpaceInFrame) return false; - return m_client.canAuthenticateAgainstProtectionSpaceInFrame(toAPI(page), toAPI(frame), toAPI(protectionSpace), m_client.base.clientInfo); + return m_client.canAuthenticateAgainstProtectionSpaceInFrame(toAPI(&page), toAPI(&frame), toAPI(protectionSpace), m_client.base.clientInfo); } - virtual void didReceiveAuthenticationChallengeInFrame(WebPageProxy* page, WebFrameProxy* frame, AuthenticationChallengeProxy* authenticationChallenge) override + void didReceiveAuthenticationChallengeInFrame(WebPageProxy& page, WebFrameProxy& frame, AuthenticationChallengeProxy* authenticationChallenge) override { if (!m_client.didReceiveAuthenticationChallengeInFrame) return; - m_client.didReceiveAuthenticationChallengeInFrame(toAPI(page), toAPI(frame), toAPI(authenticationChallenge), m_client.base.clientInfo); + m_client.didReceiveAuthenticationChallengeInFrame(toAPI(&page), toAPI(&frame), toAPI(authenticationChallenge), m_client.base.clientInfo); } - virtual void didStartProgress(WebPageProxy* page) override + void didStartProgress(WebPageProxy& page) override { if (!m_client.didStartProgress) return; - m_client.didStartProgress(toAPI(page), m_client.base.clientInfo); + m_client.didStartProgress(toAPI(&page), m_client.base.clientInfo); } - virtual void didChangeProgress(WebPageProxy* page) override + void didChangeProgress(WebPageProxy& page) override { if (!m_client.didChangeProgress) return; - m_client.didChangeProgress(toAPI(page), m_client.base.clientInfo); + m_client.didChangeProgress(toAPI(&page), m_client.base.clientInfo); } - virtual void didFinishProgress(WebPageProxy* page) override + void didFinishProgress(WebPageProxy& page) override { if (!m_client.didFinishProgress) return; - m_client.didFinishProgress(toAPI(page), m_client.base.clientInfo); + m_client.didFinishProgress(toAPI(&page), m_client.base.clientInfo); } - virtual void processDidBecomeUnresponsive(WebPageProxy* page) override + void processDidBecomeUnresponsive(WebPageProxy& page) override { if (!m_client.processDidBecomeUnresponsive) return; - m_client.processDidBecomeUnresponsive(toAPI(page), m_client.base.clientInfo); - } - - virtual void interactionOccurredWhileProcessUnresponsive(WebPageProxy* page) override - { - if (!m_client.interactionOccurredWhileProcessUnresponsive) - return; - - m_client.interactionOccurredWhileProcessUnresponsive(toAPI(page), m_client.base.clientInfo); + m_client.processDidBecomeUnresponsive(toAPI(&page), m_client.base.clientInfo); } - virtual void processDidBecomeResponsive(WebPageProxy* page) override + void processDidBecomeResponsive(WebPageProxy& page) override { if (!m_client.processDidBecomeResponsive) return; - m_client.processDidBecomeResponsive(toAPI(page), m_client.base.clientInfo); + m_client.processDidBecomeResponsive(toAPI(&page), m_client.base.clientInfo); } - virtual void processDidCrash(WebPageProxy* page) override + void processDidCrash(WebPageProxy& page) override { if (!m_client.processDidCrash) return; - m_client.processDidCrash(toAPI(page), m_client.base.clientInfo); + m_client.processDidCrash(toAPI(&page), m_client.base.clientInfo); } - virtual void didChangeBackForwardList(WebPageProxy* page, WebBackForwardListItem* addedItem, Vector<RefPtr<API::Object>>* removedItems) override + void didChangeBackForwardList(WebPageProxy& page, WebBackForwardListItem* addedItem, Vector<RefPtr<WebBackForwardListItem>> removedItems) override { if (!m_client.didChangeBackForwardList) return; RefPtr<API::Array> removedItemsArray; - if (removedItems && !removedItems->isEmpty()) - removedItemsArray = API::Array::create(std::move(*removedItems)); + if (!removedItems.isEmpty()) { + Vector<RefPtr<API::Object>> removedItemsVector; + removedItemsVector.reserveInitialCapacity(removedItems.size()); + for (auto& removedItem : removedItems) + removedItemsVector.append(WTFMove(removedItem)); - m_client.didChangeBackForwardList(toAPI(page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.base.clientInfo); + removedItemsArray = API::Array::create(WTFMove(removedItemsVector)); + } + + m_client.didChangeBackForwardList(toAPI(&page), toAPI(addedItem), toAPI(removedItemsArray.get()), m_client.base.clientInfo); + } + + bool shouldKeepCurrentBackForwardListItemInList(WebKit::WebPageProxy& page, WebKit::WebBackForwardListItem* item) override + { + if (!m_client.shouldKeepCurrentBackForwardListItemInList) + return true; + + return m_client.shouldKeepCurrentBackForwardListItemInList(toAPI(&page), toAPI(item), m_client.base.clientInfo); } - virtual void willGoToBackForwardListItem(WebPageProxy* page, WebBackForwardListItem* item, API::Object* userData) override + void willGoToBackForwardListItem(WebPageProxy& page, WebBackForwardListItem* item, API::Object* userData) override { if (m_client.willGoToBackForwardListItem) - m_client.willGoToBackForwardListItem(toAPI(page), toAPI(item), toAPI(userData), m_client.base.clientInfo); + m_client.willGoToBackForwardListItem(toAPI(&page), toAPI(item), toAPI(userData), m_client.base.clientInfo); + } + + void navigationGestureDidBegin(WebPageProxy& page) override + { + if (m_client.navigationGestureDidBegin) + m_client.navigationGestureDidBegin(toAPI(&page), m_client.base.clientInfo); + } + + void navigationGestureWillEnd(WebPageProxy& page, bool willNavigate, WebBackForwardListItem& item) override + { + if (m_client.navigationGestureWillEnd) + m_client.navigationGestureWillEnd(toAPI(&page), willNavigate, toAPI(&item), m_client.base.clientInfo); + } + + void navigationGestureDidEnd(WebPageProxy& page, bool willNavigate, WebBackForwardListItem& item) override + { + if (m_client.navigationGestureDidEnd) + m_client.navigationGestureDidEnd(toAPI(&page), willNavigate, toAPI(&item), m_client.base.clientInfo); } #if ENABLE(NETSCAPE_PLUGIN_API) - virtual void didFailToInitializePlugin(WebPageProxy* page, ImmutableDictionary* pluginInformation) override + void didFailToInitializePlugin(WebPageProxy& page, API::Dictionary* pluginInformation) override { if (m_client.didFailToInitializePlugin_deprecatedForUseWithV0) - m_client.didFailToInitializePlugin_deprecatedForUseWithV0(toAPI(page), toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), m_client.base.clientInfo); + m_client.didFailToInitializePlugin_deprecatedForUseWithV0(toAPI(&page), toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), m_client.base.clientInfo); if (m_client.pluginDidFail_deprecatedForUseWithV1) - m_client.pluginDidFail_deprecatedForUseWithV1(toAPI(page), kWKErrorCodeCannotLoadPlugIn, toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), 0, 0, m_client.base.clientInfo); + m_client.pluginDidFail_deprecatedForUseWithV1(toAPI(&page), kWKErrorCodeCannotLoadPlugIn, toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), 0, 0, m_client.base.clientInfo); if (m_client.pluginDidFail) - m_client.pluginDidFail(toAPI(page), kWKErrorCodeCannotLoadPlugIn, toAPI(pluginInformation), m_client.base.clientInfo); + m_client.pluginDidFail(toAPI(&page), kWKErrorCodeCannotLoadPlugIn, toAPI(pluginInformation), m_client.base.clientInfo); } - virtual void didBlockInsecurePluginVersion(WebPageProxy* page, ImmutableDictionary* pluginInformation) override + void didBlockInsecurePluginVersion(WebPageProxy& page, API::Dictionary* pluginInformation) override { if (m_client.pluginDidFail_deprecatedForUseWithV1) - m_client.pluginDidFail_deprecatedForUseWithV1(toAPI(page), kWKErrorCodeInsecurePlugInVersion, toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), toAPI(pluginInformation->get<API::String>(pluginInformationBundleIdentifierKey())), toAPI(pluginInformation->get<API::String>(pluginInformationBundleVersionKey())), m_client.base.clientInfo); + m_client.pluginDidFail_deprecatedForUseWithV1(toAPI(&page), kWKErrorCodeInsecurePlugInVersion, toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), toAPI(pluginInformation->get<API::String>(pluginInformationBundleIdentifierKey())), toAPI(pluginInformation->get<API::String>(pluginInformationBundleVersionKey())), m_client.base.clientInfo); if (m_client.pluginDidFail) - m_client.pluginDidFail(toAPI(page), kWKErrorCodeInsecurePlugInVersion, toAPI(pluginInformation), m_client.base.clientInfo); + m_client.pluginDidFail(toAPI(&page), kWKErrorCodeInsecurePlugInVersion, toAPI(pluginInformation), m_client.base.clientInfo); } - virtual PluginModuleLoadPolicy pluginLoadPolicy(WebPageProxy* page, PluginModuleLoadPolicy currentPluginLoadPolicy, ImmutableDictionary* pluginInformation, String& unavailabilityDescription) override + PluginModuleLoadPolicy pluginLoadPolicy(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary* pluginInformation, String& unavailabilityDescription) override { WKStringRef unavailabilityDescriptionOut = 0; PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy; if (m_client.pluginLoadPolicy_deprecatedForUseWithV2) - loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy_deprecatedForUseWithV2(toAPI(page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), m_client.base.clientInfo)); + loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy_deprecatedForUseWithV2(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), m_client.base.clientInfo)); else if (m_client.pluginLoadPolicy) - loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy(toAPI(page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo)); + loadPolicy = toPluginModuleLoadPolicy(m_client.pluginLoadPolicy(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo)); if (unavailabilityDescriptionOut) { RefPtr<API::String> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut)); @@ -952,15 +1299,26 @@ void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(WEBGL) - virtual WebCore::WebGLLoadPolicy webGLLoadPolicy(WebPageProxy* page, const String& url) const override + WebCore::WebGLLoadPolicy webGLLoadPolicy(WebPageProxy& page, const String& url) const override { - WebCore::WebGLLoadPolicy loadPolicy = WebGLAllow; + WebCore::WebGLLoadPolicy loadPolicy = WebGLAllowCreation; if (m_client.webGLLoadPolicy) - loadPolicy = toWebGLLoadPolicy(m_client.webGLLoadPolicy(toAPI(page), toAPI(url.impl()), m_client.base.clientInfo)); + loadPolicy = toWebGLLoadPolicy(m_client.webGLLoadPolicy(toAPI(&page), toAPI(url.impl()), m_client.base.clientInfo)); return loadPolicy; } + + WebCore::WebGLLoadPolicy resolveWebGLLoadPolicy(WebPageProxy& page, const String& url) const override + { + WebCore::WebGLLoadPolicy loadPolicy = WebGLAllowCreation; + + if (m_client.resolveWebGLLoadPolicy) + loadPolicy = toWebGLLoadPolicy(m_client.resolveWebGLLoadPolicy(toAPI(&page), toAPI(url.impl()), m_client.base.clientInfo)); + + return loadPolicy; + } + #endif // ENABLE(WEBGL) }; @@ -980,7 +1338,7 @@ void WKPageSetPageLoaderClient(WKPageRef pageRef, const WKPageLoaderClientBase* if (milestones) webPageProxy->process().send(Messages::WebPage::ListenForLayoutMilestones(milestones), webPageProxy->pageID()); - webPageProxy->setLoaderClient(std::move(loaderClient)); + webPageProxy->setLoaderClient(WTFMove(loaderClient)); } void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClientBase* wkClient) @@ -993,77 +1351,1096 @@ void WKPageSetPagePolicyClient(WKPageRef pageRef, const WKPagePolicyClientBase* } private: - virtual void decidePolicyForNavigationAction(WebPageProxy* page, WebFrameProxy* frame, const NavigationActionData& navigationActionData, WebFrameProxy* originatingFrame, const WebCore::ResourceRequest& originalResourceRequest, const WebCore::ResourceRequest& resourceRequest, WebFramePolicyListenerProxy* listener, API::Object* userData) override + void decidePolicyForNavigationAction(WebPageProxy& page, WebFrameProxy* frame, const NavigationActionData& navigationActionData, WebFrameProxy* originatingFrame, const WebCore::ResourceRequest& originalResourceRequest, const WebCore::ResourceRequest& resourceRequest, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override { if (!m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0 && !m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1 && !m_client.decidePolicyForNavigationAction) { - listener->use(); + listener->use({ }); return; } - RefPtr<API::URLRequest> originalRequest = API::URLRequest::create(originalResourceRequest); - RefPtr<API::URLRequest> request = API::URLRequest::create(resourceRequest); + Ref<API::URLRequest> originalRequest = API::URLRequest::create(originalResourceRequest); + Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest); if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0) - m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0(toAPI(page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(request.get()), toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForNavigationAction_deprecatedForUseWithV0(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); else if (m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1) - m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1(toAPI(page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(request.get()), toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForNavigationAction_deprecatedForUseWithV1(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); else - m_client.decidePolicyForNavigationAction(toAPI(page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(originalRequest.get()), toAPI(request.get()), toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(originatingFrame), toAPI(originalRequest.ptr()), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); } - virtual void decidePolicyForNewWindowAction(WebPageProxy* page, WebFrameProxy* frame, NavigationType type, WebEvent::Modifiers modifiers, WebMouseEvent::Button mouseButton, const ResourceRequest& resourceRequest, const String& frameName, WebFramePolicyListenerProxy* listener, API::Object* userData) override + void decidePolicyForNewWindowAction(WebPageProxy& page, WebFrameProxy& frame, const NavigationActionData& navigationActionData, const ResourceRequest& resourceRequest, const String& frameName, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override { if (!m_client.decidePolicyForNewWindowAction) { - listener->use(); + listener->use({ }); return; } - RefPtr<API::URLRequest> request = API::URLRequest::create(resourceRequest); + Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest); - m_client.decidePolicyForNewWindowAction(toAPI(page), toAPI(frame), toAPI(type), toAPI(modifiers), toAPI(mouseButton), toAPI(request.get()), toAPI(frameName.impl()), toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForNewWindowAction(toAPI(&page), toAPI(&frame), toAPI(navigationActionData.navigationType), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), toAPI(request.ptr()), toAPI(frameName.impl()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); } - virtual void decidePolicyForResponse(WebPageProxy* page, WebFrameProxy* frame, const ResourceResponse& resourceResponse, const ResourceRequest& resourceRequest, bool canShowMIMEType, WebFramePolicyListenerProxy* listener, API::Object* userData) override + void decidePolicyForResponse(WebPageProxy& page, WebFrameProxy& frame, const ResourceResponse& resourceResponse, const ResourceRequest& resourceRequest, bool canShowMIMEType, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* userData) override { if (!m_client.decidePolicyForResponse_deprecatedForUseWithV0 && !m_client.decidePolicyForResponse) { - listener->use(); + listener->use({ }); return; } - RefPtr<API::URLResponse> response = API::URLResponse::create(resourceResponse); - RefPtr<API::URLRequest> request = API::URLRequest::create(resourceRequest); + Ref<API::URLResponse> response = API::URLResponse::create(resourceResponse); + Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest); if (m_client.decidePolicyForResponse_deprecatedForUseWithV0) - m_client.decidePolicyForResponse_deprecatedForUseWithV0(toAPI(page), toAPI(frame), toAPI(response.get()), toAPI(request.get()), toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForResponse_deprecatedForUseWithV0(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); else - m_client.decidePolicyForResponse(toAPI(page), toAPI(frame), toAPI(response.get()), toAPI(request.get()), canShowMIMEType, toAPI(listener), toAPI(userData), m_client.base.clientInfo); + m_client.decidePolicyForResponse(toAPI(&page), toAPI(&frame), toAPI(response.ptr()), toAPI(request.ptr()), canShowMIMEType, toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); } - virtual void unableToImplementPolicy(WebPageProxy* page, WebFrameProxy* frame, const ResourceError& error, API::Object* userData) override + void unableToImplementPolicy(WebPageProxy& page, WebFrameProxy& frame, const ResourceError& error, API::Object* userData) override { if (!m_client.unableToImplementPolicy) return; - m_client.unableToImplementPolicy(toAPI(page), toAPI(frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); + m_client.unableToImplementPolicy(toAPI(&page), toAPI(&frame), toAPI(error), toAPI(userData), m_client.base.clientInfo); } }; toImpl(pageRef)->setPolicyClient(std::make_unique<PolicyClient>(wkClient)); } +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 +static void fixUpBotchedPageUIClient(WKPageRef pageRef, const WKPageUIClientBase& wkClient) +{ + struct BotchedWKPageUIClientV4 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt; + }; + + const auto& botchedPageUIClient = reinterpret_cast<const BotchedWKPageUIClientV4&>(wkClient); + + WKPageUIClientV5 fixedPageUIClient = { + { 5, botchedPageUIClient.base.clientInfo }, + botchedPageUIClient.createNewPage_deprecatedForUseWithV0, + botchedPageUIClient.showPage, + botchedPageUIClient.close, + botchedPageUIClient.takeFocus, + botchedPageUIClient.focus, + botchedPageUIClient.unfocus, + botchedPageUIClient.runJavaScriptAlert_deprecatedForUseWithV0, + botchedPageUIClient.runJavaScriptConfirm_deprecatedForUseWithV0, + botchedPageUIClient.runJavaScriptPrompt_deprecatedForUseWithV0, + botchedPageUIClient.setStatusText, + botchedPageUIClient.mouseDidMoveOverElement_deprecatedForUseWithV0, + botchedPageUIClient.missingPluginButtonClicked_deprecatedForUseWithV0, + botchedPageUIClient.didNotHandleKeyEvent, + botchedPageUIClient.didNotHandleWheelEvent, + botchedPageUIClient.toolbarsAreVisible, + botchedPageUIClient.setToolbarsAreVisible, + botchedPageUIClient.menuBarIsVisible, + botchedPageUIClient.setMenuBarIsVisible, + botchedPageUIClient.statusBarIsVisible, + botchedPageUIClient.setStatusBarIsVisible, + botchedPageUIClient.isResizable, + botchedPageUIClient.setIsResizable, + botchedPageUIClient.getWindowFrame, + botchedPageUIClient.setWindowFrame, + botchedPageUIClient.runBeforeUnloadConfirmPanel, + botchedPageUIClient.didDraw, + botchedPageUIClient.pageDidScroll, + botchedPageUIClient.exceededDatabaseQuota, + botchedPageUIClient.runOpenPanel, + botchedPageUIClient.decidePolicyForGeolocationPermissionRequest, + botchedPageUIClient.headerHeight, + botchedPageUIClient.footerHeight, + botchedPageUIClient.drawHeader, + botchedPageUIClient.drawFooter, + botchedPageUIClient.printFrame, + botchedPageUIClient.runModal, + botchedPageUIClient.unused1, + botchedPageUIClient.saveDataToFileInDownloadsFolder, + botchedPageUIClient.shouldInterruptJavaScript_unavailable, + botchedPageUIClient.createNewPage, + botchedPageUIClient.mouseDidMoveOverElement, + botchedPageUIClient.decidePolicyForNotificationPermissionRequest, + botchedPageUIClient.unavailablePluginButtonClicked_deprecatedForUseWithV1, + botchedPageUIClient.showColorPicker, + botchedPageUIClient.hideColorPicker, + botchedPageUIClient.unavailablePluginButtonClicked, + botchedPageUIClient.pinnedStateDidChange, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + botchedPageUIClient.runJavaScriptAlert, + botchedPageUIClient.runJavaScriptConfirm, + botchedPageUIClient.runJavaScriptPrompt, + nullptr, + }; + + WKPageSetPageUIClient(pageRef, &fixedPageUIClient.base); +} +#endif + +namespace WebKit { + +class RunBeforeUnloadConfirmPanelResultListener : public API::ObjectImpl<API::Object::Type::RunBeforeUnloadConfirmPanelResultListener> { +public: + static PassRefPtr<RunBeforeUnloadConfirmPanelResultListener> create(Function<void (bool)>&& completionHandler) + { + return adoptRef(new RunBeforeUnloadConfirmPanelResultListener(WTFMove(completionHandler))); + } + + virtual ~RunBeforeUnloadConfirmPanelResultListener() + { + } + + void call(bool result) + { + m_completionHandler(result); + } + +private: + explicit RunBeforeUnloadConfirmPanelResultListener(Function<void (bool)>&& completionHandler) + : m_completionHandler(WTFMove(completionHandler)) + { + } + + Function<void (bool)> m_completionHandler; +}; + +class RunJavaScriptAlertResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptAlertResultListener> { +public: + static PassRefPtr<RunJavaScriptAlertResultListener> create(Function<void ()>&& completionHandler) + { + return adoptRef(new RunJavaScriptAlertResultListener(WTFMove(completionHandler))); + } + + virtual ~RunJavaScriptAlertResultListener() + { + } + + void call() + { + m_completionHandler(); + } + +private: + explicit RunJavaScriptAlertResultListener(Function<void ()>&& completionHandler) + : m_completionHandler(WTFMove(completionHandler)) + { + } + + Function<void ()> m_completionHandler; +}; + +class RunJavaScriptConfirmResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptConfirmResultListener> { +public: + static PassRefPtr<RunJavaScriptConfirmResultListener> create(Function<void (bool)>&& completionHandler) + { + return adoptRef(new RunJavaScriptConfirmResultListener(WTFMove(completionHandler))); + } + + virtual ~RunJavaScriptConfirmResultListener() + { + } + + void call(bool result) + { + m_completionHandler(result); + } + +private: + explicit RunJavaScriptConfirmResultListener(Function<void (bool)>&& completionHandler) + : m_completionHandler(WTFMove(completionHandler)) + { + } + + Function<void (bool)> m_completionHandler; +}; + +class RunJavaScriptPromptResultListener : public API::ObjectImpl<API::Object::Type::RunJavaScriptPromptResultListener> { +public: + static PassRefPtr<RunJavaScriptPromptResultListener> create(Function<void (const String&)>&& completionHandler) + { + return adoptRef(new RunJavaScriptPromptResultListener(WTFMove(completionHandler))); + } + + virtual ~RunJavaScriptPromptResultListener() + { + } + + void call(const String& result) + { + m_completionHandler(result); + } + +private: + explicit RunJavaScriptPromptResultListener(Function<void (const String&)>&& completionHandler) + : m_completionHandler(WTFMove(completionHandler)) + { + } + + Function<void (const String&)> m_completionHandler; +}; + +WK_ADD_API_MAPPING(WKPageRunBeforeUnloadConfirmPanelResultListenerRef, RunBeforeUnloadConfirmPanelResultListener) +WK_ADD_API_MAPPING(WKPageRunJavaScriptAlertResultListenerRef, RunJavaScriptAlertResultListener) +WK_ADD_API_MAPPING(WKPageRunJavaScriptConfirmResultListenerRef, RunJavaScriptConfirmResultListener) +WK_ADD_API_MAPPING(WKPageRunJavaScriptPromptResultListenerRef, RunJavaScriptPromptResultListener) + +} + +WKTypeID WKPageRunBeforeUnloadConfirmPanelResultListenerGetTypeID() +{ + return toAPI(RunBeforeUnloadConfirmPanelResultListener::APIType); +} + +void WKPageRunBeforeUnloadConfirmPanelResultListenerCall(WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, bool result) +{ + toImpl(listener)->call(result); +} + +WKTypeID WKPageRunJavaScriptAlertResultListenerGetTypeID() +{ + return toAPI(RunJavaScriptAlertResultListener::APIType); +} + +void WKPageRunJavaScriptAlertResultListenerCall(WKPageRunJavaScriptAlertResultListenerRef listener) +{ + toImpl(listener)->call(); +} + +WKTypeID WKPageRunJavaScriptConfirmResultListenerGetTypeID() +{ + return toAPI(RunJavaScriptConfirmResultListener::APIType); +} + +void WKPageRunJavaScriptConfirmResultListenerCall(WKPageRunJavaScriptConfirmResultListenerRef listener, bool result) +{ + toImpl(listener)->call(result); +} + +WKTypeID WKPageRunJavaScriptPromptResultListenerGetTypeID() +{ + return toAPI(RunJavaScriptPromptResultListener::APIType); +} + +void WKPageRunJavaScriptPromptResultListenerCall(WKPageRunJavaScriptPromptResultListenerRef listener, WKStringRef result) +{ + toImpl(listener)->call(toWTFString(result)); +} + void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient) { - toImpl(pageRef)->initializeUIClient(wkClient); +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 + if (wkClient && wkClient->version == 4) { + fixUpBotchedPageUIClient(pageRef, *wkClient); + return; + } +#endif + + class UIClient : public API::Client<WKPageUIClientBase>, public API::UIClient { + public: + explicit UIClient(const WKPageUIClientBase* client) + { + initialize(client); + } + + private: + PassRefPtr<WebPageProxy> createNewPage(WebPageProxy* page, WebFrameProxy* initiatingFrame, const SecurityOriginData& securityOriginData, const ResourceRequest& resourceRequest, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData) override + { + if (m_client.createNewPage) { + auto configuration = page->configuration().copy(); + configuration->setRelatedPage(page); + + auto sourceFrameInfo = API::FrameInfo::create(*initiatingFrame, securityOriginData.securityOrigin()); + + auto userInitiatedActivity = page->process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier); + bool shouldOpenAppLinks = !hostsAreEqual(WebCore::URL(WebCore::ParsedURLString, initiatingFrame->url()), resourceRequest.url()); + auto apiNavigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.ptr(), nullptr, resourceRequest, WebCore::URL(), shouldOpenAppLinks, userInitiatedActivity); + + auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures); + + return adoptRef(toImpl(m_client.createNewPage(toAPI(page), toAPI(configuration.ptr()), toAPI(apiNavigationAction.ptr()), toAPI(apiWindowFeatures.ptr()), m_client.base.clientInfo))); + } + + if (m_client.createNewPage_deprecatedForUseWithV1 || m_client.createNewPage_deprecatedForUseWithV0) { + API::Dictionary::MapType map; + if (windowFeatures.x) + map.set("x", API::Double::create(*windowFeatures.x)); + if (windowFeatures.y) + map.set("y", API::Double::create(*windowFeatures.y)); + if (windowFeatures.width) + map.set("width", API::Double::create(*windowFeatures.width)); + if (windowFeatures.height) + map.set("height", API::Double::create(*windowFeatures.height)); + map.set("menuBarVisible", API::Boolean::create(windowFeatures.menuBarVisible)); + map.set("statusBarVisible", API::Boolean::create(windowFeatures.statusBarVisible)); + map.set("toolBarVisible", API::Boolean::create(windowFeatures.toolBarVisible)); + map.set("locationBarVisible", API::Boolean::create(windowFeatures.locationBarVisible)); + map.set("scrollbarsVisible", API::Boolean::create(windowFeatures.scrollbarsVisible)); + map.set("resizable", API::Boolean::create(windowFeatures.resizable)); + map.set("fullscreen", API::Boolean::create(windowFeatures.fullscreen)); + map.set("dialog", API::Boolean::create(windowFeatures.dialog)); + Ref<API::Dictionary> featuresMap = API::Dictionary::create(WTFMove(map)); + + if (m_client.createNewPage_deprecatedForUseWithV1) { + Ref<API::URLRequest> request = API::URLRequest::create(resourceRequest); + return adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV1(toAPI(page), toAPI(request.ptr()), toAPI(featuresMap.ptr()), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), m_client.base.clientInfo))); + } + + ASSERT(m_client.createNewPage_deprecatedForUseWithV0); + return adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV0(toAPI(page), toAPI(featuresMap.ptr()), toAPI(navigationActionData.modifiers), toAPI(navigationActionData.mouseButton), m_client.base.clientInfo))); + } + + return nullptr; + } + + void showPage(WebPageProxy* page) override + { + if (!m_client.showPage) + return; + + m_client.showPage(toAPI(page), m_client.base.clientInfo); + } + + void fullscreenMayReturnToInline(WebPageProxy* page) override + { + if (!m_client.fullscreenMayReturnToInline) + return; + + m_client.fullscreenMayReturnToInline(toAPI(page), m_client.base.clientInfo); + } + + void close(WebPageProxy* page) override + { + if (!m_client.close) + return; + + m_client.close(toAPI(page), m_client.base.clientInfo); + } + + void takeFocus(WebPageProxy* page, WKFocusDirection direction) override + { + if (!m_client.takeFocus) + return; + + m_client.takeFocus(toAPI(page), direction, m_client.base.clientInfo); + } + + void focus(WebPageProxy* page) override + { + if (!m_client.focus) + return; + + m_client.focus(toAPI(page), m_client.base.clientInfo); + } + + void unfocus(WebPageProxy* page) override + { + if (!m_client.unfocus) + return; + + m_client.unfocus(toAPI(page), m_client.base.clientInfo); + } + + void runJavaScriptAlert(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void ()>&& completionHandler) override + { + if (m_client.runJavaScriptAlert) { + RefPtr<RunJavaScriptAlertResultListener> listener = RunJavaScriptAlertResultListener::create(WTFMove(completionHandler)); + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + m_client.runJavaScriptAlert(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo); + return; + } + + if (m_client.runJavaScriptAlert_deprecatedForUseWithV5) { + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + m_client.runJavaScriptAlert_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo); + completionHandler(); + return; + } + + if (m_client.runJavaScriptAlert_deprecatedForUseWithV0) { + m_client.runJavaScriptAlert_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); + completionHandler(); + return; + } + + + completionHandler(); + } + + void runJavaScriptConfirm(WebPageProxy* page, const String& message, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void (bool)>&& completionHandler) override + { + if (m_client.runJavaScriptConfirm) { + RefPtr<RunJavaScriptConfirmResultListener> listener = RunJavaScriptConfirmResultListener::create(WTFMove(completionHandler)); + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + m_client.runJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo); + return; + } + + if (m_client.runJavaScriptConfirm_deprecatedForUseWithV5) { + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo); + + completionHandler(result); + return; + } + + if (m_client.runJavaScriptConfirm_deprecatedForUseWithV0) { + bool result = m_client.runJavaScriptConfirm_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); + + completionHandler(result); + return; + } + + completionHandler(false); + } + + void runJavaScriptPrompt(WebPageProxy* page, const String& message, const String& defaultValue, WebFrameProxy* frame, const SecurityOriginData& securityOriginData, Function<void (const String&)>&& completionHandler) override + { + if (m_client.runJavaScriptPrompt) { + RefPtr<RunJavaScriptPromptResultListener> listener = RunJavaScriptPromptResultListener::create(WTFMove(completionHandler)); + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + m_client.runJavaScriptPrompt(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), toAPI(securityOrigin.get()), toAPI(listener.get()), m_client.base.clientInfo); + return; + } + + if (m_client.runJavaScriptPrompt_deprecatedForUseWithV5) { + RefPtr<API::SecurityOrigin> securityOrigin = API::SecurityOrigin::create(securityOriginData.protocol, securityOriginData.host, securityOriginData.port); + RefPtr<API::String> string = adoptRef(toImpl(m_client.runJavaScriptPrompt_deprecatedForUseWithV5(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), toAPI(securityOrigin.get()), m_client.base.clientInfo))); + + if (string) + completionHandler(string->string()); + else + completionHandler(String()); + return; + } + + if (m_client.runJavaScriptPrompt_deprecatedForUseWithV0) { + RefPtr<API::String> string = adoptRef(toImpl(m_client.runJavaScriptPrompt_deprecatedForUseWithV0(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), m_client.base.clientInfo))); + + if (string) + completionHandler(string->string()); + else + completionHandler(String()); + return; + } + + completionHandler(String()); + } + + void setStatusText(WebPageProxy* page, const String& text) override + { + if (!m_client.setStatusText) + return; + + m_client.setStatusText(toAPI(page), toAPI(text.impl()), m_client.base.clientInfo); + } + + void mouseDidMoveOverElement(WebPageProxy* page, const WebHitTestResultData& data, WebKit::WebEvent::Modifiers modifiers, API::Object* userData) override + { + if (!m_client.mouseDidMoveOverElement && !m_client.mouseDidMoveOverElement_deprecatedForUseWithV0) + return; + + if (m_client.base.version > 0 && !m_client.mouseDidMoveOverElement) + return; + + if (!m_client.base.version) { + m_client.mouseDidMoveOverElement_deprecatedForUseWithV0(toAPI(page), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo); + return; + } + + RefPtr<API::HitTestResult> webHitTestResult = API::HitTestResult::create(data); + m_client.mouseDidMoveOverElement(toAPI(page), toAPI(webHitTestResult.get()), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + void unavailablePluginButtonClicked(WebPageProxy* page, WKPluginUnavailabilityReason pluginUnavailabilityReason, API::Dictionary* pluginInformation) override + { + if (pluginUnavailabilityReason == kWKPluginUnavailabilityReasonPluginMissing) { + if (m_client.missingPluginButtonClicked_deprecatedForUseWithV0) + m_client.missingPluginButtonClicked_deprecatedForUseWithV0( + toAPI(page), + toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), + toAPI(pluginInformation->get<API::String>(pluginInformationPluginURLKey())), + toAPI(pluginInformation->get<API::String>(pluginInformationPluginspageAttributeURLKey())), + m_client.base.clientInfo); + } + + if (m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1) + m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1( + toAPI(page), + pluginUnavailabilityReason, + toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), + toAPI(pluginInformation->get<API::String>(pluginInformationPluginURLKey())), + toAPI(pluginInformation->get<API::String>(pluginInformationPluginspageAttributeURLKey())), + m_client.base.clientInfo); + + if (m_client.unavailablePluginButtonClicked) + m_client.unavailablePluginButtonClicked( + toAPI(page), + pluginUnavailabilityReason, + toAPI(pluginInformation), + m_client.base.clientInfo); + } +#endif // ENABLE(NETSCAPE_PLUGIN_API) + + bool implementsDidNotHandleKeyEvent() const override + { + return m_client.didNotHandleKeyEvent; + } + + void didNotHandleKeyEvent(WebPageProxy* page, const NativeWebKeyboardEvent& event) override + { + if (!m_client.didNotHandleKeyEvent) + return; + m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo); + } + + bool implementsDidNotHandleWheelEvent() const override + { + return m_client.didNotHandleWheelEvent; + } + + void didNotHandleWheelEvent(WebPageProxy* page, const NativeWebWheelEvent& event) override + { + if (!m_client.didNotHandleWheelEvent) + return; + m_client.didNotHandleWheelEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo); + } + + bool toolbarsAreVisible(WebPageProxy* page) override + { + if (!m_client.toolbarsAreVisible) + return true; + return m_client.toolbarsAreVisible(toAPI(page), m_client.base.clientInfo); + } + + void setToolbarsAreVisible(WebPageProxy* page, bool visible) override + { + if (!m_client.setToolbarsAreVisible) + return; + m_client.setToolbarsAreVisible(toAPI(page), visible, m_client.base.clientInfo); + } + + bool menuBarIsVisible(WebPageProxy* page) override + { + if (!m_client.menuBarIsVisible) + return true; + return m_client.menuBarIsVisible(toAPI(page), m_client.base.clientInfo); + } + + void setMenuBarIsVisible(WebPageProxy* page, bool visible) override + { + if (!m_client.setMenuBarIsVisible) + return; + m_client.setMenuBarIsVisible(toAPI(page), visible, m_client.base.clientInfo); + } + + bool statusBarIsVisible(WebPageProxy* page) override + { + if (!m_client.statusBarIsVisible) + return true; + return m_client.statusBarIsVisible(toAPI(page), m_client.base.clientInfo); + } + + void setStatusBarIsVisible(WebPageProxy* page, bool visible) override + { + if (!m_client.setStatusBarIsVisible) + return; + m_client.setStatusBarIsVisible(toAPI(page), visible, m_client.base.clientInfo); + } + + bool isResizable(WebPageProxy* page) override + { + if (!m_client.isResizable) + return true; + return m_client.isResizable(toAPI(page), m_client.base.clientInfo); + } + + void setIsResizable(WebPageProxy* page, bool resizable) override + { + if (!m_client.setIsResizable) + return; + m_client.setIsResizable(toAPI(page), resizable, m_client.base.clientInfo); + } + + void setWindowFrame(WebPageProxy* page, const FloatRect& frame) override + { + if (!m_client.setWindowFrame) + return; + + m_client.setWindowFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo); + } + + FloatRect windowFrame(WebPageProxy* page) override + { + if (!m_client.getWindowFrame) + return FloatRect(); + + return toFloatRect(m_client.getWindowFrame(toAPI(page), m_client.base.clientInfo)); + } + + bool canRunBeforeUnloadConfirmPanel() const override + { + return m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6 || m_client.runBeforeUnloadConfirmPanel; + } + + void runBeforeUnloadConfirmPanel(WebKit::WebPageProxy* page, const WTF::String& message, WebKit::WebFrameProxy* frame, Function<void (bool)>&& completionHandler) override + { + if (m_client.runBeforeUnloadConfirmPanel) { + RefPtr<RunBeforeUnloadConfirmPanelResultListener> listener = RunBeforeUnloadConfirmPanelResultListener::create(WTFMove(completionHandler)); + m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), toAPI(listener.get()), m_client.base.clientInfo); + return; + } + + if (m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6) { + bool result = m_client.runBeforeUnloadConfirmPanel_deprecatedForUseWithV6(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); + completionHandler(result); + return; + } + + completionHandler(true); + } + + void pageDidScroll(WebPageProxy* page) override + { + if (!m_client.pageDidScroll) + return; + + m_client.pageDidScroll(toAPI(page), m_client.base.clientInfo); + } + + void exceededDatabaseQuota(WebPageProxy* page, WebFrameProxy* frame, API::SecurityOrigin* origin, const String& databaseName, const String& databaseDisplayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage, Function<void (unsigned long long)>&& completionHandler) override + { + if (!m_client.exceededDatabaseQuota) { + completionHandler(currentQuota); + return; + } + + completionHandler(m_client.exceededDatabaseQuota(toAPI(page), toAPI(frame), toAPI(origin), toAPI(databaseName.impl()), toAPI(databaseDisplayName.impl()), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, m_client.base.clientInfo)); + } + + bool runOpenPanel(WebPageProxy* page, WebFrameProxy* frame, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) override + { + if (!m_client.runOpenPanel) + return false; + + m_client.runOpenPanel(toAPI(page), toAPI(frame), toAPI(parameters), toAPI(listener), m_client.base.clientInfo); + return true; + } + + bool decidePolicyForGeolocationPermissionRequest(WebPageProxy* page, WebFrameProxy* frame, API::SecurityOrigin* origin, GeolocationPermissionRequestProxy* permissionRequest) override + { + if (!m_client.decidePolicyForGeolocationPermissionRequest) + return false; + + m_client.decidePolicyForGeolocationPermissionRequest(toAPI(page), toAPI(frame), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo); + return true; + } + + bool decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) override + { + if (!m_client.decidePolicyForUserMediaPermissionRequest) + return false; + + m_client.decidePolicyForUserMediaPermissionRequest(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&permissionRequest), m_client.base.clientInfo); + return true; + } + + bool checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionCheckProxy& request) override + { + if (!m_client.checkUserMediaPermissionForOrigin) + return false; + + m_client.checkUserMediaPermissionForOrigin(toAPI(&page), toAPI(&frame), toAPI(&userMediaDocumentOrigin), toAPI(&topLevelDocumentOrigin), toAPI(&request), m_client.base.clientInfo); + return true; + } + + bool decidePolicyForNotificationPermissionRequest(WebPageProxy* page, API::SecurityOrigin* origin, NotificationPermissionRequest* permissionRequest) override + { + if (!m_client.decidePolicyForNotificationPermissionRequest) + return false; + + m_client.decidePolicyForNotificationPermissionRequest(toAPI(page), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo); + return true; + } + + // Printing. + float headerHeight(WebPageProxy* page, WebFrameProxy* frame) override + { + if (!m_client.headerHeight) + return 0; + + return m_client.headerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo); + } + + float footerHeight(WebPageProxy* page, WebFrameProxy* frame) override + { + if (!m_client.footerHeight) + return 0; + + return m_client.footerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo); + } + + void drawHeader(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) override + { + if (!m_client.drawHeader) + return; + + m_client.drawHeader(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo); + } + + void drawFooter(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) override + { + if (!m_client.drawFooter) + return; + + m_client.drawFooter(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo); + } + + void printFrame(WebPageProxy* page, WebFrameProxy* frame) override + { + if (!m_client.printFrame) + return; + + m_client.printFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo); + } + + bool canRunModal() const override + { + return m_client.runModal; + } + + void runModal(WebPageProxy* page) override + { + if (!m_client.runModal) + return; + + m_client.runModal(toAPI(page), m_client.base.clientInfo); + } + + void saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data* data) override + { + if (!m_client.saveDataToFileInDownloadsFolder) + return; + + m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURLString.impl()), toAPI(data), m_client.base.clientInfo); + } + + void pinnedStateDidChange(WebPageProxy& page) override + { + if (!m_client.pinnedStateDidChange) + return; + + m_client.pinnedStateDidChange(toAPI(&page), m_client.base.clientInfo); + } + + void isPlayingAudioDidChange(WebPageProxy& page) override + { + if (!m_client.isPlayingAudioDidChange) + return; + + m_client.isPlayingAudioDidChange(toAPI(&page), m_client.base.clientInfo); + } + + void didClickAutoFillButton(WebPageProxy& page, API::Object* userInfo) override + { + if (!m_client.didClickAutoFillButton) + return; + + m_client.didClickAutoFillButton(toAPI(&page), toAPI(userInfo), m_client.base.clientInfo); + } + +#if ENABLE(MEDIA_SESSION) + void mediaSessionMetadataDidChange(WebPageProxy& page, WebMediaSessionMetadata* metadata) override + { + if (!m_client.mediaSessionMetadataDidChange) + return; + + m_client.mediaSessionMetadataDidChange(toAPI(&page), toAPI(metadata), m_client.base.clientInfo); + } +#endif +#if ENABLE(POINTER_LOCK) + void requestPointerLock(WebPageProxy* page) override + { + if (!m_client.requestPointerLock) + return; + + m_client.requestPointerLock(toAPI(page), m_client.base.clientInfo); + } + + void didLosePointerLock(WebPageProxy* page) override + { + if (!m_client.didLosePointerLock) + return; + + m_client.didLosePointerLock(toAPI(page), m_client.base.clientInfo); + } +#endif + + void didPlayMediaPreventedFromPlayingWithoutUserGesture(WebPageProxy& page) override + { + if (!m_client.didPlayMediaPreventedFromPlayingWithoutUserGesture) + return; + + m_client.didPlayMediaPreventedFromPlayingWithoutUserGesture(toAPI(&page), m_client.base.clientInfo); + } + }; + + toImpl(pageRef)->setUIClient(std::make_unique<UIClient>(wkClient)); } -void WKPageSetSession(WKPageRef pageRef, WKSessionRef session) +void WKPageSetPageNavigationClient(WKPageRef pageRef, const WKPageNavigationClientBase* wkClient) { - toImpl(pageRef)->setSession(*toImpl(session)); + class NavigationClient : public API::Client<WKPageNavigationClientBase>, public API::NavigationClient { + public: + explicit NavigationClient(const WKPageNavigationClientBase* client) + { + initialize(client); + } + + private: + void decidePolicyForNavigationAction(WebPageProxy& page, API::NavigationAction& navigationAction, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override + { + if (!m_client.decidePolicyForNavigationAction) + return; + m_client.decidePolicyForNavigationAction(toAPI(&page), toAPI(&navigationAction), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); + } + + void decidePolicyForNavigationResponse(WebPageProxy& page, API::NavigationResponse& navigationResponse, Ref<WebKit::WebFramePolicyListenerProxy>&& listener, API::Object* userData) override + { + if (!m_client.decidePolicyForNavigationResponse) + return; + m_client.decidePolicyForNavigationResponse(toAPI(&page), toAPI(&navigationResponse), toAPI(listener.ptr()), toAPI(userData), m_client.base.clientInfo); + } + + void didStartProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override + { + if (!m_client.didStartProvisionalNavigation) + return; + m_client.didStartProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo); + } + + void didReceiveServerRedirectForProvisionalNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override + { + if (!m_client.didReceiveServerRedirectForProvisionalNavigation) + return; + m_client.didReceiveServerRedirectForProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo); + } + + void didFailProvisionalNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override + { + if (!m_client.didFailProvisionalNavigation) + return; + m_client.didFailProvisionalNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo); + } + + void didCommitNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override + { + if (!m_client.didCommitNavigation) + return; + m_client.didCommitNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo); + } + + void didFinishNavigation(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override + { + if (!m_client.didFinishNavigation) + return; + m_client.didFinishNavigation(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo); + } + + void didFailNavigationWithError(WebPageProxy& page, WebFrameProxy&, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override + { + if (!m_client.didFailNavigation) + return; + m_client.didFailNavigation(toAPI(&page), toAPI(navigation), toAPI(error), toAPI(userData), m_client.base.clientInfo); + } + + void didFailProvisionalLoadInSubframeWithError(WebPageProxy& page, WebFrameProxy& subframe, const WebCore::SecurityOriginData& securityOriginData, API::Navigation* navigation, const WebCore::ResourceError& error, API::Object* userData) override + { + if (!m_client.didFailProvisionalLoadInSubframe) + return; + m_client.didFailProvisionalLoadInSubframe(toAPI(&page), toAPI(navigation), toAPI(API::FrameInfo::create(subframe, securityOriginData.securityOrigin()).ptr()), toAPI(error), toAPI(userData), m_client.base.clientInfo); + } + + void didFinishDocumentLoad(WebPageProxy& page, API::Navigation* navigation, API::Object* userData) override + { + if (!m_client.didFinishDocumentLoad) + return; + m_client.didFinishDocumentLoad(toAPI(&page), toAPI(navigation), toAPI(userData), m_client.base.clientInfo); + } + + void didSameDocumentNavigation(WebPageProxy& page, API::Navigation* navigation, WebKit::SameDocumentNavigationType navigationType, API::Object* userData) override + { + if (!m_client.didSameDocumentNavigation) + return; + m_client.didSameDocumentNavigation(toAPI(&page), toAPI(navigation), toAPI(navigationType), toAPI(userData), m_client.base.clientInfo); + } + + void renderingProgressDidChange(WebPageProxy& page, WebCore::LayoutMilestones milestones) override + { + if (!m_client.renderingProgressDidChange) + return; + m_client.renderingProgressDidChange(toAPI(&page), pageRenderingProgressEvents(milestones), nullptr, m_client.base.clientInfo); + } + + bool canAuthenticateAgainstProtectionSpace(WebPageProxy& page, WebProtectionSpace* protectionSpace) override + { + if (!m_client.canAuthenticateAgainstProtectionSpace) + return false; + return m_client.canAuthenticateAgainstProtectionSpace(toAPI(&page), toAPI(protectionSpace), m_client.base.clientInfo); + } + + void didReceiveAuthenticationChallenge(WebPageProxy& page, AuthenticationChallengeProxy* authenticationChallenge) override + { + if (!m_client.didReceiveAuthenticationChallenge) + return; + m_client.didReceiveAuthenticationChallenge(toAPI(&page), toAPI(authenticationChallenge), m_client.base.clientInfo); + } + + void processDidCrash(WebPageProxy& page) override + { + if (!m_client.webProcessDidCrash) + return; + m_client.webProcessDidCrash(toAPI(&page), m_client.base.clientInfo); + } + + RefPtr<API::Data> webCryptoMasterKey(WebPageProxy& page) override + { + if (m_client.copyWebCryptoMasterKey) + return adoptRef(toImpl(m_client.copyWebCryptoMasterKey(toAPI(&page), m_client.base.clientInfo))); + + Vector<uint8_t> masterKey; +#if ENABLE(SUBTLE_CRYPTO) + if (!getDefaultWebCryptoMasterKey(masterKey)) + return nullptr; +#endif + + return API::Data::create(masterKey.data(), masterKey.size()); + } + + void didBeginNavigationGesture(WebPageProxy& page) override + { + if (!m_client.didBeginNavigationGesture) + return; + m_client.didBeginNavigationGesture(toAPI(&page), m_client.base.clientInfo); + } + + void didEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override + { + if (!m_client.didEndNavigationGesture) + return; + m_client.didEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo); + } + + void willEndNavigationGesture(WebPageProxy& page, bool willNavigate, WebKit::WebBackForwardListItem& item) override + { + if (!m_client.willEndNavigationGesture) + return; + m_client.willEndNavigationGesture(toAPI(&page), willNavigate ? toAPI(&item) : nullptr, m_client.base.clientInfo); + } + + void didRemoveNavigationGestureSnapshot(WebPageProxy& page) override + { + if (!m_client.didRemoveNavigationGestureSnapshot) + return; + m_client.didRemoveNavigationGestureSnapshot(toAPI(&page), m_client.base.clientInfo); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + PluginModuleLoadPolicy decidePolicyForPluginLoad(WebPageProxy& page, PluginModuleLoadPolicy currentPluginLoadPolicy, API::Dictionary* pluginInformation, String& unavailabilityDescription) override + { + WKStringRef unavailabilityDescriptionOut = 0; + PluginModuleLoadPolicy loadPolicy = currentPluginLoadPolicy; + + if (m_client.decidePolicyForPluginLoad) + loadPolicy = toPluginModuleLoadPolicy(m_client.decidePolicyForPluginLoad(toAPI(&page), toWKPluginLoadPolicy(currentPluginLoadPolicy), toAPI(pluginInformation), &unavailabilityDescriptionOut, m_client.base.clientInfo)); + + if (unavailabilityDescriptionOut) { + RefPtr<API::String> webUnavailabilityDescription = adoptRef(toImpl(unavailabilityDescriptionOut)); + unavailabilityDescription = webUnavailabilityDescription->string(); + } + + return loadPolicy; + } +#endif + }; + + WebPageProxy* webPageProxy = toImpl(pageRef); + + auto navigationClient = std::make_unique<NavigationClient>(wkClient); + webPageProxy->setNavigationClient(WTFMove(navigationClient)); } void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, void* context, WKPageRunJavaScriptFunction callback) { - toImpl(pageRef)->runJavaScriptInMainFrame(toImpl(scriptRef)->string(), ScriptValueCallback::create(context, callback)); + toImpl(pageRef)->runJavaScriptInMainFrame(toImpl(scriptRef)->string(), [context, callback](API::SerializedScriptValue* returnValue, bool, const WebCore::ExceptionDetails&, CallbackBase::Error error) { + callback(toAPI(returnValue), (error != CallbackBase::Error::None) ? toAPI(API::Error::create().ptr()) : 0, context); + }); } #ifdef __BLOCKS__ @@ -1080,33 +2457,56 @@ void WKPageRunJavaScriptInMainFrame_b(WKPageRef pageRef, WKStringRef scriptRef, } #endif +static std::function<void (const String&, WebKit::CallbackBase::Error)> toGenericCallbackFunction(void* context, void (*callback)(WKStringRef, WKErrorRef, void*)) +{ + return [context, callback](const String& returnValue, WebKit::CallbackBase::Error error) { + callback(toAPI(API::String::create(returnValue).ptr()), error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + }; +} + void WKPageRenderTreeExternalRepresentation(WKPageRef pageRef, void* context, WKPageRenderTreeExternalRepresentationFunction callback) { - toImpl(pageRef)->getRenderTreeExternalRepresentation(StringCallback::create(context, callback)); + toImpl(pageRef)->getRenderTreeExternalRepresentation(toGenericCallbackFunction(context, callback)); } void WKPageGetSourceForFrame(WKPageRef pageRef, WKFrameRef frameRef, void* context, WKPageGetSourceForFrameFunction callback) { - toImpl(pageRef)->getSourceForFrame(toImpl(frameRef), StringCallback::create(context, callback)); + toImpl(pageRef)->getSourceForFrame(toImpl(frameRef), toGenericCallbackFunction(context, callback)); } void WKPageGetContentsAsString(WKPageRef pageRef, void* context, WKPageGetContentsAsStringFunction callback) { - toImpl(pageRef)->getContentsAsString(StringCallback::create(context, callback)); + toImpl(pageRef)->getContentsAsString(toGenericCallbackFunction(context, callback)); +} + +void WKPageGetBytecodeProfile(WKPageRef pageRef, void* context, WKPageGetBytecodeProfileFunction callback) +{ + toImpl(pageRef)->getBytecodeProfile(toGenericCallbackFunction(context, callback)); +} + +void WKPageGetSamplingProfilerOutput(WKPageRef pageRef, void* context, WKPageGetSamplingProfilerOutputFunction callback) +{ + toImpl(pageRef)->getSamplingProfilerOutput(toGenericCallbackFunction(context, callback)); +} + +void WKPageIsWebProcessResponsive(WKPageRef pageRef, void* context, WKPageIsWebProcessResponsiveFunction callback) +{ + toImpl(pageRef)->isWebProcessResponsive([context, callback](bool isWebProcessResponsive) { + callback(isWebProcessResponsive, context); + }); } void WKPageGetSelectionAsWebArchiveData(WKPageRef pageRef, void* context, WKPageGetSelectionAsWebArchiveDataFunction callback) { - toImpl(pageRef)->getSelectionAsWebArchiveData(DataCallback::create(context, callback)); + toImpl(pageRef)->getSelectionAsWebArchiveData(toGenericCallbackFunction(context, callback)); } -void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, bool useBinaryEncoding, void* context, WKPageGetContentsAsMHTMLDataFunction callback) +void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, void* context, WKPageGetContentsAsMHTMLDataFunction callback) { #if ENABLE(MHTML) - toImpl(pageRef)->getContentsAsMHTMLData(DataCallback::create(context, callback), useBinaryEncoding); + toImpl(pageRef)->getContentsAsMHTMLData(toGenericCallbackFunction(context, callback)); #else UNUSED_PARAM(pageRef); - UNUSED_PARAM(useBinaryEncoding); UNUSED_PARAM(context); UNUSED_PARAM(callback); #endif @@ -1114,7 +2514,9 @@ void WKPageGetContentsAsMHTMLData(WKPageRef pageRef, bool useBinaryEncoding, voi void WKPageForceRepaint(WKPageRef pageRef, void* context, WKPageForceRepaintFunction callback) { - toImpl(pageRef)->forceRepaint(VoidCallback::create(context, callback)); + toImpl(pageRef)->forceRepaint(VoidCallback::create([context, callback](WebKit::CallbackBase::Error error) { + callback(error == WebKit::CallbackBase::Error::None ? nullptr : toAPI(API::Error::create().ptr()), context); + })); } WK_EXPORT WKURLRef WKPageCopyPendingAPIRequestURL(WKPageRef pageRef) @@ -1149,7 +2551,9 @@ WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef applicati void WKPageValidateCommand(WKPageRef pageRef, WKStringRef command, void* context, WKPageValidateCommandCallback callback) { - toImpl(pageRef)->validateCommand(toImpl(command)->string(), ValidateCommandCallback::create(context, callback)); + toImpl(pageRef)->validateCommand(toImpl(command)->string(), [context, callback](const String& commandName, bool isEnabled, int32_t state, WebKit::CallbackBase::Error error) { + callback(toAPI(API::String::create(commandName).ptr()), isEnabled, state, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + }); } void WKPageExecuteCommand(WKPageRef pageRef, WKStringRef command) @@ -1157,26 +2561,7 @@ void WKPageExecuteCommand(WKPageRef pageRef, WKStringRef command) toImpl(pageRef)->executeEditCommand(toImpl(command)->string()); } -#if PLATFORM(MAC) -struct ComputedPagesContext { - ComputedPagesContext(WKPageComputePagesForPrintingFunction callback, void* context) - : callback(callback) - , context(context) - { - } - WKPageComputePagesForPrintingFunction callback; - void* context; -}; - -static void computedPagesCallback(const Vector<WebCore::IntRect>& rects, double scaleFactor, WKErrorRef error, void* untypedContext) -{ - OwnPtr<ComputedPagesContext> context = adoptPtr(static_cast<ComputedPagesContext*>(untypedContext)); - Vector<WKRect> wkRects(rects.size()); - for (size_t i = 0; i < rects.size(); ++i) - wkRects[i] = toAPI(rects[i]); - context->callback(wkRects.data(), wkRects.size(), scaleFactor, error, context->context); -} - +#if PLATFORM(COCOA) static PrintInfo printInfoFromWKPrintInfo(const WKPrintInfo& printInfo) { PrintInfo result; @@ -1188,7 +2573,12 @@ static PrintInfo printInfoFromWKPrintInfo(const WKPrintInfo& printInfo) void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, WKPageComputePagesForPrintingFunction callback, void* context) { - toImpl(page)->computePagesForPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo), ComputedPagesCallback::create(new ComputedPagesContext(callback, context), computedPagesCallback)); + toImpl(page)->computePagesForPrinting(toImpl(frame), printInfoFromWKPrintInfo(printInfo), ComputedPagesCallback::create([context, callback](const Vector<WebCore::IntRect>& rects, double scaleFactor, WebKit::CallbackBase::Error error) { + Vector<WKRect> wkRects(rects.size()); + for (size_t i = 0; i < rects.size(); ++i) + wkRects[i] = toAPI(rects[i]); + callback(wkRects.data(), wkRects.size(), scaleFactor, error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + })); } void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo) @@ -1198,7 +2588,7 @@ void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context) { - toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(context, callback)); + toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(toGenericCallbackFunction(context, callback))); } void WKPageEndPrinting(WKPageRef page) @@ -1207,14 +2597,34 @@ void WKPageEndPrinting(WKPageRef page) } #endif -WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef) +bool WKPageGetIsControlledByAutomation(WKPageRef page) { - return 0; + return toImpl(page)->isControlledByAutomation(); +} + +void WKPageSetControlledByAutomation(WKPageRef page, bool controlled) +{ + toImpl(page)->setControlledByAutomation(controlled); } -void WKPageSetShouldSendEventsSynchronously(WKPageRef page, bool sync) +bool WKPageGetAllowsRemoteInspection(WKPageRef page) { - toImpl(page)->setShouldSendEventsSynchronously(sync); +#if ENABLE(REMOTE_INSPECTOR) + return toImpl(page)->allowsRemoteInspection(); +#else + UNUSED_PARAM(page); + return false; +#endif +} + +void WKPageSetAllowsRemoteInspection(WKPageRef page, bool allow) +{ +#if ENABLE(REMOTE_INSPECTOR) + toImpl(page)->setAllowsRemoteInspection(allow); +#else + UNUSED_PARAM(page); + UNUSED_PARAM(allow); +#endif } void WKPageSetMediaVolume(WKPageRef page, float volume) @@ -1222,6 +2632,75 @@ void WKPageSetMediaVolume(WKPageRef page, float volume) toImpl(page)->setMediaVolume(volume); } +void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted) +{ + toImpl(page)->setMuted(muted); +} + +void WKPageDidAllowPointerLock(WKPageRef page) +{ +#if ENABLE(POINTER_LOCK) + toImpl(page)->didAllowPointerLock(); +#else + UNUSED_PARAM(page); +#endif +} + +void WKPageClearUserMediaState(WKPageRef page) +{ +#if ENABLE(MEDIA_STREAM) + toImpl(page)->clearUserMediaState(); +#else + UNUSED_PARAM(page); +#endif +} + +void WKPageDidDenyPointerLock(WKPageRef page) +{ +#if ENABLE(POINTER_LOCK) + toImpl(page)->didDenyPointerLock(); +#else + UNUSED_PARAM(page); +#endif +} + +bool WKPageHasMediaSessionWithActiveMediaElements(WKPageRef page) +{ +#if ENABLE(MEDIA_SESSION) + return toImpl(page)->hasMediaSessionWithActiveMediaElements(); +#else + UNUSED_PARAM(page); + return false; +#endif +} + +void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType wkEventType) +{ +#if ENABLE(MEDIA_SESSION) + MediaEventType eventType; + + switch (wkEventType) { + case kWKMediaEventTypePlayPause: + eventType = MediaEventType::PlayPause; + break; + case kWKMediaEventTypeTrackNext: + eventType = MediaEventType::TrackNext; + break; + case kWKMediaEventTypeTrackPrevious: + eventType = MediaEventType::TrackPrevious; + break; + default: + ASSERT_NOT_REACHED(); + return; + } + + toImpl(page)->handleMediaEvent(eventType); +#else + UNUSED_PARAM(page); + UNUSED_PARAM(wkEventType); +#endif +} + void WKPagePostMessageToInjectedBundle(WKPageRef pageRef, WKStringRef messageNameRef, WKTypeRef messageBodyRef) { toImpl(pageRef)->postMessageToInjectedBundle(toImpl(messageNameRef)->string(), toImpl(messageBodyRef)); @@ -1229,7 +2708,24 @@ void WKPagePostMessageToInjectedBundle(WKPageRef pageRef, WKStringRef messageNam WKArrayRef WKPageCopyRelatedPages(WKPageRef pageRef) { - return toAPI(toImpl(pageRef)->relatedPages().leakRef()); + Vector<RefPtr<API::Object>> relatedPages; + + for (auto& page : toImpl(pageRef)->process().pages()) { + if (page != toImpl(pageRef)) + relatedPages.append(page); + } + + return toAPI(&API::Array::create(WTFMove(relatedPages)).leakRef()); +} + +WKFrameRef WKPageLookUpFrameFromHandle(WKPageRef pageRef, WKFrameHandleRef handleRef) +{ + auto page = toImpl(pageRef); + auto frame = page->process().webFrame(toImpl(handleRef)->frameID()); + if (!frame || frame->page() != page) + return nullptr; + + return toAPI(frame); } void WKPageSetMayStartMediaWhenInWindow(WKPageRef pageRef, bool mayStartMedia) @@ -1241,7 +2737,7 @@ void WKPageSetMayStartMediaWhenInWindow(WKPageRef pageRef, bool mayStartMedia) void WKPageSelectContextMenuItem(WKPageRef page, WKContextMenuItemRef item) { #if ENABLE(CONTEXT_MENUS) - toImpl(page)->contextMenuItemSelected(*(toImpl(item)->data())); + toImpl(page)->contextMenuItemSelected((toImpl(item)->data())); #else UNUSED_PARAM(page); UNUSED_PARAM(item); @@ -1286,9 +2782,70 @@ void WKPageSetScrollPinningBehavior(WKPageRef page, WKScrollPinningBehavior pinn toImpl(page)->setScrollPinningBehavior(corePinning); } -void WKPageSetInvalidMessageFunction(WKPageInvalidMessageFunction) +bool WKPageGetAddsVisitedLinks(WKPageRef page) +{ + return toImpl(page)->addsVisitedLinks(); +} + +void WKPageSetAddsVisitedLinks(WKPageRef page, bool addsVisitedLinks) +{ + toImpl(page)->setAddsVisitedLinks(addsVisitedLinks); +} + +bool WKPageIsPlayingAudio(WKPageRef page) +{ + return toImpl(page)->isPlayingAudio(); +} + +WKMediaState WKPageGetMediaState(WKPageRef page) +{ + WebCore::MediaProducer::MediaStateFlags coreState = toImpl(page)->mediaStateFlags(); + WKMediaState state = kWKMediaIsNotPlaying; + + if (coreState & WebCore::MediaProducer::IsPlayingAudio) + state |= kWKMediaIsPlayingAudio; + if (coreState & WebCore::MediaProducer::IsPlayingVideo) + state |= kWKMediaIsPlayingVideo; + if (coreState & WebCore::MediaProducer::HasActiveAudioCaptureDevice) + state |= kWKMediaHasActiveAudioCaptureDevice; + if (coreState & WebCore::MediaProducer::HasActiveVideoCaptureDevice) + state |= kWKMediaHasActiveVideoCaptureDevice; + + return state; +} + +void WKPageClearWheelEventTestTrigger(WKPageRef pageRef) +{ + toImpl(pageRef)->clearWheelEventTestTrigger(); +} + +void WKPageCallAfterNextPresentationUpdate(WKPageRef pageRef, void* context, WKPagePostPresentationUpdateFunction callback) +{ + toImpl(pageRef)->callAfterNextPresentationUpdate([context, callback](WebKit::CallbackBase::Error error) { + callback(error != WebKit::CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + }); +} + +bool WKPageGetResourceCachingDisabled(WKPageRef page) +{ + return toImpl(page)->isResourceCachingDisabled(); +} + +void WKPageSetResourceCachingDisabled(WKPageRef page, bool disabled) +{ + toImpl(page)->setResourceCachingDisabled(disabled); +} + +void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresViewportScaleLimits) +{ +#if PLATFORM(IOS) + toImpl(page)->setForceAlwaysUserScalable(ignoresViewportScaleLimits); +#endif +} + +pid_t WKPageGetProcessIdentifier(WKPageRef page) { - // FIXME: Remove this function when doing so won't break WebKit nightlies. + return toImpl(page)->processIdentifier(); } #if ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h index 216a8ff45..56de50357 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.h +++ b/Source/WebKit2/UIProcess/API/C/WKPage.h @@ -26,22 +26,24 @@ #ifndef WKPage_h #define WKPage_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKError.h> -#include <WebKit2/WKEvent.h> -#include <WebKit2/WKFindOptions.h> -#include <WebKit2/WKGeometry.h> -#include <WebKit2/WKNativeEvent.h> -#include <WebKit2/WKPageContextMenuClient.h> -#include <WebKit2/WKPageFindClient.h> -#include <WebKit2/WKPageFindMatchesClient.h> -#include <WebKit2/WKPageFormClient.h> -#include <WebKit2/WKPageLoadTypes.h> -#include <WebKit2/WKPageLoaderClient.h> -#include <WebKit2/WKPagePolicyClient.h> -#include <WebKit2/WKPageUIClient.h> -#include <WebKit2/WKPageVisibilityTypes.h> -#include <WebKit2/WKSessionRef.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKErrorRef.h> +#include <WebKit/WKEvent.h> +#include <WebKit/WKFindOptions.h> +#include <WebKit/WKGeometry.h> +#include <WebKit/WKNativeEvent.h> +#include <WebKit/WKPageContextMenuClient.h> +#include <WebKit/WKPageDiagnosticLoggingClient.h> +#include <WebKit/WKPageFindClient.h> +#include <WebKit/WKPageFindMatchesClient.h> +#include <WebKit/WKPageFormClient.h> +#include <WebKit/WKPageInjectedBundleClient.h> +#include <WebKit/WKPageLoadTypes.h> +#include <WebKit/WKPageLoaderClient.h> +#include <WebKit/WKPageNavigationClient.h> +#include <WebKit/WKPagePolicyClient.h> +#include <WebKit/WKPageUIClient.h> +#include <WebKit/WKPageVisibilityTypes.h> #ifndef __cplusplus #include <stdbool.h> @@ -56,6 +58,8 @@ WK_EXPORT WKTypeID WKPageGetTypeID(); WK_EXPORT WKContextRef WKPageGetContext(WKPageRef page); WK_EXPORT WKPageGroupRef WKPageGetPageGroup(WKPageRef page); +WK_EXPORT WKPageConfigurationRef WKPageCopyPageConfiguration(WKPageRef page); + // URL Requests WK_EXPORT void WKPageLoadURL(WKPageRef page, WKURLRef url); WK_EXPORT void WKPageLoadURLWithUserData(WKPageRef page, WKURLRef url, WKTypeRef userData); @@ -78,6 +82,7 @@ WK_EXPORT void WKPageLoadWebArchiveDataWithUserData(WKPageRef page, WKDataRef we WK_EXPORT void WKPageStopLoading(WKPageRef page); WK_EXPORT void WKPageReload(WKPageRef page); +WK_EXPORT void WKPageReloadWithoutContentBlockers(WKPageRef page); WK_EXPORT void WKPageReloadFromOrigin(WKPageRef page); WK_EXPORT bool WKPageTryClose(WKPageRef page); @@ -92,7 +97,9 @@ WK_EXPORT void WKPageGoToBackForwardListItem(WKPageRef page, WKBackForwardListIt WK_EXPORT void WKPageTryRestoreScrollPosition(WKPageRef page); WK_EXPORT WKBackForwardListRef WKPageGetBackForwardList(WKPageRef page); WK_EXPORT bool WKPageWillHandleHorizontalScrollEvents(WKPageRef page); - + +WK_EXPORT void WKPageUpdateWebsitePolicies(WKPageRef, WKWebsitePoliciesRef); + WK_EXPORT WKStringRef WKPageCopyTitle(WKPageRef page); WK_EXPORT WKURLRef WKPageCopyPendingAPIRequestURL(WKPageRef page); @@ -108,8 +115,6 @@ WK_EXPORT double WKPageGetEstimatedProgress(WKPageRef page); WK_EXPORT uint64_t WKPageGetRenderTreeSize(WKPageRef page); -WK_EXPORT void WKPageSetMemoryCacheClientCallsEnabled(WKPageRef page, bool memoryCacheClientCallsEnabled); - WK_EXPORT WKInspectorRef WKPageGetInspector(WKPageRef page); WK_EXPORT WKVibrationRef WKPageGetVibration(WKPageRef page); @@ -122,6 +127,8 @@ WK_EXPORT void WKPageSetApplicationNameForUserAgent(WKPageRef page, WKStringRef WK_EXPORT WKStringRef WKPageCopyCustomUserAgent(WKPageRef page); WK_EXPORT void WKPageSetCustomUserAgent(WKPageRef page, WKStringRef userAgent); +WK_EXPORT void WKPageSetUserContentExtensionsEnabled(WKPageRef, bool); + WK_EXPORT bool WKPageSupportsTextEncoding(WKPageRef page); WK_EXPORT WKStringRef WKPageCopyCustomTextEncodingName(WKPageRef page); WK_EXPORT void WKPageSetCustomTextEncodingName(WKPageRef page, WKStringRef encodingName); @@ -132,11 +139,18 @@ WK_EXPORT WKStringRef WKPageGetSessionHistoryURLValueType(void); WK_EXPORT WKStringRef WKPageGetSessionBackForwardListItemValueType(void); typedef bool (*WKPageSessionStateFilterCallback)(WKPageRef page, WKStringRef valueType, WKTypeRef value, void* context); -WK_EXPORT WKDataRef WKPageCopySessionState(WKPageRef page, void* context, WKPageSessionStateFilterCallback urlAllowedCallback); -WK_EXPORT void WKPageRestoreFromSessionState(WKPageRef page, WKDataRef sessionStateData); + +// FIXME: This should return a WKSessionStateRef object, not a WKTypeRef. +// It currently returns a WKTypeRef for backwards compatibility with Safari. +WK_EXPORT WKTypeRef WKPageCopySessionState(WKPageRef page, void* context, WKPageSessionStateFilterCallback urlAllowedCallback); + +// FIXME: This should take a WKSessionStateRef object, not a WKTypeRef. +// It currently takes a WKTypeRef for backwards compatibility with Safari. +WK_EXPORT void WKPageRestoreFromSessionState(WKPageRef page, WKTypeRef sessionState); WK_EXPORT double WKPageGetBackingScaleFactor(WKPageRef page); WK_EXPORT void WKPageSetCustomBackingScaleFactor(WKPageRef page, double customScaleFactor); +WK_EXPORT void WKPageClearWheelEventTestTrigger(WKPageRef page); WK_EXPORT bool WKPageSupportsTextZoom(WKPageRef page); WK_EXPORT double WKPageGetTextZoomFactor(WKPageRef page); @@ -155,8 +169,6 @@ WK_EXPORT WKSize WKPageFixedLayoutSize(WKPageRef page); WK_EXPORT void WKPageListenForLayoutMilestones(WKPageRef page, WKLayoutMilestones milestones); -WK_EXPORT void WKPageSetVisibilityState(WKPageRef page, WKPageVisibilityState state, bool isInitialState); - WK_EXPORT bool WKPageHasHorizontalScrollbar(WKPageRef page); WK_EXPORT bool WKPageHasVerticalScrollbar(WKPageRef page); @@ -167,7 +179,11 @@ WK_EXPORT bool WKPageIsPinnedToLeftSide(WKPageRef page); WK_EXPORT bool WKPageIsPinnedToRightSide(WKPageRef page); WK_EXPORT bool WKPageIsPinnedToTopSide(WKPageRef page); WK_EXPORT bool WKPageIsPinnedToBottomSide(WKPageRef page); - + +// This API is poorly named. Even when these values are set to false, rubber-banding will +// still be allowed to occur at the end of a momentum scroll. These values are used along +// with pin state to determine if wheel events should be handled in the web process or if +// they should be passed up to the client. WK_EXPORT bool WKPageRubberBandsAtLeft(WKPageRef); WK_EXPORT void WKPageSetRubberBandsAtLeft(WKPageRef, bool rubberBandsAtLeft); WK_EXPORT bool WKPageRubberBandsAtRight(WKPageRef); @@ -176,7 +192,13 @@ WK_EXPORT bool WKPageRubberBandsAtTop(WKPageRef); WK_EXPORT void WKPageSetRubberBandsAtTop(WKPageRef, bool rubberBandsAtTop); WK_EXPORT bool WKPageRubberBandsAtBottom(WKPageRef); WK_EXPORT void WKPageSetRubberBandsAtBottom(WKPageRef, bool rubberBandsAtBottom); - + +// Rubber-banding is enabled by default. +WK_EXPORT bool WKPageVerticalRubberBandingIsEnabled(WKPageRef); +WK_EXPORT void WKPageSetEnableVerticalRubberBanding(WKPageRef, bool enableVerticalRubberBanding); +WK_EXPORT bool WKPageHorizontalRubberBandingIsEnabled(WKPageRef); +WK_EXPORT void WKPageSetEnableHorizontalRubberBanding(WKPageRef, bool enableHorizontalRubberBanding); + WK_EXPORT void WKPageSetBackgroundExtendsBeyondPage(WKPageRef, bool backgroundExtendsBeyondPage); WK_EXPORT bool WKPageBackgroundExtendsBeyondPage(WKPageRef); @@ -195,14 +217,17 @@ WK_EXPORT void WKPageGetImageForFindMatch(WKPageRef page, int32_t matchIndex); WK_EXPORT void WKPageSelectFindMatch(WKPageRef page, int32_t matchIndex); WK_EXPORT void WKPageSetPageContextMenuClient(WKPageRef page, const WKPageContextMenuClientBase* client); +WK_EXPORT void WKPageSetPageDiagnosticLoggingClient(WKPageRef page, const WKPageDiagnosticLoggingClientBase* client); WK_EXPORT void WKPageSetPageFindClient(WKPageRef page, const WKPageFindClientBase* client); WK_EXPORT void WKPageSetPageFindMatchesClient(WKPageRef page, const WKPageFindMatchesClientBase* client); WK_EXPORT void WKPageSetPageFormClient(WKPageRef page, const WKPageFormClientBase* client); -WK_EXPORT void WKPageSetPageLoaderClient(WKPageRef page, const WKPageLoaderClientBase* client); -WK_EXPORT void WKPageSetPagePolicyClient(WKPageRef page, const WKPagePolicyClientBase* client); WK_EXPORT void WKPageSetPageUIClient(WKPageRef page, const WKPageUIClientBase* client); +WK_EXPORT void WKPageSetPageInjectedBundleClient(WKPageRef page, const WKPageInjectedBundleClientBase* client); -WK_EXPORT void WKPageSetSession(WKPageRef page, WKSessionRef session); +// A client can implement either a navigation client or loader and policy clients, but never both. +WK_EXPORT void WKPageSetPageLoaderClient(WKPageRef page, const WKPageLoaderClientBase* client); +WK_EXPORT void WKPageSetPagePolicyClient(WKPageRef page, const WKPagePolicyClientBase* client); +WK_EXPORT void WKPageSetPageNavigationClient(WKPageRef page, const WKPageNavigationClientBase* client); typedef void (*WKPageRunJavaScriptFunction)(WKSerializedScriptValueRef, WKErrorRef, void*); WK_EXPORT void WKPageRunJavaScriptInMainFrame(WKPageRef page, WKStringRef script, void* context, WKPageRunJavaScriptFunction function); @@ -218,7 +243,7 @@ typedef void (*WKPageGetContentsAsStringFunction)(WKStringRef, WKErrorRef, void* WK_EXPORT void WKPageGetContentsAsString(WKPageRef page, void* context, WKPageGetContentsAsStringFunction function); typedef void (*WKPageGetContentsAsMHTMLDataFunction)(WKDataRef, WKErrorRef, void*); -WK_EXPORT void WKPageGetContentsAsMHTMLData(WKPageRef page, bool useBinaryEncoding, void* context, WKPageGetContentsAsMHTMLDataFunction function); +WK_EXPORT void WKPageGetContentsAsMHTMLData(WKPageRef page, void* context, WKPageGetContentsAsMHTMLDataFunction function); typedef void (*WKPageGetSelectionAsWebArchiveDataFunction)(WKDataRef, WKErrorRef, void*); WK_EXPORT void WKPageGetSelectionAsWebArchiveData(WKPageRef page, void* context, WKPageGetSelectionAsWebArchiveDataFunction function); diff --git a/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.cpp b/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.cpp new file mode 100644 index 000000000..4f4d5f094 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKPageConfigurationRef.h" + +#include "APIPageConfiguration.h" +#include "WKAPICast.h" +#include "WebPageGroup.h" +#include "WebProcessPool.h" +#include "WebUserContentControllerProxy.h" + +using namespace WebKit; + +WKTypeID WKPageConfigurationGetTypeID() +{ + return toAPI(API::PageConfiguration::APIType); +} + +WKPageConfigurationRef WKPageConfigurationCreate() +{ + return toAPI(&API::PageConfiguration::create().leakRef()); +} + +WKContextRef WKPageConfigurationGetContext(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->processPool()); +} + +void WKPageConfigurationSetContext(WKPageConfigurationRef configuration, WKContextRef context) +{ + toImpl(configuration)->setProcessPool(toImpl(context)); +} + +WKPageGroupRef WKPageConfigurationGetPageGroup(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->pageGroup()); +} + +void WKPageConfigurationSetPageGroup(WKPageConfigurationRef configuration, WKPageGroupRef pageGroup) +{ + toImpl(configuration)->setPageGroup(toImpl(pageGroup)); +} + +WKUserContentControllerRef WKPageConfigurationGetUserContentController(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->userContentController()); +} + +void WKPageConfigurationSetUserContentController(WKPageConfigurationRef configuration, WKUserContentControllerRef userContentController) +{ + toImpl(configuration)->setUserContentController(toImpl(userContentController)); +} + +WKPreferencesRef WKPageConfigurationGetPreferences(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->preferences()); +} + +void WKPageConfigurationSetPreferences(WKPageConfigurationRef configuration, WKPreferencesRef preferences) +{ + toImpl(configuration)->setPreferences(toImpl(preferences)); +} + +WKPageRef WKPageConfigurationGetRelatedPage(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->relatedPage()); +} + +void WKPageConfigurationSetRelatedPage(WKPageConfigurationRef configuration, WKPageRef relatedPage) +{ + toImpl(configuration)->setRelatedPage(toImpl(relatedPage)); +} + +WKWebsiteDataStoreRef WKPageConfigurationGetWebsiteDataStore(WKPageConfigurationRef configuration) +{ + return toAPI(toImpl(configuration)->websiteDataStore()); +} + +void WKPageConfigurationSetWebsiteDataStore(WKPageConfigurationRef configuration, WKWebsiteDataStoreRef websiteDataStore) +{ + toImpl(configuration)->setWebsiteDataStore(toImpl(websiteDataStore)); +} + +void WKPageConfigurationSetInitialCapitalizationEnabled(WKPageConfigurationRef configuration, bool enabled) +{ + toImpl(configuration)->setInitialCapitalizationEnabled(enabled); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.h b/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.h new file mode 100644 index 000000000..72e7a6bc2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPageConfigurationRef.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKPageConfigurationRef_h +#define WKPageConfigurationRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKPageConfigurationGetTypeID(); + +WK_EXPORT WKPageConfigurationRef WKPageConfigurationCreate(); + +WK_EXPORT WKContextRef WKPageConfigurationGetContext(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetContext(WKPageConfigurationRef configuration, WKContextRef context); + +WK_EXPORT WKPageGroupRef WKPageConfigurationGetPageGroup(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetPageGroup(WKPageConfigurationRef configuration, WKPageGroupRef pageGroup); + +WK_EXPORT WKUserContentControllerRef WKPageConfigurationGetUserContentController(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetUserContentController(WKPageConfigurationRef configuration, WKUserContentControllerRef userContentController); + +WK_EXPORT WKPreferencesRef WKPageConfigurationGetPreferences(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetPreferences(WKPageConfigurationRef configuration, WKPreferencesRef preferences); + +WK_EXPORT WKPageRef WKPageConfigurationGetRelatedPage(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetRelatedPage(WKPageConfigurationRef configuration, WKPageRef relatedPage); + +WK_EXPORT WKWebsiteDataStoreRef WKPageConfigurationGetWebsiteDataStore(WKPageConfigurationRef configuration); +WK_EXPORT void WKPageConfigurationSetWebsiteDataStore(WKPageConfigurationRef configuration, WKWebsiteDataStoreRef websiteDataStore); + +WK_EXPORT void WKPageConfigurationSetInitialCapitalizationEnabled(WKPageConfigurationRef configuration, bool enabled); + +#ifdef __cplusplus +} +#endif + +#endif // WKPageConfigurationRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPageContextMenuClient.h b/Source/WebKit2/UIProcess/API/C/WKPageContextMenuClient.h index e892c3d59..18d7b5b67 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageContextMenuClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageContextMenuClient.h @@ -26,14 +26,15 @@ #ifndef WKPageContextMenuClient_h #define WKPageContextMenuClient_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKGeometry.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKGeometry.h> #ifdef __cplusplus extern "C" { #endif typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo); +typedef void (*WKPageGetContextMenuFromProposedContextMenuCallbackAsync)(WKPageRef page, WKArrayRef proposedMenu, WKContextMenuListenerRef listener, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo); typedef void (*WKPageCustomContextMenuItemSelectedCallback)(WKPageRef page, WKContextMenuItemRef contextMenuItem, const void* clientInfo); typedef void (*WKPageContextMenuDismissedCallback)(WKPageRef page, const void* clientInfo); typedef void (*WKPageShowContextMenuCallback)(WKPageRef page, WKPoint menuLocation, WKArrayRef menuItems, const void* clientInfo); @@ -98,10 +99,8 @@ typedef struct WKPageContextMenuClientV3 { WKPageHideContextMenuCallback hideContextMenu; } WKPageContextMenuClientV3; -enum { kWKPageContextMenuClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 3 }; -typedef struct WKPageContextMenuClient { - int version; - const void * clientInfo; +typedef struct WKPageContextMenuClientV4 { + WKPageContextMenuClientBase base; // Version 0. WKPageGetContextMenuFromProposedContextMenuCallback_deprecatedForUseWithV0 getContextMenuFromProposedMenu_deprecatedForUseWithV0; @@ -116,7 +115,11 @@ typedef struct WKPageContextMenuClient { // Version 3. WKPageShowContextMenuCallback showContextMenu; WKPageHideContextMenuCallback hideContextMenu; -} WKPageContextMenuClient WK_DEPRECATED("Use an explicit versioned struct instead"); + + // Version 4. + WKPageGetContextMenuFromProposedContextMenuCallbackAsync getContextMenuFromProposedMenuAsync; + +} WKPageContextMenuClientV4; #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKPageDiagnosticLoggingClient.h b/Source/WebKit2/UIProcess/API/C/WKPageDiagnosticLoggingClient.h new file mode 100644 index 000000000..8ae513a3b --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPageDiagnosticLoggingClient.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKPageDiagnosticLoggingClient_h +#define WKPageDiagnosticLoggingClient_h + +#include <WebKit/WKBase.h> +#include <WebKit/WKDiagnosticLoggingResultType.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*WKPageLogDiagnosticMessageCallback)(WKPageRef page, WKStringRef message, WKStringRef description, const void* clientInfo); +typedef void (*WKPageLogDiagnosticMessageWithResultCallback)(WKPageRef page, WKStringRef message, WKStringRef description, WKDiagnosticLoggingResultType result, const void* clientInfo); +typedef void (*WKPageLogDiagnosticMessageWithValueCallback)(WKPageRef page, WKStringRef message, WKStringRef description, WKStringRef value, const void* clientInfo); +typedef void (*WKPageLogDiagnosticMessageWithEnhancedPrivacyCallback)(WKPageRef page, WKStringRef message, WKStringRef description, const void* clientInfo); + +typedef struct WKPageDiagnosticLoggingClientBase { + int version; + const void * clientInfo; +} WKPageDiagnosticLoggingClientBase; + +typedef struct WKPageDiagnosticLoggingClientV0 { + WKPageDiagnosticLoggingClientBase base; + + // Version 0. + WKPageLogDiagnosticMessageCallback logDiagnosticMessage; + WKPageLogDiagnosticMessageWithResultCallback logDiagnosticMessageWithResult; + WKPageLogDiagnosticMessageWithValueCallback logDiagnosticMessageWithValue; +} WKPageDiagnosticLoggingClientV0; + +typedef struct WKPageDiagnosticLoggingClientV1 { + WKPageDiagnosticLoggingClientBase base; + + // Version 0. + WKPageLogDiagnosticMessageCallback logDiagnosticMessage; + WKPageLogDiagnosticMessageWithResultCallback logDiagnosticMessageWithResult; + WKPageLogDiagnosticMessageWithValueCallback logDiagnosticMessageWithValue; + + // Version 1. + WKPageLogDiagnosticMessageWithEnhancedPrivacyCallback logDiagnosticMessageWithEnhancedPrivacy; +} WKPageDiagnosticLoggingClientV1; + +#ifdef __cplusplus +} +#endif + +#endif // WKPageDiagnosticLoggingClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPageFindClient.h b/Source/WebKit2/UIProcess/API/C/WKPageFindClient.h index 4d67d69db..6c7b1f22c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageFindClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageFindClient.h @@ -26,7 +26,7 @@ #ifndef WKPageFindClient_h #define WKPageFindClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -50,17 +50,6 @@ typedef struct WKPageFindClientV0 { WKPageDidCountStringMatchesCallback didCountStringMatches; } WKPageFindClientV0; -enum { kWKPageFindClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKPageFindClient { - int version; - const void * clientInfo; - - // Version 0. - WKPageDidFindStringCallback didFindString; - WKPageDidFailToFindStringCallback didFailToFindString; - WKPageDidCountStringMatchesCallback didCountStringMatches; -} WKPageFindClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPageFindMatchesClient.h b/Source/WebKit2/UIProcess/API/C/WKPageFindMatchesClient.h index 15701aac6..395588c7e 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageFindMatchesClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageFindMatchesClient.h @@ -26,7 +26,7 @@ #ifndef WKPageFindMatchesClient_h #define WKPageFindMatchesClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -53,14 +53,6 @@ typedef struct WKPageFindMatchesClientV0 { WKPageDidGetImageForMatchResultCallback didGetImageForMatchResult; } WKPageFindMatchesClientV0; -enum { kWKPageFindMatchesClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKPageFindMatchesClient { - int version; - const void * clientInfo; - WKPageDidFindStringMatchesCallback didFindStringMatches; - WKPageDidGetImageForMatchResultCallback didGetImageForMatchResult; -} WKPageFindMatchesClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPageFormClient.h b/Source/WebKit2/UIProcess/API/C/WKPageFormClient.h index 98b2c6abe..2e6b7aeb1 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageFormClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageFormClient.h @@ -26,7 +26,7 @@ #ifndef WKPageFormClient_h #define WKPageFormClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -47,15 +47,6 @@ typedef struct WKPageFormClientV0 { WKPageWillSubmitFormCallback willSubmitForm; } WKPageFormClientV0; -enum { kWKPageFormClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 0 }; -typedef struct WKPageFormClient { - int version; - const void * clientInfo; - - // Version 0. - WKPageWillSubmitFormCallback willSubmitForm; -} WKPageFormClient WK_DEPRECATED("Use an explicit versioned struct instead"); - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPageGroup.cpp b/Source/WebKit2/UIProcess/API/C/WKPageGroup.cpp index 51298cd14..81e9cbf60 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageGroup.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPageGroup.cpp @@ -26,9 +26,14 @@ #include "config.h" #include "WKPageGroup.h" +#include "APIUserContentExtension.h" +#include "APIUserContentWorld.h" +#include "APIUserScript.h" +#include "APIUserStyleSheet.h" #include "WKAPICast.h" #include "WebPageGroup.h" #include "WebPreferences.h" +#include "WebUserContentControllerProxy.h" using namespace WebKit; @@ -39,13 +44,8 @@ WKTypeID WKPageGroupGetTypeID() WKPageGroupRef WKPageGroupCreateWithIdentifier(WKStringRef identifier) { - RefPtr<WebPageGroup> pageGroup = WebPageGroup::create(toWTFString(identifier)); - return toAPI(pageGroup.release().leakRef()); -} - -WKStringRef WKPageGroupCopyIdentifier(WKPageGroupRef pageGroupRef) -{ - return toCopiedAPI(toImpl(pageGroupRef)->identifier()); + auto pageGroup = WebPageGroup::create(toWTFString(identifier)); + return toAPI(pageGroup.leakRef()); } void WKPageGroupSetPreferences(WKPageGroupRef pageGroupRef, WKPreferencesRef preferencesRef) @@ -55,25 +55,51 @@ void WKPageGroupSetPreferences(WKPageGroupRef pageGroupRef, WKPreferencesRef pre WKPreferencesRef WKPageGroupGetPreferences(WKPageGroupRef pageGroupRef) { - return toAPI(toImpl(pageGroupRef)->preferences()); + return toAPI(&toImpl(pageGroupRef)->preferences()); } -void WKPageGroupAddUserStyleSheet(WKPageGroupRef pageGroupRef, WKStringRef sourceRef, WKURLRef baseURL, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames injectedFrames) +WKUserContentControllerRef WKPageGroupGetUserContentController(WKPageGroupRef pageGroupRef) { - toImpl(pageGroupRef)->addUserStyleSheet(toWTFString(sourceRef), toWTFString(baseURL), toImpl(whitelistedURLPatterns), toImpl(blacklistedURLPatterns), toUserContentInjectedFrames(injectedFrames), WebCore::UserStyleUserLevel); + return toAPI(&toImpl(pageGroupRef)->userContentController()); } -void WKPageGroupRemoveAllUserStyleSheets(WKPageGroupRef pageGroupRef) +void WKPageGroupAddUserStyleSheet(WKPageGroupRef pageGroupRef, WKStringRef sourceRef, WKURLRef baseURLRef, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames injectedFrames) { - toImpl(pageGroupRef)->removeAllUserStyleSheets(); + auto source = toWTFString(sourceRef); + + if (source.isEmpty()) + return; + + auto baseURLString = toWTFString(baseURLRef); + auto whitelist = toImpl(whitelistedURLPatterns); + auto blacklist = toImpl(blacklistedURLPatterns); + + Ref<API::UserStyleSheet> userStyleSheet = API::UserStyleSheet::create(WebCore::UserStyleSheet { source, (baseURLString.isEmpty() ? WebCore::blankURL() : WebCore::URL(WebCore::URL(), baseURLString)), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), toUserContentInjectedFrames(injectedFrames), WebCore::UserStyleUserLevel }, API::UserContentWorld::normalWorld()); + + toImpl(pageGroupRef)->userContentController().addUserStyleSheet(userStyleSheet.get()); } -void WKPageGroupAddUserScript(WKPageGroupRef pageGroupRef, WKStringRef sourceRef, WKURLRef baseURL, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames injectedFrames, WKUserScriptInjectionTime injectionTime) +void WKPageGroupRemoveAllUserStyleSheets(WKPageGroupRef pageGroup) { - toImpl(pageGroupRef)->addUserScript(toWTFString(sourceRef), toWTFString(baseURL), toImpl(whitelistedURLPatterns), toImpl(blacklistedURLPatterns), toUserContentInjectedFrames(injectedFrames), toUserScriptInjectionTime(injectionTime)); + toImpl(pageGroup)->userContentController().removeAllUserStyleSheets(); +} + +void WKPageGroupAddUserScript(WKPageGroupRef pageGroupRef, WKStringRef sourceRef, WKURLRef baseURLRef, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames injectedFrames, _WKUserScriptInjectionTime injectionTime) +{ + auto source = toWTFString(sourceRef); + + if (source.isEmpty()) + return; + + auto baseURLString = toWTFString(baseURLRef); + auto whitelist = toImpl(whitelistedURLPatterns); + auto blacklist = toImpl(blacklistedURLPatterns); + + Ref<API::UserScript> userScript = API::UserScript::create(WebCore::UserScript { source, (baseURLString.isEmpty() ? WebCore::blankURL() : WebCore::URL(WebCore::URL(), baseURLString)), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), toUserScriptInjectionTime(injectionTime), toUserContentInjectedFrames(injectedFrames) }, API::UserContentWorld::normalWorld()); + toImpl(pageGroupRef)->userContentController().addUserScript(userScript.get()); } void WKPageGroupRemoveAllUserScripts(WKPageGroupRef pageGroupRef) { - toImpl(pageGroupRef)->removeAllUserScripts(); + toImpl(pageGroupRef)->userContentController().removeAllUserScripts(); } diff --git a/Source/WebKit2/UIProcess/API/C/WKPageGroup.h b/Source/WebKit2/UIProcess/API/C/WKPageGroup.h index 530674220..d820804f0 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageGroup.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageGroup.h @@ -26,9 +26,9 @@ #ifndef WKPageGroup_h #define WKPageGroup_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKUserContentInjectedFrames.h> -#include <WebKit2/WKUserScriptInjectionTime.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKUserContentInjectedFrames.h> +#include <WebKit/WKUserScriptInjectionTime.h> #ifdef __cplusplus extern "C" { @@ -38,15 +38,15 @@ WK_EXPORT WKTypeID WKPageGroupGetTypeID(); WK_EXPORT WKPageGroupRef WKPageGroupCreateWithIdentifier(WKStringRef identifier); -WK_EXPORT WKStringRef WKPageGroupCopyIdentifier(WKPageGroupRef pageGroup); - WK_EXPORT void WKPageGroupSetPreferences(WKPageGroupRef pageGroup, WKPreferencesRef preferences); WK_EXPORT WKPreferencesRef WKPageGroupGetPreferences(WKPageGroupRef pageGroup); - + +WK_EXPORT WKUserContentControllerRef WKPageGroupGetUserContentController(WKPageGroupRef pageGroup); + WK_EXPORT void WKPageGroupAddUserStyleSheet(WKPageGroupRef pageGroup, WKStringRef source, WKURLRef baseURL, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames); WK_EXPORT void WKPageGroupRemoveAllUserStyleSheets(WKPageGroupRef pageGroup); -WK_EXPORT void WKPageGroupAddUserScript(WKPageGroupRef pageGroup, WKStringRef source, WKURLRef baseURL, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames, WKUserScriptInjectionTime); +WK_EXPORT void WKPageGroupAddUserScript(WKPageGroupRef pageGroup, WKStringRef source, WKURLRef baseURL, WKArrayRef whitelistedURLPatterns, WKArrayRef blacklistedURLPatterns, WKUserContentInjectedFrames, _WKUserScriptInjectionTime); WK_EXPORT void WKPageGroupRemoveAllUserScripts(WKPageGroupRef pageGroup); #ifdef __cplusplus diff --git a/Source/WebKit2/UIProcess/API/C/WKBatteryManager.h b/Source/WebKit2/UIProcess/API/C/WKPageInjectedBundleClient.h index 75b3eafec..b22c3eb86 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBatteryManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageInjectedBundleClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,40 +23,26 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKBatteryManager_h -#define WKBatteryManager_h +#ifndef WKPageInjectedBundleClient_h +#define WKPageInjectedBundleClient_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> -#ifdef __cplusplus -extern "C" { -#endif +typedef void (*WKPageDidReceiveMessageFromInjectedBundleCallback)(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, const void *clientInfo); +typedef void (*WKPageDidReceiveSynchronousMessageFromInjectedBundleCallback)(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void *clientInfo); +typedef WKTypeRef (*WKPageGetInjectedBundleInitializationUserDataCallback)(WKPageRef page, const void *clientInfo); -// Provider. -typedef void (*WKBatteryProviderStartUpdatingCallback)(WKBatteryManagerRef batteryManager, const void* clientInfo); -typedef void (*WKBatteryProviderStopUpdatingCallback)(WKBatteryManagerRef batteryManager, const void* clientInfo); - -typedef struct WKBatteryProviderBase { +typedef struct WKPageInjectedBundleClientBase { int version; const void * clientInfo; -} WKBatteryProviderBase; - -typedef struct WKBatteryProviderV0 { - WKBatteryProviderBase base; - - WKBatteryProviderStartUpdatingCallback startUpdating; - WKBatteryProviderStopUpdatingCallback stopUpdating; -} WKBatteryProviderV0; - -WK_EXPORT WKTypeID WKBatteryManagerGetTypeID(); - -WK_EXPORT void WKBatteryManagerSetProvider(WKBatteryManagerRef batteryManager, const WKBatteryProviderBase* provider); +} WKPageInjectedBundleClientBase; -WK_EXPORT void WKBatteryManagerProviderDidChangeBatteryStatus(WKBatteryManagerRef batteryManager, WKStringRef eventType, WKBatteryStatusRef status); -WK_EXPORT void WKBatteryManagerProviderUpdateBatteryStatus(WKBatteryManagerRef batteryManager, WKBatteryStatusRef status); +typedef struct WKPageInjectedBundleClientV0 { + WKPageInjectedBundleClientBase base; -#ifdef __cplusplus -} -#endif + // Version 0. + WKPageDidReceiveMessageFromInjectedBundleCallback didReceiveMessageFromInjectedBundle; + WKPageDidReceiveSynchronousMessageFromInjectedBundleCallback didReceiveSynchronousMessageFromInjectedBundle; +} WKPageInjectedBundleClientV0; -#endif /* WKBatteryManager_h */ +#endif // WKPageInjectedBundleClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h b/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h index 579d8c2cb..c7c1cb011 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageLoaderClient.h @@ -26,25 +26,19 @@ #ifndef WKPageLoaderClient_h #define WKPageLoaderClient_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKError.h> -#include <WebKit2/WKPageLoadTypes.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKErrorRef.h> +#include <WebKit/WKPageLoadTypes.h> +#include <WebKit/WKPluginLoadPolicy.h> #ifdef __cplusplus extern "C" { #endif enum { - kWKPluginLoadPolicyLoadNormally = 0, - kWKPluginLoadPolicyBlocked, - kWKPluginLoadPolicyInactive, - kWKPluginLoadPolicyLoadUnsandboxed, -}; -typedef uint32_t WKPluginLoadPolicy; - -enum { kWKWebGLLoadPolicyBlocked = 0, kWKWebGLLoadPolicyLoadNormally, + kWKWebGLLoadPolicyPending }; typedef uint32_t WKWebGLLoadPolicy; @@ -68,15 +62,19 @@ typedef bool (*WKPageCanAuthenticateAgainstProtectionSpaceInFrameCallback)(WKPag typedef void (*WKPageDidReceiveAuthenticationChallengeInFrameCallback)(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo); typedef void (*WKPageDidChangeBackForwardListCallback)(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void *clientInfo); typedef bool (*WKPageShouldGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, const void *clientInfo); +typedef bool (*WKPageShouldKeepCurrentBackForwardListItemInListCallback)(WKPageRef page, WKBackForwardListItemRef item, const void *clientInfo); typedef void (*WKPageWillGoToBackForwardListItemCallback)(WKPageRef page, WKBackForwardListItemRef item, WKTypeRef userData, const void *clientInfo); typedef void (*WKPageDidLayoutCallback)(WKPageRef page, WKLayoutMilestones milestones, WKTypeRef userData, const void *clientInfo); typedef WKPluginLoadPolicy (*WKPagePluginLoadPolicyCallback)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, WKStringRef* unavailabilityDescription, const void* clientInfo); -typedef void (*WKPagePluginDidFailCallback)(WKPageRef page, WKErrorCode errorCode, WKDictionaryRef pluginInfoDictionary, const void* clientInfo); +typedef void (*WKPagePluginDidFailCallback)(WKPageRef page, uint32_t errorCode, WKDictionaryRef pluginInfoDictionary, const void* clientInfo); typedef WKWebGLLoadPolicy (*WKPageWebGLLoadPolicyCallback)(WKPageRef page, WKStringRef url, const void* clientInfo); +typedef void (*WKPageNavigationGestureDidBeginCallback)(WKPageRef page, const void* clientInfo); +typedef void (*WKPageNavigationGestureWillEndCallback)(WKPageRef page, bool willNavigate, WKBackForwardListItemRef item, const void* clientInfo); +typedef void (*WKPageNavigationGestureDidEndCallback)(WKPageRef page, bool willNavigate, WKBackForwardListItemRef item, const void* clientInfo); // Deprecated typedef void (*WKPageDidFailToInitializePluginCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef mimeType, const void* clientInfo); -typedef void (*WKPagePluginDidFailCallback_deprecatedForUseWithV1)(WKPageRef page, WKErrorCode errorCode, WKStringRef mimeType, WKStringRef pluginIdentifier, WKStringRef pluginVersion, const void* clientInfo); +typedef void (*WKPagePluginDidFailCallback_deprecatedForUseWithV1)(WKPageRef page, uint32_t errorCode, WKStringRef mimeType, WKStringRef pluginIdentifier, WKStringRef pluginVersion, const void* clientInfo); typedef WKPluginLoadPolicy (*WKPagePluginLoadPolicyCallback_deprecatedForUseWithV2)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, const void* clientInfo); typedef struct WKPageLoaderClientBase { @@ -330,13 +328,74 @@ typedef struct WKPageLoaderClientV4 { // Version 4 WKPageWebGLLoadPolicyCallback webGLLoadPolicy; + WKPageWebGLLoadPolicyCallback resolveWebGLLoadPolicy; } WKPageLoaderClientV4; -// FIXME: These should be deprecated. -enum { kWKPageLoaderClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 3 }; -typedef struct WKPageLoaderClient { - int version; - const void * clientInfo; +typedef struct WKPageLoaderClientV5 { + WKPageLoaderClientBase base; + + // Version 0. + WKPageDidStartProvisionalLoadForFrameCallback didStartProvisionalLoadForFrame; + WKPageDidReceiveServerRedirectForProvisionalLoadForFrameCallback didReceiveServerRedirectForProvisionalLoadForFrame; + WKPageDidFailProvisionalLoadWithErrorForFrameCallback didFailProvisionalLoadWithErrorForFrame; + WKPageDidCommitLoadForFrameCallback didCommitLoadForFrame; + WKPageDidFinishDocumentLoadForFrameCallback didFinishDocumentLoadForFrame; + WKPageDidFinishLoadForFrameCallback didFinishLoadForFrame; + WKPageDidFailLoadWithErrorForFrameCallback didFailLoadWithErrorForFrame; + WKPageDidSameDocumentNavigationForFrameCallback didSameDocumentNavigationForFrame; + WKPageDidReceiveTitleForFrameCallback didReceiveTitleForFrame; + WKPageDidFirstLayoutForFrameCallback didFirstLayoutForFrame; + WKPageDidFirstVisuallyNonEmptyLayoutForFrameCallback didFirstVisuallyNonEmptyLayoutForFrame; + WKPageDidRemoveFrameFromHierarchyCallback didRemoveFrameFromHierarchy; + WKPageDidDisplayInsecureContentForFrameCallback didDisplayInsecureContentForFrame; + WKPageDidRunInsecureContentForFrameCallback didRunInsecureContentForFrame; + WKPageCanAuthenticateAgainstProtectionSpaceInFrameCallback canAuthenticateAgainstProtectionSpaceInFrame; + WKPageDidReceiveAuthenticationChallengeInFrameCallback didReceiveAuthenticationChallengeInFrame; + + // FIXME: Move to progress client. + WKPageLoaderClientCallback didStartProgress; + WKPageLoaderClientCallback didChangeProgress; + WKPageLoaderClientCallback didFinishProgress; + + // FIXME: These three functions should not be part of this client. + WKPageLoaderClientCallback processDidBecomeUnresponsive; + WKPageLoaderClientCallback processDidBecomeResponsive; + WKPageLoaderClientCallback processDidCrash; + WKPageDidChangeBackForwardListCallback didChangeBackForwardList; + WKPageShouldGoToBackForwardListItemCallback shouldGoToBackForwardListItem; + WKPageDidFailToInitializePluginCallback_deprecatedForUseWithV0 didFailToInitializePlugin_deprecatedForUseWithV0; + + // Version 1. + WKPageDidDetectXSSForFrameCallback didDetectXSSForFrame; + + void* didNewFirstVisuallyNonEmptyLayout_unavailable; + + WKPageWillGoToBackForwardListItemCallback willGoToBackForwardListItem; + + WKPageLoaderClientCallback interactionOccurredWhileProcessUnresponsive; + WKPagePluginDidFailCallback_deprecatedForUseWithV1 pluginDidFail_deprecatedForUseWithV1; + + // Version 2. + void (*didReceiveIntentForFrame_unavailable)(void); + void (*registerIntentServiceForFrame_unavailable)(void); + + WKPageDidLayoutCallback didLayout; + WKPagePluginLoadPolicyCallback_deprecatedForUseWithV2 pluginLoadPolicy_deprecatedForUseWithV2; + WKPagePluginDidFailCallback pluginDidFail; + + // Version 3. + WKPagePluginLoadPolicyCallback pluginLoadPolicy; + + // Version 4. + WKPageWebGLLoadPolicyCallback webGLLoadPolicy; + WKPageWebGLLoadPolicyCallback resolveWebGLLoadPolicy; + + // Version 5. + WKPageShouldKeepCurrentBackForwardListItemInListCallback shouldKeepCurrentBackForwardListItemInList; +} WKPageLoaderClientV5; + +typedef struct WKPageLoaderClientV6 { + WKPageLoaderClientBase base; // Version 0. WKPageDidStartProvisionalLoadForFrameCallback didStartProvisionalLoadForFrame; @@ -389,7 +448,19 @@ typedef struct WKPageLoaderClient { // Version 3. WKPagePluginLoadPolicyCallback pluginLoadPolicy; -} WKPageLoaderClient; + + // Version 4. + WKPageWebGLLoadPolicyCallback webGLLoadPolicy; + WKPageWebGLLoadPolicyCallback resolveWebGLLoadPolicy; + + // Version 5. + WKPageShouldKeepCurrentBackForwardListItemInListCallback shouldKeepCurrentBackForwardListItemInList; + + // Version 6. + WKPageNavigationGestureDidBeginCallback navigationGestureDidBegin; + WKPageNavigationGestureWillEndCallback navigationGestureWillEnd; + WKPageNavigationGestureDidEndCallback navigationGestureDidEnd; +} WKPageLoaderClientV6; #ifdef __cplusplus } diff --git a/Source/WebKit2/UIProcess/API/C/WKPageNavigationClient.h b/Source/WebKit2/UIProcess/API/C/WKPageNavigationClient.h new file mode 100644 index 000000000..e19cf9741 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPageNavigationClient.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKPageNavigationClient_h +#define WKPageNavigationClient_h + +#include <WebKit/WKBase.h> +#include <WebKit/WKPageLoadTypes.h> +#include <WebKit/WKPageRenderingProgressEvents.h> +#include <WebKit/WKPluginLoadPolicy.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*WKPageNavigationDecidePolicyForNavigationActionCallback)(WKPageRef page, WKNavigationActionRef navigationAction, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDecidePolicyForNavigationResponseCallback)(WKPageRef page, WKNavigationResponseRef navigationResponse, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidStartProvisionalNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidReceiveServerRedirectForProvisionalNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidFailProvisionalNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKErrorRef error, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidCommitNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidFinishNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidFailNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKErrorRef error, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidFailProvisionalLoadInSubframeCallback)(WKPageRef page, WKNavigationRef navigation, WKFrameInfoRef subframe, WKErrorRef error, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidFinishDocumentLoadCallback)(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationDidSameDocumentNavigationCallback)(WKPageRef page, WKNavigationRef navigation, WKSameDocumentNavigationType navigationType, WKTypeRef userData, const void* clientInfo); + +typedef void (*WKPageNavigationRenderingProgressDidChangeCallback)(WKPageRef page, WKPageRenderingProgressEvents progressEvents, WKTypeRef userData, const void* clientInfo); + +typedef bool (*WKPageNavigationCanAuthenticateAgainstProtectionSpaceCallback)(WKPageRef page, WKProtectionSpaceRef protectionSpace, const void* clientInfo); + +typedef void (*WKPageNavigationDidReceiveAuthenticationChallengeCallback)(WKPageRef page, WKAuthenticationChallengeRef challenge, const void* clientInfo); + +typedef void (*WKPageNavigationWebProcessDidCrashCallback)(WKPageRef page, const void* clientInfo); + +typedef WKDataRef (*WKPageNavigationCopyWebCryptoMasterKeyCallback)(WKPageRef page, const void* clientInfo); + +typedef WKPluginLoadPolicy (*WKPageNavigationDecidePolicyForPluginLoadCallback)(WKPageRef page, WKPluginLoadPolicy currentPluginLoadPolicy, WKDictionaryRef pluginInfoDictionary, WKStringRef* unavailabilityDescription, const void* clientInfo); + +typedef void (*WKPageNavigationDidBeginNavigationGesture)(WKPageRef page, const void* clientInfo); + +typedef void (*WKPageNavigationWillEndNavigationGesture)(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void* clientInfo); + +typedef void (*WKPageNavigationDidEndNavigationGesture)(WKPageRef page, WKBackForwardListItemRef backForwardListItem, const void* clientInfo); + +typedef void (*WKPageNavigationDidRemoveNavigationGestureSnapshot)(WKPageRef page, const void* clientInfo); + + +typedef struct WKPageNavigationClientBase { + int version; + const void* clientInfo; +} WKPageNavigationClientBase; + +typedef struct WKPageNavigationClientV0 { + WKPageNavigationClientBase base; + + // Version 0. + WKPageNavigationDecidePolicyForNavigationActionCallback decidePolicyForNavigationAction; + WKPageNavigationDecidePolicyForNavigationResponseCallback decidePolicyForNavigationResponse; + WKPageNavigationDecidePolicyForPluginLoadCallback decidePolicyForPluginLoad; + WKPageNavigationDidStartProvisionalNavigationCallback didStartProvisionalNavigation; + WKPageNavigationDidReceiveServerRedirectForProvisionalNavigationCallback didReceiveServerRedirectForProvisionalNavigation; + WKPageNavigationDidFailProvisionalNavigationCallback didFailProvisionalNavigation; + WKPageNavigationDidCommitNavigationCallback didCommitNavigation; + WKPageNavigationDidFinishNavigationCallback didFinishNavigation; + WKPageNavigationDidFailNavigationCallback didFailNavigation; + WKPageNavigationDidFailProvisionalLoadInSubframeCallback didFailProvisionalLoadInSubframe; + WKPageNavigationDidFinishDocumentLoadCallback didFinishDocumentLoad; + WKPageNavigationDidSameDocumentNavigationCallback didSameDocumentNavigation; + WKPageNavigationRenderingProgressDidChangeCallback renderingProgressDidChange; + WKPageNavigationCanAuthenticateAgainstProtectionSpaceCallback canAuthenticateAgainstProtectionSpace; + WKPageNavigationDidReceiveAuthenticationChallengeCallback didReceiveAuthenticationChallenge; + WKPageNavigationWebProcessDidCrashCallback webProcessDidCrash; + WKPageNavigationCopyWebCryptoMasterKeyCallback copyWebCryptoMasterKey; + + WKPageNavigationDidBeginNavigationGesture didBeginNavigationGesture; + WKPageNavigationWillEndNavigationGesture willEndNavigationGesture; + WKPageNavigationDidEndNavigationGesture didEndNavigationGesture; + WKPageNavigationDidRemoveNavigationGestureSnapshot didRemoveNavigationGestureSnapshot; +} WKPageNavigationClientV0; + +#ifdef __cplusplus +} +#endif + +#endif // WKPageNavigationClient_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPagePolicyClient.h b/Source/WebKit2/UIProcess/API/C/WKPagePolicyClient.h index 15f834835..121c1018a 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPagePolicyClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPagePolicyClient.h @@ -26,9 +26,9 @@ #ifndef WKPagePolicyClient_h #define WKPagePolicyClient_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKEvent.h> -#include <WebKit2/WKPageLoadTypes.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKEvent.h> +#include <WebKit/WKPageLoadTypes.h> #ifdef __cplusplus extern "C" { @@ -71,23 +71,6 @@ typedef struct WKPagePolicyClientV1 { WKPageDecidePolicyForResponseCallback decidePolicyForResponse; } WKPagePolicyClientV1; -// FIXME: These should be deprecated. -enum { kWKPagePolicyClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 1 }; -typedef struct WKPagePolicyClient { - int version; - const void * clientInfo; - - // Version 0. - WKPageDecidePolicyForNavigationActionCallback_deprecatedForUseWithV0 decidePolicyForNavigationAction_deprecatedForUseWithV0; - WKPageDecidePolicyForNewWindowActionCallback decidePolicyForNewWindowAction; - WKPageDecidePolicyForResponseCallback_deprecatedForUseWithV0 decidePolicyForResponse_deprecatedForUseWithV0; - WKPageUnableToImplementPolicyCallback unableToImplementPolicy; - - // Version 1. - WKPageDecidePolicyForNavigationActionCallback decidePolicyForNavigationAction; - WKPageDecidePolicyForResponseCallback decidePolicyForResponse; -} WKPagePolicyClient; - #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h index 5d6f66082..d3ed91af6 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h @@ -26,8 +26,8 @@ #ifndef WKPagePrivate_h #define WKPagePrivate_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKPage.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKPage.h> #ifdef __cplusplus extern "C" { @@ -42,9 +42,6 @@ enum { }; typedef unsigned WKPageDebugPaintFlags; -WK_EXPORT void WKPageSetDebugPaintFlags(WKPageDebugPaintFlags flags); -WK_EXPORT WKPageDebugPaintFlags WKPageGetDebugPaintFlags(void); - WK_EXPORT WKStringRef WKPageCopyStandardUserAgentWithApplicationName(WKStringRef); enum { @@ -64,6 +61,8 @@ WK_EXPORT void WKPageSetPageLength(WKPageRef page, double pageLength); WK_EXPORT double WKPageGetPageLength(WKPageRef page); WK_EXPORT void WKPageSetGapBetweenPages(WKPageRef page, double gap); WK_EXPORT double WKPageGetGapBetweenPages(WKPageRef page); +WK_EXPORT void WKPageSetPaginationLineGridEnabled(WKPageRef page, bool lineGridEnabled); +WK_EXPORT bool WKPageGetPaginationLineGridEnabled(WKPageRef page); WK_EXPORT unsigned WKPageGetPageCount(WKPageRef page); @@ -82,18 +81,27 @@ WK_EXPORT void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo WK_EXPORT void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context); WK_EXPORT void WKPageEndPrinting(WKPageRef page); -// FIXME https://bugs.webkit.org/show_bug.cgi?id=66979: Remove this sync call. -WK_EXPORT WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef page); +WK_EXPORT bool WKPageGetIsControlledByAutomation(WKPageRef page); +WK_EXPORT void WKPageSetControlledByAutomation(WKPageRef page, bool controlled); -WK_EXPORT void WKPageSetShouldSendEventsSynchronously(WKPageRef page, bool sync); +WK_EXPORT bool WKPageGetAllowsRemoteInspection(WKPageRef page); +WK_EXPORT void WKPageSetAllowsRemoteInspection(WKPageRef page, bool allow); WK_EXPORT void WKPageSetMediaVolume(WKPageRef page, float volume); WK_EXPORT void WKPageSetMayStartMediaWhenInWindow(WKPageRef page, bool mayStartMedia); +typedef void (*WKPageGetBytecodeProfileFunction)(WKStringRef, WKErrorRef, void*); +WK_EXPORT void WKPageGetBytecodeProfile(WKPageRef page, void* context, WKPageGetBytecodeProfileFunction function); + +typedef void (*WKPageGetSamplingProfilerOutputFunction)(WKStringRef, WKErrorRef, void*); +WK_EXPORT void WKPageGetSamplingProfilerOutput(WKPageRef page, void* context, WKPageGetSamplingProfilerOutputFunction function); + +typedef void (*WKPageIsWebProcessResponsiveFunction)(bool isWebProcessResponsive, void* context); +WK_EXPORT void WKPageIsWebProcessResponsive(WKPageRef page, void* context, WKPageIsWebProcessResponsiveFunction function); + WK_EXPORT WKArrayRef WKPageCopyRelatedPages(WKPageRef page); -typedef void (*WKPageInvalidMessageFunction)(uint32_t messageID); -WK_EXPORT void WKPageSetInvalidMessageFunction(WKPageInvalidMessageFunction function); +WK_EXPORT WKFrameRef WKPageLookUpFrameFromHandle(WKPageRef page, WKFrameHandleRef handle); enum { kWKScrollPinningBehaviorDoNotPin, @@ -105,6 +113,60 @@ typedef uint32_t WKScrollPinningBehavior; WK_EXPORT WKScrollPinningBehavior WKPageGetScrollPinningBehavior(WKPageRef page); WK_EXPORT void WKPageSetScrollPinningBehavior(WKPageRef page, WKScrollPinningBehavior pinning); +WK_EXPORT bool WKPageGetAddsVisitedLinks(WKPageRef page); +WK_EXPORT void WKPageSetAddsVisitedLinks(WKPageRef page, bool visitedLinks); + +WK_EXPORT bool WKPageIsPlayingAudio(WKPageRef page); + +enum { + kWKMediaNoneMuted = 0, + kWKMediaAudioMuted = 1 << 0, + kWKMediaCaptureDevicesMuted = 1 << 1, +}; +typedef uint32_t WKMediaMutedState; +WK_EXPORT void WKPageSetMuted(WKPageRef page, WKMediaMutedState muted); + +WK_EXPORT void WKPageClearUserMediaState(WKPageRef page); + +WK_EXPORT void WKPageDidAllowPointerLock(WKPageRef page); +WK_EXPORT void WKPageDidDenyPointerLock(WKPageRef page); + +enum { + kWKMediaIsNotPlaying = 0, + kWKMediaIsPlayingAudio = 1 << 0, + kWKMediaIsPlayingVideo = 1 << 1, + kWKMediaHasActiveAudioCaptureDevice = 1 << 2, + kWKMediaHasActiveVideoCaptureDevice = 1 << 3, +}; +typedef uint32_t WKMediaState; + + +WK_EXPORT WKMediaState WKPageGetMediaState(WKPageRef page); + +enum { + kWKMediaEventTypePlayPause, + kWKMediaEventTypeTrackNext, + kWKMediaEventTypeTrackPrevious +}; +typedef uint32_t WKMediaEventType; + +WK_EXPORT bool WKPageHasMediaSessionWithActiveMediaElements(WKPageRef page); +WK_EXPORT void WKPageHandleMediaEvent(WKPageRef page, WKMediaEventType event); + +WK_EXPORT void WKPageLoadURLWithShouldOpenExternalURLsPolicy(WKPageRef page, WKURLRef url, bool shouldOpenExternalURLs); + +typedef void (*WKPagePostPresentationUpdateFunction)(WKErrorRef, void*); +WK_EXPORT void WKPageCallAfterNextPresentationUpdate(WKPageRef page, void* context, WKPagePostPresentationUpdateFunction function); + +WK_EXPORT bool WKPageGetResourceCachingDisabled(WKPageRef page); +WK_EXPORT void WKPageSetResourceCachingDisabled(WKPageRef page, bool disabled); + +WK_EXPORT void WKPageRestoreFromSessionStateWithoutNavigation(WKPageRef page, WKTypeRef sessionState); + +WK_EXPORT void WKPageSetIgnoresViewportScaleLimits(WKPageRef page, bool ignoresViewportScaleLimits); + +WK_EXPORT pid_t WKPageGetProcessIdentifier(WKPageRef page); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKSessionRef.h b/Source/WebKit2/UIProcess/API/C/WKPageRenderingProgressEvents.h index 63fa54277..6d258ed15 100644 --- a/Source/WebKit2/UIProcess/API/C/WKSessionRef.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageRenderingProgressEvents.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,24 +23,25 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKSessionRef_h -#define WKSessionRef_h +#ifndef WKPageRenderingProgressEvents_h +#define WKPageRenderingProgressEvents_h -#include <WebKit2/WKBase.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { #endif -/* FIXME: We can create sessions on demand, because we hardcode the fact that all sessions but the default one are ephemeral. We'll need to create them explicitly once sessions have more configuration options. */ -WK_EXPORT WKSessionRef WKSessionCreate(bool isEphemeral); - -WK_EXPORT WKTypeID WKSessionGetTypeID(); - -WK_EXPORT bool WKSessionIsEphemeral(WKSessionRef session); +enum { + WKPageRenderingProgressEventFirstLayout = 1 << 0, + WKPageRenderingProgressEventFirstVisuallyNonEmptyLayout = 1 << 1, + WKPageRenderingProgressEventFirstPaintWithSignificantArea = 1 << 2, + WKPageRenderingProgressEventReachedSessionRestorationRenderTreeSizeThreshold = 1 << 3 +}; +typedef uint32_t WKPageRenderingProgressEvents; #ifdef __cplusplus } #endif -#endif /* WKSessionRef_h */ +#endif /* WKPageRenderingProgressEvents_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKPageRenderingProgressEventsInternal.h b/Source/WebKit2/UIProcess/API/C/WKPageRenderingProgressEventsInternal.h new file mode 100644 index 000000000..ab9274534 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPageRenderingProgressEventsInternal.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "WKPageRenderingProgressEvents.h" + +#include <WebCore/LayoutMilestones.h> + +static inline WKPageRenderingProgressEvents pageRenderingProgressEvents(WebCore::LayoutMilestones milestones) +{ + WKPageRenderingProgressEvents events = 0; + + if (milestones & WebCore::DidFirstLayout) + events |= WKPageRenderingProgressEventFirstLayout; + + if (milestones & WebCore::DidFirstVisuallyNonEmptyLayout) + events |= WKPageRenderingProgressEventFirstVisuallyNonEmptyLayout; + + if (milestones & WebCore::DidHitRelevantRepaintedObjectsAreaThreshold) + events |= WKPageRenderingProgressEventFirstPaintWithSignificantArea; + + if (milestones & WebCore::ReachedSessionRestorationRenderTreeSizeThreshold) + events |= WKPageRenderingProgressEventReachedSessionRestorationRenderTreeSizeThreshold; + + return events; +} diff --git a/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h b/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h index 1d8417000..21f51a882 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h +++ b/Source/WebKit2/UIProcess/API/C/WKPageUIClient.h @@ -26,10 +26,10 @@ #ifndef WKPageUIClient_h #define WKPageUIClient_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKEvent.h> -#include <WebKit2/WKGeometry.h> -#include <WebKit2/WKNativeEvent.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKEvent.h> +#include <WebKit/WKGeometry.h> +#include <WebKit/WKNativeEvent.h> #ifdef __cplusplus extern "C" { @@ -48,11 +48,24 @@ enum { }; typedef uint32_t WKPluginUnavailabilityReason; +WK_EXPORT WKTypeID WKPageRunBeforeUnloadConfirmPanelResultListenerGetTypeID(); +WK_EXPORT void WKPageRunBeforeUnloadConfirmPanelResultListenerCall(WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, bool result); + +WK_EXPORT WKTypeID WKPageRunJavaScriptAlertResultListenerGetTypeID(); +WK_EXPORT void WKPageRunJavaScriptAlertResultListenerCall(WKPageRunJavaScriptAlertResultListenerRef listener); + +WK_EXPORT WKTypeID WKPageRunJavaScriptConfirmResultListenerGetTypeID(); +WK_EXPORT void WKPageRunJavaScriptConfirmResultListenerCall(WKPageRunJavaScriptConfirmResultListenerRef listener, bool result); + +WK_EXPORT WKTypeID WKPageRunJavaScriptPromptResultListenerGetTypeID(); +WK_EXPORT void WKPageRunJavaScriptPromptResultListenerCall(WKPageRunJavaScriptPromptResultListenerRef listener, WKStringRef result); + typedef void (*WKPageUIClientCallback)(WKPageRef page, const void* clientInfo); -typedef WKPageRef (*WKPageCreateNewPageCallback)(WKPageRef page, WKURLRequestRef urlRequest, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo); -typedef void (*WKPageRunJavaScriptAlertCallback)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void *clientInfo); -typedef bool (*WKPageRunJavaScriptConfirmCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, const void *clientInfo); -typedef WKStringRef (*WKPageRunJavaScriptPromptCallback)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void *clientInfo); +typedef WKPageRef (*WKPageCreateNewPageCallback)(WKPageRef page, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo); +typedef void (*WKPageRunBeforeUnloadConfirmPanelCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, WKPageRunBeforeUnloadConfirmPanelResultListenerRef listener, const void *clientInfo); +typedef void (*WKPageRunJavaScriptAlertCallback)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptAlertResultListenerRef listener, const void *clientInfo); +typedef void (*WKPageRunJavaScriptConfirmCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptConfirmResultListenerRef listener, const void *clientInfo); +typedef void (*WKPageRunJavaScriptPromptCallback)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, WKPageRunJavaScriptPromptResultListenerRef listener, const void *clientInfo); typedef void (*WKPageTakeFocusCallback)(WKPageRef page, WKFocusDirection direction, const void *clientInfo); typedef void (*WKPageFocusCallback)(WKPageRef page, const void *clientInfo); typedef void (*WKPageUnfocusCallback)(WKPageRef page, const void *clientInfo); @@ -70,7 +83,6 @@ typedef bool (*WKPageGetIsResizableCallback)(WKPageRef page, const void *clientI typedef void (*WKPageSetIsResizableCallback)(WKPageRef page, bool resizable, const void *clientInfo); typedef WKRect (*WKPageGetWindowFrameCallback)(WKPageRef page, const void *clientInfo); typedef void (*WKPageSetWindowFrameCallback)(WKPageRef page, WKRect frame, const void *clientInfo); -typedef bool (*WKPageRunBeforeUnloadConfirmPanelCallback)(WKPageRef page, WKStringRef message, WKFrameRef frame, const void *clientInfo); typedef unsigned long long (*WKPageExceededDatabaseQuotaCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKStringRef databaseName, WKStringRef displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage, const void *clientInfo); typedef void (*WKPageRunOpenPanelCallback)(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo); typedef void (*WKPageDecidePolicyForGeolocationPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo); @@ -80,17 +92,35 @@ typedef void (*WKPageDrawHeaderCallback)(WKPageRef page, WKFrameRef frame, WKRec typedef void (*WKPageDrawFooterCallback)(WKPageRef page, WKFrameRef frame, WKRect rect, const void* clientInfo); typedef void (*WKPagePrintFrameCallback)(WKPageRef page, WKFrameRef frame, const void* clientInfo); typedef void (*WKPageSaveDataToFileInDownloadsFolderCallback)(WKPageRef page, WKStringRef suggestedFilename, WKStringRef mimeType, WKURLRef originatingURL, WKDataRef data, const void* clientInfo); -typedef bool (*WKPageShouldInterruptJavaScriptCallback)(WKPageRef page, const void *clientInfo); typedef void (*WKPageDecidePolicyForNotificationPermissionRequestCallback)(WKPageRef page, WKSecurityOriginRef origin, WKNotificationPermissionRequestRef permissionRequest, const void *clientInfo); typedef void (*WKPageShowColorPickerCallback)(WKPageRef page, WKStringRef initialColor, WKColorPickerResultListenerRef listener, const void* clientInfo); typedef void (*WKPageHideColorPickerCallback)(WKPageRef page, const void* clientInfo); typedef void (*WKPageUnavailablePluginButtonClickedCallback)(WKPageRef page, WKPluginUnavailabilityReason pluginUnavailabilityReason, WKDictionaryRef pluginInfoDictionary, const void* clientInfo); +typedef void (*WKPagePinnedStateDidChangeCallback)(WKPageRef page, const void* clientInfo); +typedef void (*WKPageIsPlayingAudioDidChangeCallback)(WKPageRef page, const void* clientInfo); +typedef void (*WKPageDecidePolicyForUserMediaPermissionRequestCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef permissionRequest, const void* clientInfo); +typedef void (*WKCheckUserMediaPermissionCallback)(WKPageRef page, WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionCheckRef devicesRequest, const void *clientInfo); +typedef void (*WKPageDidClickAutoFillButtonCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo); +typedef void (*WKPageMediaSessionMetadataDidChangeCallback)(WKPageRef page, WKMediaSessionMetadataRef metadata, const void* clientInfo); +typedef void (*WKDidPlayMediaPreventedFromPlayingWithoutUserGesture)(WKPageRef page, const void* clientInfo); +typedef void (*WKFullscreenMayReturnToInlineCallback)(WKPageRef page, const void* clientInfo); + +typedef void (*WKRequestPointerLockCallback)(WKPageRef page, const void* clientInfo); +typedef void (*WKDidLosePointerLockCallback)(WKPageRef page, const void* clientInfo); -// Deprecated +// Deprecated typedef WKPageRef (*WKPageCreateNewPageCallback_deprecatedForUseWithV0)(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo); typedef void (*WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0)(WKPageRef page, WKEventModifiers modifiers, WKTypeRef userData, const void *clientInfo); typedef void (*WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef mimeType, WKStringRef url, WKStringRef pluginsPageURL, const void* clientInfo); typedef void (*WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1)(WKPageRef page, WKPluginUnavailabilityReason pluginUnavailabilityReason, WKStringRef mimeType, WKStringRef url, WKStringRef pluginsPageURL, const void* clientInfo); +typedef void (*WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void *clientInfo); +typedef bool (*WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef message, WKFrameRef frame, const void *clientInfo); +typedef WKStringRef (*WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, const void *clientInfo); +typedef WKPageRef (*WKPageCreateNewPageCallback_deprecatedForUseWithV1)(WKPageRef page, WKURLRequestRef urlRequest, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo); +typedef void (*WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5)(WKPageRef page, WKStringRef alertText, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void *clientInfo); +typedef bool (*WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5)(WKPageRef page, WKStringRef message, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void *clientInfo); +typedef WKStringRef (*WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5)(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef frame, WKSecurityOriginRef securityOrigin, const void *clientInfo); +typedef bool (*WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6)(WKPageRef page, WKStringRef message, WKFrameRef frame, const void *clientInfo); typedef struct WKPageUIClientBase { int version; @@ -107,9 +137,9 @@ typedef struct WKPageUIClientV0 { WKPageTakeFocusCallback takeFocus; WKPageFocusCallback focus; WKPageUnfocusCallback unfocus; - WKPageRunJavaScriptAlertCallback runJavaScriptAlert; - WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; - WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt; WKPageSetStatusTextCallback setStatusText; WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; @@ -125,7 +155,7 @@ typedef struct WKPageUIClientV0 { WKPageSetIsResizableCallback setIsResizable; WKPageGetWindowFrameCallback getWindowFrame; WKPageSetWindowFrameCallback setWindowFrame; - WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; WKPageUIClientCallback didDraw; WKPageUIClientCallback pageDidScroll; WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; @@ -139,7 +169,7 @@ typedef struct WKPageUIClientV0 { WKPageUIClientCallback runModal; void* unused1; // Used to be didCompleteRubberBandForMainFrame WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; - WKPageShouldInterruptJavaScriptCallback shouldInterruptJavaScript; + void* shouldInterruptJavaScript_unavailable; } WKPageUIClientV0; typedef struct WKPageUIClientV1 { @@ -152,9 +182,9 @@ typedef struct WKPageUIClientV1 { WKPageTakeFocusCallback takeFocus; WKPageFocusCallback focus; WKPageUnfocusCallback unfocus; - WKPageRunJavaScriptAlertCallback runJavaScriptAlert; - WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; - WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt; WKPageSetStatusTextCallback setStatusText; WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; @@ -170,7 +200,7 @@ typedef struct WKPageUIClientV1 { WKPageSetIsResizableCallback setIsResizable; WKPageGetWindowFrameCallback getWindowFrame; WKPageSetWindowFrameCallback setWindowFrame; - WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; WKPageUIClientCallback didDraw; WKPageUIClientCallback pageDidScroll; WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; @@ -184,10 +214,10 @@ typedef struct WKPageUIClientV1 { WKPageUIClientCallback runModal; void* unused1; // Used to be didCompleteRubberBandForMainFrame WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; - WKPageShouldInterruptJavaScriptCallback shouldInterruptJavaScript; + void* shouldInterruptJavaScript_unavailable; // Version 1. - WKPageCreateNewPageCallback createNewPage; + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; @@ -203,9 +233,342 @@ typedef struct WKPageUIClientV2 { WKPageTakeFocusCallback takeFocus; WKPageFocusCallback focus; WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; +} WKPageUIClientV2; + +typedef struct WKPageUIClientV3 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; +} WKPageUIClientV3; + +typedef struct WKPageUIClientV4 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame. + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; +} WKPageUIClientV4; + +typedef struct WKPageUIClientV5 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; + + // Version 5. + WKPageDecidePolicyForUserMediaPermissionRequestCallback decidePolicyForUserMediaPermissionRequest; + WKPageDidClickAutoFillButtonCallback didClickAutoFillButton; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt; + WKPageMediaSessionMetadataDidChangeCallback mediaSessionMetadataDidChange; +} WKPageUIClientV5; + +typedef struct WKPageUIClientV6 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage_deprecatedForUseWithV1; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; + + // Version 5. + WKPageDecidePolicyForUserMediaPermissionRequestCallback decidePolicyForUserMediaPermissionRequest; + WKPageDidClickAutoFillButtonCallback didClickAutoFillButton; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert_deprecatedForUseWithV5; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm_deprecatedForUseWithV5; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt_deprecatedForUseWithV5; + WKPageMediaSessionMetadataDidChangeCallback mediaSessionMetadataDidChange; + + // Version 6. + WKPageCreateNewPageCallback createNewPage; WKPageRunJavaScriptAlertCallback runJavaScriptAlert; WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKCheckUserMediaPermissionCallback checkUserMediaPermissionForOrigin; +} WKPageUIClientV6; + +typedef struct WKPageUIClientV7 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; WKPageSetStatusTextCallback setStatusText; WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; @@ -221,7 +584,7 @@ typedef struct WKPageUIClientV2 { WKPageSetIsResizableCallback setIsResizable; WKPageGetWindowFrameCallback getWindowFrame; WKPageSetWindowFrameCallback setWindowFrame; - WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel_deprecatedForUseWithV6; WKPageUIClientCallback didDraw; WKPageUIClientCallback pageDidScroll; WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; @@ -235,10 +598,10 @@ typedef struct WKPageUIClientV2 { WKPageUIClientCallback runModal; void* unused1; // Used to be didCompleteRubberBandForMainFrame WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; - WKPageShouldInterruptJavaScriptCallback shouldInterruptJavaScript; + void* shouldInterruptJavaScript_unavailable; // Version 1. - WKPageCreateNewPageCallback createNewPage; + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage_deprecatedForUseWithV1; WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; @@ -247,13 +610,39 @@ typedef struct WKPageUIClientV2 { WKPageShowColorPickerCallback showColorPicker; WKPageHideColorPickerCallback hideColorPicker; WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; -} WKPageUIClientV2; -enum { kWKPageUIClientCurrentVersion WK_ENUM_DEPRECATED("Use an explicit version number instead") = 2 }; -typedef struct WKPageUIClient { - int version; - const void * clientInfo; + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; + + // Version 5. + WKPageDecidePolicyForUserMediaPermissionRequestCallback decidePolicyForUserMediaPermissionRequest; + WKPageDidClickAutoFillButtonCallback didClickAutoFillButton; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert_deprecatedForUseWithV5; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm_deprecatedForUseWithV5; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt_deprecatedForUseWithV5; + WKPageMediaSessionMetadataDidChangeCallback mediaSessionMetadataDidChange; + + // Version 6. + WKPageCreateNewPageCallback createNewPage; + WKPageRunJavaScriptAlertCallback runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKCheckUserMediaPermissionCallback checkUserMediaPermissionForOrigin; + + // Version 7. + WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKFullscreenMayReturnToInlineCallback fullscreenMayReturnToInline; +} WKPageUIClientV7; +typedef struct WKPageUIClientV8 { + WKPageUIClientBase base; + // Version 0. WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; WKPageUIClientCallback showPage; @@ -261,9 +650,97 @@ typedef struct WKPageUIClient { WKPageTakeFocusCallback takeFocus; WKPageFocusCallback focus; WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; + WKPageSetStatusTextCallback setStatusText; + WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; + WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; + WKPageDidNotHandleKeyEventCallback didNotHandleKeyEvent; + WKPageDidNotHandleWheelEventCallback didNotHandleWheelEvent; + WKPageGetToolbarsAreVisibleCallback toolbarsAreVisible; + WKPageSetToolbarsAreVisibleCallback setToolbarsAreVisible; + WKPageGetMenuBarIsVisibleCallback menuBarIsVisible; + WKPageSetMenuBarIsVisibleCallback setMenuBarIsVisible; + WKPageGetStatusBarIsVisibleCallback statusBarIsVisible; + WKPageSetStatusBarIsVisibleCallback setStatusBarIsVisible; + WKPageGetIsResizableCallback isResizable; + WKPageSetIsResizableCallback setIsResizable; + WKPageGetWindowFrameCallback getWindowFrame; + WKPageSetWindowFrameCallback setWindowFrame; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel_deprecatedForUseWithV6; + WKPageUIClientCallback didDraw; + WKPageUIClientCallback pageDidScroll; + WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; + WKPageRunOpenPanelCallback runOpenPanel; + WKPageDecidePolicyForGeolocationPermissionRequestCallback decidePolicyForGeolocationPermissionRequest; + WKPageHeaderHeightCallback headerHeight; + WKPageFooterHeightCallback footerHeight; + WKPageDrawHeaderCallback drawHeader; + WKPageDrawFooterCallback drawFooter; + WKPagePrintFrameCallback printFrame; + WKPageUIClientCallback runModal; + void* unused1; // Used to be didCompleteRubberBandForMainFrame + WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; + void* shouldInterruptJavaScript_unavailable; + + // Version 1. + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage_deprecatedForUseWithV1; + WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; + WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; + WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; + + // Version 2. + WKPageShowColorPickerCallback showColorPicker; + WKPageHideColorPickerCallback hideColorPicker; + WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; + + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; + + // Version 5. + WKPageDecidePolicyForUserMediaPermissionRequestCallback decidePolicyForUserMediaPermissionRequest; + WKPageDidClickAutoFillButtonCallback didClickAutoFillButton; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert_deprecatedForUseWithV5; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm_deprecatedForUseWithV5; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt_deprecatedForUseWithV5; + WKPageMediaSessionMetadataDidChangeCallback mediaSessionMetadataDidChange; + + // Version 6. + WKPageCreateNewPageCallback createNewPage; WKPageRunJavaScriptAlertCallback runJavaScriptAlert; WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKCheckUserMediaPermissionCallback checkUserMediaPermissionForOrigin; + + // Version 7. + WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKFullscreenMayReturnToInlineCallback fullscreenMayReturnToInline; + + // Version 8. + WKRequestPointerLockCallback requestPointerLock; + WKDidLosePointerLockCallback didLosePointerLock; +} WKPageUIClientV8; + +typedef struct WKPageUIClientV9 { + WKPageUIClientBase base; + + // Version 0. + WKPageCreateNewPageCallback_deprecatedForUseWithV0 createNewPage_deprecatedForUseWithV0; + WKPageUIClientCallback showPage; + WKPageUIClientCallback close; + WKPageTakeFocusCallback takeFocus; + WKPageFocusCallback focus; + WKPageUnfocusCallback unfocus; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0 runJavaScriptAlert_deprecatedForUseWithV0; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0 runJavaScriptConfirm_deprecatedForUseWithV0; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0 runJavaScriptPrompt_deprecatedForUseWithV0; WKPageSetStatusTextCallback setStatusText; WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0 mouseDidMoveOverElement_deprecatedForUseWithV0; WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0 missingPluginButtonClicked_deprecatedForUseWithV0; @@ -279,7 +756,7 @@ typedef struct WKPageUIClient { WKPageSetIsResizableCallback setIsResizable; WKPageGetWindowFrameCallback getWindowFrame; WKPageSetWindowFrameCallback setWindowFrame; - WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6 runBeforeUnloadConfirmPanel_deprecatedForUseWithV6; WKPageUIClientCallback didDraw; WKPageUIClientCallback pageDidScroll; WKPageExceededDatabaseQuotaCallback exceededDatabaseQuota; @@ -293,10 +770,10 @@ typedef struct WKPageUIClient { WKPageUIClientCallback runModal; void* unused1; // Used to be didCompleteRubberBandForMainFrame WKPageSaveDataToFileInDownloadsFolderCallback saveDataToFileInDownloadsFolder; - WKPageShouldInterruptJavaScriptCallback shouldInterruptJavaScript; + void* shouldInterruptJavaScript_unavailable; // Version 1. - WKPageCreateNewPageCallback createNewPage; + WKPageCreateNewPageCallback_deprecatedForUseWithV1 createNewPage_deprecatedForUseWithV1; WKPageMouseDidMoveOverElementCallback mouseDidMoveOverElement; WKPageDecidePolicyForNotificationPermissionRequestCallback decidePolicyForNotificationPermissionRequest; WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1; @@ -305,8 +782,43 @@ typedef struct WKPageUIClient { WKPageShowColorPickerCallback showColorPicker; WKPageHideColorPickerCallback hideColorPicker; WKPageUnavailablePluginButtonClickedCallback unavailablePluginButtonClicked; -} WKPageUIClient WK_DEPRECATED("Use an explicit versioned struct instead"); + // Version 3. + WKPagePinnedStateDidChangeCallback pinnedStateDidChange; + + // Version 4. + void* unused2; // Used to be didBeginTrackingPotentialLongMousePress. + void* unused3; // Used to be didRecognizeLongMousePress. + void* unused4; // Used to be didCancelTrackingPotentialLongMousePress. + WKPageIsPlayingAudioDidChangeCallback isPlayingAudioDidChange; + + // Version 5. + WKPageDecidePolicyForUserMediaPermissionRequestCallback decidePolicyForUserMediaPermissionRequest; + WKPageDidClickAutoFillButtonCallback didClickAutoFillButton; + WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5 runJavaScriptAlert_deprecatedForUseWithV5; + WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5 runJavaScriptConfirm_deprecatedForUseWithV5; + WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5 runJavaScriptPrompt_deprecatedForUseWithV5; + WKPageMediaSessionMetadataDidChangeCallback mediaSessionMetadataDidChange; + + // Version 6. + WKPageCreateNewPageCallback createNewPage; + WKPageRunJavaScriptAlertCallback runJavaScriptAlert; + WKPageRunJavaScriptConfirmCallback runJavaScriptConfirm; + WKPageRunJavaScriptPromptCallback runJavaScriptPrompt; + WKCheckUserMediaPermissionCallback checkUserMediaPermissionForOrigin; + + // Version 7. + WKPageRunBeforeUnloadConfirmPanelCallback runBeforeUnloadConfirmPanel; + WKFullscreenMayReturnToInlineCallback fullscreenMayReturnToInline; + + // Version 8. + WKRequestPointerLockCallback requestPointerLock; + WKDidLosePointerLockCallback didLosePointerLock; + + // Version 9. + WKDidPlayMediaPreventedFromPlayingWithoutUserGesture didPlayMediaPreventedFromPlayingWithoutUserGesture; +} WKPageUIClientV9; + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPluginLoadPolicy.h b/Source/WebKit2/UIProcess/API/C/WKPluginLoadPolicy.h new file mode 100644 index 000000000..7aaef37ee --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKPluginLoadPolicy.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKPluginLoadPolicy_h +#define WKPluginLoadPolicy_h + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + kWKPluginLoadPolicyLoadNormally = 0, + kWKPluginLoadPolicyBlocked, + kWKPluginLoadPolicyInactive, + kWKPluginLoadPolicyLoadUnsandboxed, + kWKPluginLoadPolicyBlockedForCompatibility, +}; +typedef uint32_t WKPluginLoadPolicy; + +enum { + kWKPluginLoadClientPolicyUndefined = 0, + kWKPluginLoadClientPolicyBlock, + kWKPluginLoadClientPolicyAsk, + kWKPluginLoadClientPolicyAllow, + kWKPluginLoadClientPolicyAllowAlways, +}; +typedef uint32_t WKPluginLoadClientPolicy; + +#ifdef __cplusplus +} +#endif + +#endif /* WKPluginLoadPolicy_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp b/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp deleted file mode 100644 index 5ae8abf9d..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WKPluginSiteDataManager.h" - -#include "APIObject.h" -#include "WKAPICast.h" -#include "WebPluginSiteDataManager.h" - -#if ENABLE(NETSCAPE_PLUGIN_API) -#include <WebCore/npapi.h> -#endif - -using namespace WebKit; - -WKTypeID WKPluginSiteDataManagerGetTypeID() -{ -#if ENABLE(NETSCAPE_PLUGIN_API) - return toAPI(WebPluginSiteDataManager::APIType); -#else - return toAPI(API::Object::Type::Null); -#endif -} - -void WKPluginSiteDataManagerGetSitesWithData(WKPluginSiteDataManagerRef managerRef, void* context, WKPluginSiteDataManagerGetSitesWithDataFunction callback) -{ -#if ENABLE(NETSCAPE_PLUGIN_API) - toImpl(managerRef)->getSitesWithData(ArrayCallback::create(context, callback)); -#else - UNUSED_PARAM(managerRef); - UNUSED_PARAM(context); - UNUSED_PARAM(callback); -#endif -} - -#if ENABLE(NETSCAPE_PLUGIN_API) -static uint64_t toNPClearSiteDataFlags(WKClearSiteDataFlags flags) -{ - if (flags == kWKClearSiteDataFlagsClearAll) - return NP_CLEAR_ALL; - - uint64_t result = 0; - if (flags & kWKClearSiteDataFlagsClearCache) - result |= NP_CLEAR_CACHE; - return result; -} -#endif - -void WKPluginSiteDataManagerClearSiteData(WKPluginSiteDataManagerRef managerRef, WKArrayRef sitesRef, WKClearSiteDataFlags flags, uint64_t maxAgeInSeconds, void* context, WKPluginSiteDataManagerClearSiteDataFunction function) -{ -#if ENABLE(NETSCAPE_PLUGIN_API) - toImpl(managerRef)->clearSiteData(toImpl(sitesRef), toNPClearSiteDataFlags(flags), maxAgeInSeconds, VoidCallback::create(context, function)); -#else - UNUSED_PARAM(managerRef); - UNUSED_PARAM(sitesRef); - UNUSED_PARAM(flags); - UNUSED_PARAM(maxAgeInSeconds); - UNUSED_PARAM(context); - UNUSED_PARAM(function); -#endif -} - -void WKPluginSiteDataManagerClearAllSiteData(WKPluginSiteDataManagerRef managerRef, void* context, WKPluginSiteDataManagerClearSiteDataFunction function) -{ -#if ENABLE(NETSCAPE_PLUGIN_API) - toImpl(managerRef)->clearSiteData(0, NP_CLEAR_ALL, std::numeric_limits<uint64_t>::max(), VoidCallback::create(context, function)); -#else - UNUSED_PARAM(managerRef); - UNUSED_PARAM(context); - UNUSED_PARAM(function); -#endif -} diff --git a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.h b/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.h deleted file mode 100644 index 66e76fbcd..000000000 --- a/Source/WebKit2/UIProcess/API/C/WKPluginSiteDataManager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKPluginSiteDataManager_h -#define WKPluginSiteDataManager_h - -#include <WebKit2/WKBase.h> - -#ifdef __cplusplus -extern "C" { -#endif - -WK_EXPORT WKTypeID WKPluginSiteDataManagerGetTypeID(); - -typedef void (*WKPluginSiteDataManagerGetSitesWithDataFunction)(WKArrayRef, WKErrorRef, void*); -WK_EXPORT void WKPluginSiteDataManagerGetSitesWithData(WKPluginSiteDataManagerRef manager, void* context, WKPluginSiteDataManagerGetSitesWithDataFunction function); - -enum { - kWKClearSiteDataFlagsClearAll = 0, - kWKClearSiteDataFlagsClearCache = 1 << 0, -}; -typedef uint64_t WKClearSiteDataFlags; - -typedef void (*WKPluginSiteDataManagerClearSiteDataFunction)(WKErrorRef, void*); - -WK_EXPORT void WKPluginSiteDataManagerClearSiteData(WKPluginSiteDataManagerRef manager, WKArrayRef sites, WKClearSiteDataFlags flags, uint64_t maxAgeInSeconds, void* context, WKPluginSiteDataManagerClearSiteDataFunction function); -WK_EXPORT void WKPluginSiteDataManagerClearAllSiteData(WKPluginSiteDataManagerRef manager, void* context, WKPluginSiteDataManagerClearSiteDataFunction function); - -#ifdef __cplusplus -} -#endif - -#endif // WKPluginSiteDataManager_h diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp index d81dd2ba5..0d7090e3d 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,14 +24,12 @@ */ #include "config.h" -#include "WKPreferencesPrivate.h" -#include "WKPreferencesRef.h" +#include "WKPreferencesRef.h" +#include "WKPreferencesRefPrivate.h" #include "WKAPICast.h" -#include "WebContext.h" #include "WebPreferences.h" #include <WebCore/Settings.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> using namespace WebKit; @@ -43,20 +41,25 @@ WKTypeID WKPreferencesGetTypeID() WKPreferencesRef WKPreferencesCreate() { - RefPtr<WebPreferences> preferences = WebPreferences::create(); - return toAPI(preferences.release().leakRef()); + auto preferences = WebPreferences::createWithLegacyDefaults(String(), "WebKit2.", "WebKit2."); + return toAPI(preferences.leakRef()); } WKPreferencesRef WKPreferencesCreateWithIdentifier(WKStringRef identifierRef) { - RefPtr<WebPreferences> preferences = WebPreferences::create(toWTFString(identifierRef)); - return toAPI(preferences.release().leakRef()); + auto preferences = WebPreferences::createWithLegacyDefaults(toWTFString(identifierRef), "WebKit2.", "WebKit2."); + return toAPI(preferences.leakRef()); } WKPreferencesRef WKPreferencesCreateCopy(WKPreferencesRef preferencesRef) { - RefPtr<WebPreferences> preferences = WebPreferences::create(*toImpl(preferencesRef)); - return toAPI(preferences.release().leakRef()); + auto preferences = toImpl(preferencesRef)->copy(); + return toAPI(preferences.leakRef()); +} + +void WKPreferencesEnableAllExperimentalFeatures(WKPreferencesRef preferencesRef) +{ + toImpl(preferencesRef)->enableAllExperimentalFeatures(); } void WKPreferencesSetJavaScriptEnabled(WKPreferencesRef preferencesRef, bool javaScriptEnabled) @@ -299,15 +302,6 @@ uint32_t WKPreferencesGetMinimumFontSize(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->minimumFontSize(); } -void WKPreferencesSetScreenFontSubstitutionEnabled(WKPreferencesRef preferencesRef, bool enabled) -{ - toImpl(preferencesRef)->setScreenFontSubstitutionEnabled(enabled); -} - -bool WKPreferencesGetScreenFontSubstitutionEnabled(WKPreferencesRef preferencesRef) -{ - return toImpl(preferencesRef)->screenFontSubstitutionEnabled(); -} void WKPreferencesSetCookieEnabled(WKPreferencesRef preferencesRef, bool enabled) { @@ -359,14 +353,14 @@ bool WKPreferencesGetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->developerExtrasEnabled(); } -void WKPreferencesSetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef, bool enabled) +void WKPreferencesSetJavaScriptRuntimeFlags(WKPreferencesRef preferencesRef, WKJavaScriptRuntimeFlagSet javaScriptRuntimeFlagSet) { - toImpl(preferencesRef)->setJavaScriptExperimentsEnabled(enabled); + toImpl(preferencesRef)->setJavaScriptRuntimeFlags(javaScriptRuntimeFlagSet); } -bool WKPreferencesGetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef) +WKJavaScriptRuntimeFlagSet WKPreferencesGetJavaScriptRuntimeFlags(WKPreferencesRef preferencesRef) { - return toImpl(preferencesRef)->javaScriptExperimentsEnabled(); + return toImpl(preferencesRef)->javaScriptRuntimeFlags(); } void WKPreferencesSetTextAreasAreResizable(WKPreferencesRef preferencesRef, bool resizable) @@ -469,16 +463,6 @@ bool WKPreferencesGetWebGLEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->webGLEnabled(); } -void WKPreferencesSetMultithreadedWebGLEnabled(WKPreferencesRef preferencesRef, bool flag) -{ - toImpl(preferencesRef)->setMultithreadedWebGLEnabled(flag); -} - -bool WKPreferencesGetMultithreadedWebGLEnabled(WKPreferencesRef preferencesRef) -{ - return toImpl(preferencesRef)->multithreadedWebGLEnabled(); -} - void WKPreferencesSetForceSoftwareWebGLRendering(WKPreferencesRef preferencesRef, bool flag) { toImpl(preferencesRef)->setForceSoftwareWebGLRendering(flag); @@ -499,34 +483,24 @@ bool WKPreferencesGetAccelerated2DCanvasEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->accelerated2dCanvasEnabled(); } -void WKPreferencesSetCSSRegionsEnabled(WKPreferencesRef preferencesRef, bool flag) -{ - toImpl(preferencesRef)->setCSSRegionsEnabled(flag); -} - -bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef preferencesRef) +void WKPreferencesSetCSSAnimationTriggersEnabled(WKPreferencesRef preferencesRef, bool flag) { - return toImpl(preferencesRef)->cssRegionsEnabled(); + toImpl(preferencesRef)->setCSSAnimationTriggersEnabled(flag); } -void WKPreferencesSetCSSGridLayoutEnabled(WKPreferencesRef preferencesRef, bool flag) +bool WKPreferencesGetCSSAnimationTriggersEnabled(WKPreferencesRef preferencesRef) { - toImpl(preferencesRef)->setCSSGridLayoutEnabled(flag); + return toImpl(preferencesRef)->cssAnimationTriggersEnabled(); } -bool WKPreferencesGetCSSGridLayoutEnabled(WKPreferencesRef preferencesRef) +void WKPreferencesSetWebAnimationsEnabled(WKPreferencesRef preferencesRef, bool flag) { - return toImpl(preferencesRef)->cssGridLayoutEnabled(); + toImpl(preferencesRef)->setWebAnimationsEnabled(flag); } -void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef preferencesRef, bool flag) +bool WKPreferencesGetWebAnimationsEnabled(WKPreferencesRef preferencesRef) { - toImpl(preferencesRef)->setRegionBasedColumnsEnabled(flag); -} - -bool WKPreferencesGetRegionBasedColumnsEnabled(WKPreferencesRef preferencesRef) -{ - return toImpl(preferencesRef)->regionBasedColumnsEnabled(); + return toImpl(preferencesRef)->webAnimationsEnabled(); } void WKPreferencesSetNeedsSiteSpecificQuirks(WKPreferencesRef preferencesRef, bool flag) @@ -609,6 +583,16 @@ bool WKPreferencesGetShouldPrintBackgrounds(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->shouldPrintBackgrounds(); } +void WKPreferencesSetDOMTimersThrottlingEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setDOMTimersThrottlingEnabled(enabled); +} + +bool WKPreferencesGetDOMTimersThrottlingEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->domTimersThrottlingEnabled(); +} + void WKPreferencesSetWebArchiveDebugModeEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setWebArchiveDebugModeEnabled(enabled); @@ -709,6 +693,16 @@ bool WKPreferencesGetAVFoundationEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->isAVFoundationEnabled(); } +void WKPreferencesSetAVFoundationNSURLSessionEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setAVFoundationNSURLSessionEnabled(enabled); +} + +bool WKPreferencesGetAVFoundationNSURLSessionEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->isAVFoundationNSURLSessionEnabled(); +} + void WKPreferencesSetWebSecurityEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setWebSecurityEnabled(enabled); @@ -739,6 +733,16 @@ bool WKPreferencesGetFileAccessFromFileURLsAllowed(WKPreferencesRef preferencesR return toImpl(preferencesRef)->allowFileAccessFromFileURLs(); } +void WKPreferencesSetNeedsStorageAccessFromFileURLsQuirk(WKPreferencesRef preferencesRef, bool needsQuirk) +{ + toImpl(preferencesRef)->setNeedsStorageAccessFromFileURLsQuirk(needsQuirk); +} + +bool WKPreferencesGetNeedsStorageAccessFromFileURLsQuirk(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->needsStorageAccessFromFileURLsQuirk(); +} + void WKPreferencesSetHixie76WebSocketProtocolEnabled(WKPreferencesRef, bool /*enabled*/) { } @@ -750,22 +754,82 @@ bool WKPreferencesGetHixie76WebSocketProtocolEnabled(WKPreferencesRef) void WKPreferencesSetMediaPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag) { - toImpl(preferencesRef)->setMediaPlaybackRequiresUserGesture(flag); + toImpl(preferencesRef)->setRequiresUserGestureForMediaPlayback(flag); } bool WKPreferencesGetMediaPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef) { - return toImpl(preferencesRef)->mediaPlaybackRequiresUserGesture(); + return toImpl(preferencesRef)->requiresUserGestureForMediaPlayback(); +} + +void WKPreferencesSetVideoPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setRequiresUserGestureForVideoPlayback(flag); +} + +bool WKPreferencesGetVideoPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->requiresUserGestureForVideoPlayback(); +} + +void WKPreferencesSetAudioPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setRequiresUserGestureForAudioPlayback(flag); +} + +bool WKPreferencesGetAudioPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->requiresUserGestureForAudioPlayback(); +} + +void WKPreferencesSetMainContentUserGestureOverrideEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setMainContentUserGestureOverrideEnabled(flag); +} + +bool WKPreferencesGetMainContentUserGestureOverrideEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->mainContentUserGestureOverrideEnabled(); } void WKPreferencesSetMediaPlaybackAllowsInline(WKPreferencesRef preferencesRef, bool flag) { - toImpl(preferencesRef)->setMediaPlaybackAllowsInline(flag); + toImpl(preferencesRef)->setAllowsInlineMediaPlayback(flag); } bool WKPreferencesGetMediaPlaybackAllowsInline(WKPreferencesRef preferencesRef) { - return toImpl(preferencesRef)->mediaPlaybackAllowsInline(); + return toImpl(preferencesRef)->allowsInlineMediaPlayback(); +} + +void WKPreferencesSetInlineMediaPlaybackRequiresPlaysInlineAttribute(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setInlineMediaPlaybackRequiresPlaysInlineAttribute(flag); +} + +bool WKPreferencesGetInlineMediaPlaybackRequiresPlaysInlineAttribute(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->inlineMediaPlaybackRequiresPlaysInlineAttribute(); +} + +void WKPreferencesSetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setMediaControlsScaleWithPageZoom(flag); +} + +bool WKPreferencesGetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->mediaControlsScaleWithPageZoom(); +} + +void WKPreferencesSetModernMediaControlsEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setModernMediaControlsEnabled(flag); +} + +bool WKPreferencesGetModernMediaControlsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->modernMediaControlsEnabled(); } void WKPreferencesSetShowsToolTipOverTruncatedText(WKPreferencesRef preferencesRef, bool flag) @@ -798,14 +862,15 @@ bool WKPreferencesGetWebAudioEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->webAudioEnabled(); } -void WKPreferencesSetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef, bool enabled) +void WKPreferencesSetApplicationChromeModeEnabled(WKPreferencesRef, bool) { - toImpl(preferencesRef)->setApplicationChromeModeEnabled(enabled); + // FIXME: Remove once WebKit nightlies don't need to support Safari 8. } -bool WKPreferencesGetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef) +bool WKPreferencesGetApplicationChromeModeEnabled(WKPreferencesRef) { - return toImpl(preferencesRef)->applicationChromeMode(); + // FIXME: Remove once WebKit nightlies don't need to support Safari 8. + return false; } void WKPreferencesSetInspectorUsesWebKitUserInterface(WKPreferencesRef, bool) @@ -1141,11 +1206,21 @@ void WKPreferencesSetHiddenPageDOMTimerThrottlingEnabled(WKPreferencesRef prefer toImpl(preferencesRef)->setHiddenPageDOMTimerThrottlingEnabled(enabled); } +void WKPreferencesSetHiddenPageDOMTimerThrottlingAutoIncreases(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setHiddenPageDOMTimerThrottlingAutoIncreases(enabled); +} + bool WKPreferencesGetHiddenPageDOMTimerThrottlingEnabled(WKPreferencesRef preferencesRef) { return toImpl(preferencesRef)->hiddenPageDOMTimerThrottlingEnabled(); } +bool WKPreferencesGetHiddenPageDOMTimerThrottlingAutoIncreases(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->hiddenPageDOMTimerThrottlingAutoIncreases(); +} + void WKPreferencesSetHiddenPageCSSAnimationSuspensionEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setHiddenPageCSSAnimationSuspensionEnabled(enabled); @@ -1196,6 +1271,46 @@ bool WKPreferencesGetSimpleLineLayoutDebugBordersEnabled(WKPreferencesRef prefer return toImpl(preferencesRef)->simpleLineLayoutDebugBordersEnabled(); } +void WKPreferencesSetNewBlockInsideInlineModelEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setNewBlockInsideInlineModelEnabled(flag); +} + +bool WKPreferencesGetNewBlockInsideInlineModelEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->newBlockInsideInlineModelEnabled(); +} + +void WKPreferencesSetDeferredCSSParserEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setDeferredCSSParserEnabled(flag); +} + +bool WKPreferencesGetDeferredCSSParserEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->deferredCSSParserEnabled(); +} + +void WKPreferencesSetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setSubpixelCSSOMElementMetricsEnabled(flag); +} + +bool WKPreferencesGetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->subpixelCSSOMElementMetricsEnabled(); +} + +void WKPreferencesSetUseGiantTiles(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setUseGiantTiles(flag); +} + +bool WKPreferencesGetUseGiantTiles(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->useGiantTiles(); +} + void WKPreferencesSetMediaStreamEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setMediaStreamEnabled(enabled); @@ -1206,14 +1321,14 @@ bool WKPreferencesGetMediaStreamEnabled(WKPreferencesRef preferencesRef) return toImpl(preferencesRef)->mediaStreamEnabled(); } -void WKPreferencesSetVideoPluginProxyEnabled(WKPreferencesRef preferencesRef, bool enabled) +void WKPreferencesSetPeerConnectionEnabled(WKPreferencesRef preferencesRef, bool enabled) { - toImpl(preferencesRef)->setVideoPluginProxyEnabled(enabled); + toImpl(preferencesRef)->setPeerConnectionEnabled(enabled); } -bool WKPreferencesGetVideoPluginProxyEnabled(WKPreferencesRef preferencesRef) +bool WKPreferencesGetPeerConnectionEnabled(WKPreferencesRef preferencesRef) { - return toImpl(preferencesRef)->isVideoPluginProxyEnabled(); + return toImpl(preferencesRef)->peerConnectionEnabled(); } void WKPreferencesSetSpatialNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled) @@ -1245,3 +1360,303 @@ bool WKPreferencesGetViewGestureDebuggingEnabled(WKPreferencesRef preferencesRef { return toImpl(preferencesRef)->viewGestureDebuggingEnabled(); } + +void WKPreferencesSetShouldConvertPositionStyleOnCopy(WKPreferencesRef preferencesRef, bool convert) +{ + toImpl(preferencesRef)->setShouldConvertPositionStyleOnCopy(convert); +} + +bool WKPreferencesGetShouldConvertPositionStyleOnCopy(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->shouldConvertPositionStyleOnCopy(); +} + +void WKPreferencesSetTelephoneNumberParsingEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setTelephoneNumberParsingEnabled(enabled); +} + +bool WKPreferencesGetTelephoneNumberParsingEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->telephoneNumberParsingEnabled(); +} + +void WKPreferencesSetEnableInheritURIQueryComponent(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setEnableInheritURIQueryComponent(enabled); +} + +bool WKPreferencesGetEnableInheritURIQueryComponent(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->enableInheritURIQueryComponent(); +} + +void WKPreferencesSetServiceControlsEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setServiceControlsEnabled(enabled); +} + +bool WKPreferencesGetServiceControlsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->serviceControlsEnabled(); +} + +void WKPreferencesSetImageControlsEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setImageControlsEnabled(enabled); +} + +bool WKPreferencesGetImageControlsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->imageControlsEnabled(); +} + +void WKPreferencesSetGamepadsEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setGamepadsEnabled(enabled); +} + +bool WKPreferencesGetGamepadsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->gamepadsEnabled(); +} + +// FIXME: Remove these when possible. +void WKPreferencesSetLongMousePressEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ +} + +bool WKPreferencesGetLongMousePressEnabled(WKPreferencesRef preferencesRef) +{ + return false; +} + +void WKPreferencesSetMinimumZoomFontSize(WKPreferencesRef preferencesRef, double size) +{ + toImpl(preferencesRef)->setMinimumZoomFontSize(size); +} + +double WKPreferencesGetMinimumZoomFontSize(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->minimumZoomFontSize(); +} + +void WKPreferencesSetAntialiasedFontDilationEnabled(WKPreferencesRef, bool) +{ + // Feature removed. +} + +bool WKPreferencesGetAntialiasedFontDilationEnabled(WKPreferencesRef) +{ + return false; // Feature removed. +} + +void WKPreferencesSetVisibleDebugOverlayRegions(WKPreferencesRef preferencesRef, WKDebugOverlayRegions visibleRegions) +{ + toImpl(preferencesRef)->setVisibleDebugOverlayRegions(visibleRegions); +} + +WKDebugOverlayRegions WKPreferencesGetVisibleDebugOverlayRegions(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->visibleDebugOverlayRegions(); +} + +void WKPreferencesSetIgnoreViewportScalingConstraints(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setIgnoreViewportScalingConstraints(enabled); +} + +bool WKPreferencesGetIgnoreViewportScalingConstraints(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->ignoreViewportScalingConstraints(); +} + +void WKPreferencesSetMetaRefreshEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setHTTPEquivEnabled(enabled); +} + +bool WKPreferencesGetMetaRefreshEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->httpEquivEnabled(); +} + +void WKPreferencesSetHTTPEquivEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setHTTPEquivEnabled(enabled); +} + +bool WKPreferencesGetHTTPEquivEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->httpEquivEnabled(); +} + +void WKPreferencesSetAllowsAirPlayForMediaPlayback(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setAllowsAirPlayForMediaPlayback(enabled); +} + +bool WKPreferencesGetAllowsAirPlayForMediaPlayback(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->allowsAirPlayForMediaPlayback(); +} + +void WKPreferencesSetUserInterfaceDirectionPolicy(WKPreferencesRef preferencesRef, _WKUserInterfaceDirectionPolicy userInterfaceDirectionPolicy) +{ + toImpl(preferencesRef)->setUserInterfaceDirectionPolicy(userInterfaceDirectionPolicy); +} + +_WKUserInterfaceDirectionPolicy WKPreferencesGetUserInterfaceDirectionPolicy(WKPreferencesRef preferencesRef) +{ + return static_cast<_WKUserInterfaceDirectionPolicy>(toImpl(preferencesRef)->userInterfaceDirectionPolicy()); +} + +void WKPreferencesSetResourceUsageOverlayVisible(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setResourceUsageOverlayVisible(enabled); +} + +bool WKPreferencesGetResourceUsageOverlayVisible(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->resourceUsageOverlayVisible(); +} + +void WKPreferencesSetMockCaptureDevicesEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setMockCaptureDevicesEnabled(enabled); +} + +bool WKPreferencesGetMockCaptureDevicesEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->mockCaptureDevicesEnabled(); +} + +void WKPreferencesSetMediaCaptureRequiresSecureConnection(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setMediaCaptureRequiresSecureConnection(enabled); +} + +bool WKPreferencesGetMediaCaptureRequiresSecureConnection(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->mediaCaptureRequiresSecureConnection(); +} + +void WKPreferencesSetFetchAPIEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setFetchAPIEnabled(flag); +} + +bool WKPreferencesGetFetchAPIEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->fetchAPIEnabled(); +} + +void WKPreferencesSetDownloadAttributeEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setDownloadAttributeEnabled(flag); +} + +bool WKPreferencesGetDownloadAttributeEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->downloadAttributeEnabled(); +} + +void WKPreferencesSetIntersectionObserverEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setIntersectionObserverEnabled(flag); +} + +bool WKPreferencesGetIntersectionObserverEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->intersectionObserverEnabled(); +} + +void WKPreferencesSetUserTimingEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setUserTimingEnabled(flag); +} + +bool WKPreferencesGetUserTimingEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->userTimingEnabled(); +} + +void WKPreferencesSetResourceTimingEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setResourceTimingEnabled(flag); +} + +bool WKPreferencesGetResourceTimingEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->resourceTimingEnabled(); +} + +void WKPreferencesSetSelectionPaintingWithoutSelectionGapsEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setSelectionPaintingWithoutSelectionGapsEnabled(flag); +} + +bool WKPreferencesGetSelectionPaintingWithoutSelectionGapsEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->selectionPaintingWithoutSelectionGapsEnabled(); +} + +void WKPreferencesSetAllowsPictureInPictureMediaPlayback(WKPreferencesRef preferencesRef, bool enabled) +{ + toImpl(preferencesRef)->setAllowsPictureInPictureMediaPlayback(enabled); +} + +bool WKPreferencesGetAllowsPictureInPictureMediaPlayback(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->allowsPictureInPictureMediaPlayback(); +} + +WK_EXPORT bool WKPreferencesGetApplePayEnabled(WKPreferencesRef preferencesRef) +{ + return WebKit::toImpl(preferencesRef)->applePayEnabled(); +} + +void WKPreferencesSetApplePayEnabled(WKPreferencesRef preferencesRef, bool enabled) +{ + WebKit::toImpl(preferencesRef)->setApplePayEnabled(enabled); +} + +bool WKPreferencesGetApplePayCapabilityDisclosureAllowed(WKPreferencesRef preferencesRef) +{ + return WebKit::toImpl(preferencesRef)->applePayCapabilityDisclosureAllowed(); +} + +void WKPreferencesSetApplePayCapabilityDisclosureAllowed(WKPreferencesRef preferencesRef, bool allowed) +{ + WebKit::toImpl(preferencesRef)->setApplePayCapabilityDisclosureAllowed(allowed); +} + +void WKPreferencesSetSubtleCryptoEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setSubtleCryptoEnabled(flag); +} + +bool WKPreferencesGetSubtleCryptoEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->subtleCryptoEnabled(); +} + +void WKPreferencesSetLinkPreloadEnabled(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setLinkPreloadEnabled(flag); +} + +bool WKPreferencesGetLinkPreloadEnabled(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->linkPreloadEnabled(); +} + +void WKPreferencesSetShouldSuppressKeyboardInputDuringProvisionalNavigation(WKPreferencesRef preferencesRef, bool flag) +{ + toImpl(preferencesRef)->setShouldSuppressKeyboardInputDuringProvisionalNavigation(flag); +} + +bool WKPreferencesGetShouldSuppressKeyboardInputDuringProvisionalNavigation(WKPreferencesRef preferencesRef) +{ + return toImpl(preferencesRef)->shouldSuppressKeyboardInputDuringProvisionalNavigation(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferencesRef.h b/Source/WebKit2/UIProcess/API/C/WKPreferencesRef.h index a4a7c9b1a..bc5d70b01 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferencesRef.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferencesRef.h @@ -26,7 +26,7 @@ #ifndef WKPreferencesRef_h #define WKPreferencesRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifndef __cplusplus #include <stdbool.h> @@ -43,6 +43,18 @@ enum WKStorageBlockingPolicy { }; typedef enum WKStorageBlockingPolicy WKStorageBlockingPolicy; +enum WKDebugOverlayRegionFlags { + kWKNonFastScrollableRegion = 1 << 0, + kWKWheelEventHandlerRegion = 1 << 1 +}; +typedef unsigned WKDebugOverlayRegions; + +enum _WKUserInterfaceDirectionPolicy { + kWKUserInterfaceDirectionPolicyContent, + kWKUserInterfaceDirectionPolicySystem, +}; +typedef enum _WKUserInterfaceDirectionPolicy _WKUserInterfaceDirectionPolicy; + WK_EXPORT WKTypeID WKPreferencesGetTypeID(); WK_EXPORT WKPreferencesRef WKPreferencesCreate(); @@ -64,7 +76,7 @@ WK_EXPORT bool WKPreferencesGetLoadsImagesAutomatically(WKPreferencesRef prefere WK_EXPORT void WKPreferencesSetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferences, bool loadsSiteIconsIgnoringImageLoadingPreference); WK_EXPORT bool WKPreferencesGetLoadsSiteIconsIgnoringImageLoadingPreference(WKPreferencesRef preferences); -// Defaults to false. +// Defaults to true. WK_EXPORT void WKPreferencesSetOfflineWebApplicationCacheEnabled(WKPreferencesRef preferences, bool offlineWebApplicationCacheEnabled); WK_EXPORT bool WKPreferencesGetOfflineWebApplicationCacheEnabled(WKPreferencesRef preferences); @@ -144,10 +156,6 @@ WK_EXPORT bool WKPreferencesGetPrivateBrowsingEnabled(WKPreferencesRef preferenc WK_EXPORT void WKPreferencesSetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetDeveloperExtrasEnabled(WKPreferencesRef preferencesRef); -// Defaults to false. -WK_EXPORT void WKPreferencesSetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef, bool enabled); -WK_EXPORT bool WKPreferencesGetJavaScriptExperimentsEnabled(WKPreferencesRef preferencesRef); - // Defaults to true. WK_EXPORT void WKPreferencesSetTextAreasAreResizable(WKPreferencesRef preferencesRef, bool resizable); WK_EXPORT bool WKPreferencesGetTextAreasAreResizable(WKPreferencesRef preferencesRef); @@ -180,6 +188,10 @@ WK_EXPORT bool WKPreferencesGetFullScreenEnabled(WKPreferencesRef preferencesRef WK_EXPORT void WKPreferencesSetAVFoundationEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetAVFoundationEnabled(WKPreferencesRef preferencesRef); +// Defaults to false. +WK_EXPORT void WKPreferencesSetAVFoundationNSURLSessionEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetAVFoundationNSURLSessionEnabled(WKPreferencesRef preferencesRef); + // Defaults to false WK_EXPORT void WKPreferencesSetWebAudioEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetWebAudioEnabled(WKPreferencesRef preferencesRef); @@ -216,7 +228,7 @@ WK_EXPORT bool WKPreferencesGetNotificationsEnabled(WKPreferencesRef preferences WK_EXPORT void WKPreferencesSetShouldRespectImageOrientation(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetShouldRespectImageOrientation(WKPreferencesRef preferencesRef); -// Defaults to false +// Defaults to kWKAllowAllStorage WK_EXPORT void WKPreferencesSetStorageBlockingPolicy(WKPreferencesRef preferencesRef, WKStorageBlockingPolicy policy); WK_EXPORT WKStorageBlockingPolicy WKPreferencesGetStorageBlockingPolicy(WKPreferencesRef preferencesRef); @@ -244,14 +256,38 @@ WK_EXPORT bool WKPreferencesGetAsynchronousSpellCheckingEnabled(WKPreferencesRef WK_EXPORT void WKPreferencesSetMediaStreamEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetMediaStreamEnabled(WKPreferencesRef preferencesRef); -// Defaults to true. -WK_EXPORT void WKPreferencesSetVideoPluginProxyEnabled(WKPreferencesRef preferencesRef, bool enabled); -WK_EXPORT bool WKPreferencesGetVideoPluginProxyEnabled(WKPreferencesRef preferencesRef); +// Defaults to false +WK_EXPORT void WKPreferencesSetPeerConnectionEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetPeerConnectionEnabled(WKPreferencesRef preferencesRef); // Defaults to false. WK_EXPORT void WKPreferencesSetSpatialNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetSpatialNavigationEnabled(WKPreferencesRef preferencesRef); +// Defaults to 0. +WK_EXPORT void WKPreferencesSetVisibleDebugOverlayRegions(WKPreferencesRef preferencesRef, WKDebugOverlayRegions enabled); +WK_EXPORT WKDebugOverlayRegions WKPreferencesGetVisibleDebugOverlayRegions(WKPreferencesRef preferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetIgnoreViewportScalingConstraints(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetIgnoreViewportScalingConstraints(WKPreferencesRef preferencesRef); + +// Defaults to true. +WK_EXPORT void WKPreferencesSetAllowsAirPlayForMediaPlayback(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetAllowsAirPlayForMediaPlayback(WKPreferencesRef preferencesRef); + +// Defaults to kWKUserInterfaceDirectionPolicyContent. +WK_EXPORT void WKPreferencesSetUserInterfaceDirectionPolicy(WKPreferencesRef preferencesRef, _WKUserInterfaceDirectionPolicy userInterfaceDirectionPolicy); +WK_EXPORT _WKUserInterfaceDirectionPolicy WKPreferencesGetUserInterfaceDirectionPolicy(WKPreferencesRef preferencesRef); + +// Defaults to false. +WK_EXPORT bool WKPreferencesGetApplePayEnabled(WKPreferencesRef preferencesRef); +WK_EXPORT void WKPreferencesSetApplePayEnabled(WKPreferencesRef preferencesRef, bool enabled); + +// Defaults to true. +WK_EXPORT bool WKPreferencesGetApplePayCapabilityDisclosureAllowed(WKPreferencesRef preferencesRef); +WK_EXPORT void WKPreferencesSetApplePayCapabilityDisclosureAllowed(WKPreferencesRef preferencesRef, bool allowed); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h b/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h index 0d80f0499..7c255841a 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferencesPrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,7 +26,7 @@ #ifndef WKPreferencesPrivate_h #define WKPreferencesPrivate_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -49,9 +49,16 @@ enum WKEditableLinkBehavior { }; typedef enum WKEditableLinkBehavior WKEditableLinkBehavior; +enum WKJavaScriptRuntimeFlags { + kWKJavaScriptRuntimeFlagsAllEnabled = 0 +}; +typedef unsigned WKJavaScriptRuntimeFlagSet; + // Creates a copy with no identifier. WK_EXPORT WKPreferencesRef WKPreferencesCreateCopy(WKPreferencesRef); +WK_EXPORT void WKPreferencesEnableAllExperimentalFeatures(WKPreferencesRef); + // Defaults to kWKFontSmoothingLevelMedium. WK_EXPORT void WKPreferencesSetFontSmoothingLevel(WKPreferencesRef, WKFontSmoothingLevel); WK_EXPORT WKFontSmoothingLevel WKPreferencesGetFontSmoothingLevel(WKPreferencesRef); @@ -93,10 +100,6 @@ WK_EXPORT void WKPreferencesSetWebGLEnabled(WKPreferencesRef, bool); WK_EXPORT bool WKPreferencesGetWebGLEnabled(WKPreferencesRef); // Defaults to false. -WK_EXPORT void WKPreferencesSetMultithreadedWebGLEnabled(WKPreferencesRef, bool); -WK_EXPORT bool WKPreferencesGetMultithreadedWebGLEnabled(WKPreferencesRef); - -// Defaults to false. WK_EXPORT void WKPreferencesSetForceSoftwareWebGLRendering(WKPreferencesRef, bool); WK_EXPORT bool WKPreferencesGetForceSoftwareWebGLRendering(WKPreferencesRef); @@ -105,16 +108,12 @@ WK_EXPORT void WKPreferencesSetAccelerated2DCanvasEnabled(WKPreferencesRef, bool WK_EXPORT bool WKPreferencesGetAccelerated2DCanvasEnabled(WKPreferencesRef); // Defaults to true -WK_EXPORT void WKPreferencesSetCSSRegionsEnabled(WKPreferencesRef, bool flag); -WK_EXPORT bool WKPreferencesGetCSSRegionsEnabled(WKPreferencesRef); - -// Defaults to false -WK_EXPORT void WKPreferencesSetCSSGridLayoutEnabled(WKPreferencesRef, bool flag); -WK_EXPORT bool WKPreferencesGetCSSGridLayoutEnabled(WKPreferencesRef); +WK_EXPORT void WKPreferencesSetCSSAnimationTriggersEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetCSSAnimationTriggersEnabled(WKPreferencesRef); // Defaults to false -WK_EXPORT void WKPreferencesSetRegionBasedColumnsEnabled(WKPreferencesRef, bool flag); -WK_EXPORT bool WKPreferencesGetRegionBasedColumnsEnabled(WKPreferencesRef); +WK_EXPORT void WKPreferencesSetWebAnimationsEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetWebAnimationsEnabled(WKPreferencesRef); // Defaults to false. WK_EXPORT void WKPreferencesSetNeedsSiteSpecificQuirks(WKPreferencesRef, bool); @@ -128,6 +127,10 @@ WK_EXPORT bool WKPreferencesGetForceFTPDirectoryListings(WKPreferencesRef prefer WK_EXPORT void WKPreferencesSetFTPDirectoryTemplatePath(WKPreferencesRef preferences, WKStringRef path); WK_EXPORT WKStringRef WKPreferencesCopyFTPDirectoryTemplatePath(WKPreferencesRef preferences); +// Defaults to true. +WK_EXPORT void WKPreferencesSetDOMTimersThrottlingEnabled(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetDOMTimersThrottlingEnabled(WKPreferencesRef preferences); + // Defaults to false. WK_EXPORT void WKPreferencesSetWebArchiveDebugModeEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetWebArchiveDebugModeEnabled(WKPreferencesRef preferences); @@ -164,6 +167,10 @@ WK_EXPORT bool WKPreferencesGetUniversalAccessFromFileURLsAllowed(WKPreferencesR WK_EXPORT void WKPreferencesSetFileAccessFromFileURLsAllowed(WKPreferencesRef preferences, bool allowed); WK_EXPORT bool WKPreferencesGetFileAccessFromFileURLsAllowed(WKPreferencesRef preferences); +// Defaults to true +WK_EXPORT void WKPreferencesSetNeedsStorageAccessFromFileURLsQuirk(WKPreferencesRef preferences, bool needsQuirk); +WK_EXPORT bool WKPreferencesGetNeedsStorageAccessFromFileURLsQuirk(WKPreferencesRef preferences); + // Defaults to true. WK_EXPORT void WKPreferencesSetHixie76WebSocketProtocolEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetHixie76WebSocketProtocolEnabled(WKPreferencesRef preferencesRef); @@ -172,19 +179,43 @@ WK_EXPORT bool WKPreferencesGetHixie76WebSocketProtocolEnabled(WKPreferencesRef WK_EXPORT void WKPreferencesSetMediaPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag); WK_EXPORT bool WKPreferencesGetMediaPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef); +// Defaults to false. +WK_EXPORT void WKPreferencesSetVideoPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetVideoPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetAudioPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetAudioPlaybackRequiresUserGesture(WKPreferencesRef preferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetMainContentUserGestureOverrideEnabled(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetMainContentUserGestureOverrideEnabled(WKPreferencesRef preferencesRef); + // Defaults to true. WK_EXPORT void WKPreferencesSetMediaPlaybackAllowsInline(WKPreferencesRef preferencesRef, bool flag); WK_EXPORT bool WKPreferencesGetMediaPlaybackAllowsInline(WKPreferencesRef preferencesRef); // Defaults to false. +WK_EXPORT void WKPreferencesSetInlineMediaPlaybackRequiresPlaysInlineAttribute(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetInlineMediaPlaybackRequiresPlaysInlineAttribute(WKPreferencesRef preferencesRef); + +// Defaults to false on iOS, true elsewhere. +WK_EXPORT void WKPreferencesSetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetMediaControlsScaleWithPageZoom(WKPreferencesRef preferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetModernMediaControlsEnabled(WKPreferencesRef preferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetModernMediaControlsEnabled(WKPreferencesRef preferencesRef); + +// Defaults to false. WK_EXPORT void WKPreferencesSetShowsToolTipOverTruncatedText(WKPreferencesRef preferencesRef, bool flag); WK_EXPORT bool WKPreferencesGetShowsToolTipOverTruncatedText(WKPreferencesRef preferencesRef); // Defaults to false. WK_EXPORT void WKPreferencesSetMockScrollbarsEnabled(WKPreferencesRef preferencesRef, bool flag); WK_EXPORT bool WKPreferencesGetMockScrollbarsEnabled(WKPreferencesRef preferencesRef); - -// Defaults to false. + +// Deprecated. Always returns false. WK_EXPORT void WKPreferencesSetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetApplicationChromeModeEnabled(WKPreferencesRef preferencesRef); @@ -220,7 +251,7 @@ WK_EXPORT bool WKPreferencesGetArtificialPluginInitializationDelayEnabled(WKPref WK_EXPORT void WKPreferencesSetTabToLinksEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetTabToLinksEnabled(WKPreferencesRef preferencesRef); -// Defaults to false +// Defaults to true WK_EXPORT void WKPreferencesSetInteractiveFormValidationEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetInteractiveFormValidationEnabled(WKPreferencesRef preferencesRef); @@ -229,10 +260,6 @@ WK_EXPORT void WKPreferencesSetScrollingPerformanceLoggingEnabled(WKPreferencesR WK_EXPORT bool WKPreferencesGetScrollingPerformanceLoggingEnabled(WKPreferencesRef preferencesRef); // Defaults to true -WK_EXPORT void WKPreferencesSetScreenFontSubstitutionEnabled(WKPreferencesRef preferences, bool enabled); -WK_EXPORT bool WKPreferencesGetScreenFontSubstitutionEnabled(WKPreferencesRef preferences); - -// Defaults to true WK_EXPORT void WKPreferencesSetCookieEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetCookieEnabled(WKPreferencesRef preferences); @@ -248,7 +275,7 @@ WK_EXPORT bool WKPreferencesGetAggressiveTileRetentionEnabled(WKPreferencesRef p WK_EXPORT void WKPreferencesSetLogsPageMessagesToSystemConsoleEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetLogsPageMessagesToSystemConsoleEnabled(WKPreferencesRef preferences); -// Defaults to false +// Defaults to true WK_EXPORT void WKPreferencesSetPageVisibilityBasedProcessSuppressionEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetPageVisibilityBasedProcessSuppressionEnabled(WKPreferencesRef); @@ -268,6 +295,10 @@ WK_EXPORT bool WKPreferencesGetShowsURLsInToolTipsEnabled(WKPreferencesRef prefe WK_EXPORT void WKPreferencesSetHiddenPageDOMTimerThrottlingEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetHiddenPageDOMTimerThrottlingEnabled(WKPreferencesRef preferences); +// Defaults to false +WK_EXPORT void WKPreferencesSetHiddenPageDOMTimerThrottlingAutoIncreases(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetHiddenPageDOMTimerThrottlingAutoIncreases(WKPreferencesRef preferences); + // Defaults to true on Mac, false on other platforms. WK_EXPORT void WKPreferencesSetHiddenPageCSSAnimationSuspensionEnabled(WKPreferencesRef preferences, bool enabled); WK_EXPORT bool WKPreferencesGetHiddenPageCSSAnimationSuspensionEnabled(WKPreferencesRef preferences); @@ -300,13 +331,29 @@ WK_EXPORT bool WKPreferencesGetSimpleLineLayoutEnabled(WKPreferencesRef); WK_EXPORT void WKPreferencesSetSimpleLineLayoutDebugBordersEnabled(WKPreferencesRef, bool); WK_EXPORT bool WKPreferencesGetSimpleLineLayoutDebugBordersEnabled(WKPreferencesRef); +// Defaults to false. +WK_EXPORT void WKPreferencesSetNewBlockInsideInlineModelEnabled(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetNewBlockInsideInlineModelEnabled(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetDeferredCSSParserEnabled(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetDeferredCSSParserEnabled(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetSubpixelCSSOMElementMetricsEnabled(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetUseGiantTiles(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetUseGiantTiles(WKPreferencesRef); + WK_EXPORT void WKPreferencesResetTestRunnerOverrides(WKPreferencesRef preferencesRef); // Defaults to false. WK_EXPORT void WKPreferencesSetUseLegacyTextAlignPositionedElementBehavior(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesUseLegacyTextAlignPositionedElementBehavior(WKPreferencesRef preferencesRef); -// Defaults to false. +// Defaults to true. WK_EXPORT void WKPreferencesSetMediaSourceEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetMediaSourceEnabled(WKPreferencesRef preferencesRef); @@ -314,6 +361,110 @@ WK_EXPORT bool WKPreferencesGetMediaSourceEnabled(WKPreferencesRef preferencesRe WK_EXPORT void WKPreferencesSetViewGestureDebuggingEnabled(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetViewGestureDebuggingEnabled(WKPreferencesRef preferencesRef); +// Default to false. +WK_EXPORT void WKPreferencesSetShouldConvertPositionStyleOnCopy(WKPreferencesRef preferencesRef, bool convert); +WK_EXPORT bool WKPreferencesGetShouldConvertPositionStyleOnCopy(WKPreferencesRef preferencesRef); + +// Default to false. +WK_EXPORT void WKPreferencesSetTelephoneNumberParsingEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetTelephoneNumberParsingEnabled(WKPreferencesRef preferencesRef); + +// Default to false. +WK_EXPORT void WKPreferencesSetEnableInheritURIQueryComponent(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetEnableInheritURIQueryComponent(WKPreferencesRef preferencesRef); + +// Default to false. +WK_EXPORT void WKPreferencesSetServiceControlsEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetServiceControlsEnabled(WKPreferencesRef preferencesRef); + +// Default to false. +WK_EXPORT void WKPreferencesSetImageControlsEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetImageControlsEnabled(WKPreferencesRef preferencesRef); + +// Default to false. +WK_EXPORT void WKPreferencesSetGamepadsEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetGamepadsEnabled(WKPreferencesRef preferencesRef); + +// Not implemented, should be deleted once there are no callers. +WK_EXPORT void WKPreferencesSetLongMousePressEnabled(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetLongMousePressEnabled(WKPreferencesRef preferencesRef); + +// Defaults to 0. Setting this to 0 disables font autosizing on iOS. +WK_EXPORT void WKPreferencesSetMinimumZoomFontSize(WKPreferencesRef preferencesRef, double); +WK_EXPORT double WKPreferencesGetMinimumZoomFontSize(WKPreferencesRef preferencesRef); + +// Not implemented, should be deleted once Safari no longer uses this function. +WK_EXPORT void WKPreferencesSetScreenFontSubstitutionEnabled(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetScreenFontSubstitutionEnabled(WKPreferencesRef preferences); + +// Not implemented, should be deleted once Safari no longer uses this function. +WK_EXPORT void WKPreferencesSetAntialiasedFontDilationEnabled(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetAntialiasedFontDilationEnabled(WKPreferencesRef preferences); + +// Defaults to 0. +WK_EXPORT void WKPreferencesSetJavaScriptRuntimeFlags(WKPreferencesRef preferences, WKJavaScriptRuntimeFlagSet javascriptRuntimeFlagSet); +WK_EXPORT WKJavaScriptRuntimeFlagSet WKPreferencesGetJavaScriptRuntimeFlags(WKPreferencesRef preferences); + +// Defaults to true. +WK_EXPORT void WKPreferencesSetMetaRefreshEnabled(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetMetaRefreshEnabled(WKPreferencesRef preferences); + +// Defaults to true. +WK_EXPORT void WKPreferencesSetHTTPEquivEnabled(WKPreferencesRef preferences, bool enabled); +WK_EXPORT bool WKPreferencesGetHTTPEquivEnabled(WKPreferencesRef preferences); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetResourceUsageOverlayVisible(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetResourceUsageOverlayVisible(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetMockCaptureDevicesEnabled(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetMockCaptureDevicesEnabled(WKPreferencesRef); + +// Defaults to true. +WK_EXPORT void WKPreferencesSetMediaCaptureRequiresSecureConnection(WKPreferencesRef, bool); +WK_EXPORT bool WKPreferencesGetMediaCaptureRequiresSecureConnection(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetFetchAPIEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetFetchAPIEnabled(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetDownloadAttributeEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetDownloadAttributeEnabled(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetSelectionPaintingWithoutSelectionGapsEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetSelectionPaintingWithoutSelectionGapsEnabled(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetAllowsPictureInPictureMediaPlayback(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetAllowsPictureInPictureMediaPlayback(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetIntersectionObserverEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetIntersectionObserverEnabled(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetUserTimingEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetUserTimingEnabled(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetResourceTimingEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetResourceTimingEnabled(WKPreferencesRef); + +// Defaults to true +WK_EXPORT void WKPreferencesSetSubtleCryptoEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetSubtleCryptoEnabled(WKPreferencesRef); + +// Defaults to false +WK_EXPORT void WKPreferencesSetShouldSuppressKeyboardInputDuringProvisionalNavigation(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetShouldSuppressKeyboardInputDuringProvisionalNavigation(WKPreferencesRef); + +// Defaults to false. +WK_EXPORT void WKPreferencesSetLinkPreloadEnabled(WKPreferencesRef, bool flag); +WK_EXPORT bool WKPreferencesGetLinkPreloadEnabled(WKPreferencesRef); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKProtectionSpace.h b/Source/WebKit2/UIProcess/API/C/WKProtectionSpace.h index c77d93ba0..ff7ca8742 100644 --- a/Source/WebKit2/UIProcess/API/C/WKProtectionSpace.h +++ b/Source/WebKit2/UIProcess/API/C/WKProtectionSpace.h @@ -26,8 +26,8 @@ #ifndef WKProtectionSpace_h #define WKProtectionSpace_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKProtectionSpaceTypes.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKProtectionSpaceTypes.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKProtectionSpaceTypes.h b/Source/WebKit2/UIProcess/API/C/WKProtectionSpaceTypes.h index fd1bd09d2..474146049 100644 --- a/Source/WebKit2/UIProcess/API/C/WKProtectionSpaceTypes.h +++ b/Source/WebKit2/UIProcess/API/C/WKProtectionSpaceTypes.h @@ -26,7 +26,7 @@ #ifndef WKProtectionSpaceTypes_h #define WKProtectionSpaceTypes_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp index a5711e014..c0621d5a8 100644 --- a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.cpp @@ -26,27 +26,68 @@ #include "config.h" #include "WKResourceCacheManager.h" -#include "WebResourceCacheManagerProxy.h" +#include "APIWebsiteDataStore.h" #include "WKAPICast.h" +#include "WebsiteDataRecord.h" using namespace WebKit; WKTypeID WKResourceCacheManagerGetTypeID() { - return toAPI(WebResourceCacheManagerProxy::APIType); + return toAPI(API::WebsiteDataStore::APIType); } -void WKResourceCacheManagerGetCacheOrigins(WKResourceCacheManagerRef cacheManagerRef, void* context, WKResourceCacheManagerGetCacheOriginsFunction callback) +static OptionSet<WebsiteDataType> toWebsiteDataTypes(WKResourceCachesToClear cachesToClear) { - toImpl(cacheManagerRef)->getCacheOrigins(ArrayCallback::create(context, callback)); + OptionSet<WebsiteDataType> websiteDataTypes; + + websiteDataTypes |= WebsiteDataType::MemoryCache; + + if (cachesToClear == WKResourceCachesToClearAll) + websiteDataTypes |= WebsiteDataType::DiskCache; + + return websiteDataTypes; +} + +void WKResourceCacheManagerGetCacheOrigins(WKResourceCacheManagerRef cacheManager, void* context, WKResourceCacheManagerGetCacheOriginsFunction callback) +{ + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(cacheManager))->websiteDataStore(); + websiteDataStore.fetchData(toWebsiteDataTypes(WKResourceCachesToClearAll), { }, [context, callback](auto dataRecords) { + Vector<RefPtr<API::Object>> securityOrigins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + securityOrigins.append(API::SecurityOrigin::create(origin.securityOrigin())); + } + + callback(toAPI(API::Array::create(WTFMove(securityOrigins)).ptr()), nullptr, context); + }); } -void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManagerRef, WKSecurityOriginRef originRef, WKResourceCachesToClear cachesToClear) +void WKResourceCacheManagerClearCacheForOrigin(WKResourceCacheManagerRef cacheManager, WKSecurityOriginRef origin, WKResourceCachesToClear cachesToClear) { - toImpl(cacheManagerRef)->clearCacheForOrigin(toImpl(originRef), toResourceCachesToClear(cachesToClear)); + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(cacheManager))->websiteDataStore(); + + Vector<WebsiteDataRecord> dataRecords; + + { + WebsiteDataRecord dataRecord; + dataRecord.add(WebsiteDataType::MemoryCache, WebCore::SecurityOriginData::fromSecurityOrigin(toImpl(origin)->securityOrigin())); + + dataRecords.append(dataRecord); + } + + if (cachesToClear == WKResourceCachesToClearAll) { + WebsiteDataRecord dataRecord; + dataRecord.add(WebsiteDataType::DiskCache, WebCore::SecurityOriginData::fromSecurityOrigin(toImpl(origin)->securityOrigin())); + + dataRecords.append(dataRecord); + } + + websiteDataStore.removeData(toWebsiteDataTypes(cachesToClear), dataRecords, [] { }); } -void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManagerRef, WKResourceCachesToClear cachesToClear) +void WKResourceCacheManagerClearCacheForAllOrigins(WKResourceCacheManagerRef cacheManager, WKResourceCachesToClear cachesToClear) { - toImpl(cacheManagerRef)->clearCacheForAllOrigins(toResourceCachesToClear(cachesToClear)); + auto& websiteDataStore = toImpl(reinterpret_cast<WKWebsiteDataStoreRef>(cacheManager))->websiteDataStore(); + websiteDataStore.removeData(toWebsiteDataTypes(cachesToClear), std::chrono::system_clock::time_point::min(), [] { }); } diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h index 80c4531ff..7f4bb6c51 100644 --- a/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKResourceCacheManager.h @@ -26,7 +26,7 @@ #ifndef WKResourceCacheManager_h #define WKResourceCacheManager_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp b/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp new file mode 100644 index 000000000..879abeb39 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKResourceLoadStatisticsManager.h" + +#include "WKAPICast.h" +#include "WebResourceLoadStatisticsManager.h" + +using namespace WebKit; + +WKTypeID WKResourceLoadStatisticsManagerGetTypeID() +{ + return toAPI(WebResourceLoadStatisticsManager::APIType); +} + +void WKResourceLoadStatisticsManagerSetPrevalentResource(WKStringRef hostName, bool value) +{ + WebResourceLoadStatisticsManager::setPrevalentResource(toWTFString(hostName), value); +} + +bool WKResourceLoadStatisticsManagerIsPrevalentResource(WKStringRef hostName) +{ + return WebResourceLoadStatisticsManager::isPrevalentResource(toWTFString(hostName)); +} + +void WKResourceLoadStatisticsManagerSetHasHadUserInteraction(WKStringRef hostName, bool value) +{ + WebResourceLoadStatisticsManager::setHasHadUserInteraction(toWTFString(hostName), value); +} + +bool WKResourceLoadStatisticsManagerIsHasHadUserInteraction(WKStringRef hostName) +{ + return WebResourceLoadStatisticsManager::hasHadUserInteraction(toWTFString(hostName)); +} + +void WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(double seconds) +{ + WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction(seconds); +} + +void WKResourceLoadStatisticsManagerFireDataModificationHandler() +{ + WebResourceLoadStatisticsManager::fireDataModificationHandler(); +} + +void WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(bool value) +{ + WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned(value); +} + +void WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) +{ + WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval(value); +} + +void WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(double seconds) +{ + WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval(seconds); +} + +void WKResourceLoadStatisticsManagerResetToConsistentState() +{ + WebResourceLoadStatisticsManager::resetToConsistentState(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h b/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h new file mode 100644 index 000000000..2b83f5c11 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKResourceLoadStatisticsManager.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <WebKit/WKBase.h> +#include <wtf/text/WTFString.h> + +#ifdef __cplusplus +extern "C" { +#endif + + WK_EXPORT WKTypeID WKResourceLoadStatisticsManagerGetTypeID(); + + WK_EXPORT void WKResourceLoadStatisticsManagerSetPrevalentResource(WKStringRef hostName, bool value); + WK_EXPORT bool WKResourceLoadStatisticsManagerIsPrevalentResource(WKStringRef hostName); + WK_EXPORT void WKResourceLoadStatisticsManagerSetHasHadUserInteraction(WKStringRef hostName, bool value); + WK_EXPORT bool WKResourceLoadStatisticsManagerIsHasHadUserInteraction(WKStringRef hostName); + WK_EXPORT void WKResourceLoadStatisticsManagerSetTimeToLiveUserInteraction(double seconds); + WK_EXPORT void WKResourceLoadStatisticsManagerSetReducedTimestampResolution(double seconds); + WK_EXPORT void WKResourceLoadStatisticsManagerFireDataModificationHandler(); + WK_EXPORT void WKResourceLoadStatisticsManagerSetNotifyPagesWhenDataRecordsWereScanned(bool value); + WK_EXPORT void WKResourceLoadStatisticsManagerSetShouldClassifyResourcesBeforeDataRecordsRemoval(bool value); + WK_EXPORT void WKResourceLoadStatisticsManagerSetMinimumTimeBetweeenDataRecordsRemoval(double seconds); + WK_EXPORT void WKResourceLoadStatisticsManagerResetToConsistentState(); + +#ifdef __cplusplus +} +#endif diff --git a/Source/WebKit2/UIProcess/API/C/WKSessionStateRef.cpp b/Source/WebKit2/UIProcess/API/C/WKSessionStateRef.cpp new file mode 100644 index 000000000..c938f514c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKSessionStateRef.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKSessionStateRef.h" + +#include "APIData.h" +#include "APISessionState.h" +#include "LegacySessionStateCoding.h" +#include "SessionState.h" +#include "WKAPICast.h" + +WKTypeID WKSessionStateGetTypeID() +{ + return WebKit::toAPI(API::SessionState::APIType); +} + +WKSessionStateRef WKSessionStateCreateFromData(WKDataRef data) +{ + WebKit::SessionState sessionState; + if (!WebKit::decodeLegacySessionState(WebKit::toImpl(data)->bytes(), WebKit::toImpl(data)->size(), sessionState)) + return nullptr; + + return WebKit::toAPI(&API::SessionState::create(WTFMove(sessionState)).leakRef()); +} + +WKDataRef WKSessionStateCopyData(WKSessionStateRef sessionState) +{ + return WebKit::toAPI(WebKit::encodeLegacySessionState(WebKit::toImpl(sessionState)->sessionState()).leakRef()); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKColorPickerResultListener.h b/Source/WebKit2/UIProcess/API/C/WKSessionStateRef.h index bfd4732c9..e46b66414 100644 --- a/Source/WebKit2/UIProcess/API/C/WKColorPickerResultListener.h +++ b/Source/WebKit2/UIProcess/API/C/WKSessionStateRef.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS @@ -23,21 +23,23 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKColorPickerResultListener_h -#define WKColorPickerResultListener_h +#ifndef WKSessionStateRef_h +#define WKSessionStateRef_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT WKTypeID WKColorPickerResultListenerGetTypeID(); +WK_EXPORT WKTypeID WKSessionStateGetTypeID(); -WK_EXPORT void WKColorPickerResultListenerSetColor(WKColorPickerResultListenerRef listenerRef, const WKStringRef color); +WK_EXPORT WKSessionStateRef WKSessionStateCreateFromData(WKDataRef data); + +WK_EXPORT WKDataRef WKSessionStateCopyData(WKSessionStateRef sessionState); #ifdef __cplusplus } #endif -#endif /* WKColorPickerResultListener_h */ +#endif // WKSessionStateRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WKTextChecker.cpp b/Source/WebKit2/UIProcess/API/C/WKTextChecker.cpp index 2da94dfc2..c8e7560b1 100644 --- a/Source/WebKit2/UIProcess/API/C/WKTextChecker.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKTextChecker.cpp @@ -25,36 +25,48 @@ #include "config.h" #include "WKTextChecker.h" +#include "TextChecker.h" +#if defined(BUILDING_GTK__) #include "WKAPICast.h" #include "WebPageProxy.h" #include "WebTextChecker.h" +#endif using namespace WebKit; +void WKTextCheckerSetTestingMode(bool enabled) +{ + TextChecker::setTestingMode(enabled); +} + +#if defined(BUILDING_GTK__) + void WKTextCheckerSetClient(const WKTextCheckerClientBase* wkClient) { if (wkClient && wkClient->version) return; - WebTextChecker::shared()->setClient(wkClient); + WebTextChecker::singleton()->setClient(wkClient); } void WKTextCheckerContinuousSpellCheckingEnabledStateChanged(bool enabled) { - WebTextChecker::shared()->continuousSpellCheckingEnabledStateChanged(enabled); + WebTextChecker::singleton()->continuousSpellCheckingEnabledStateChanged(enabled); } void WKTextCheckerGrammarCheckingEnabledStateChanged(bool enabled) { - WebTextChecker::shared()->grammarCheckingEnabledStateChanged(enabled); + WebTextChecker::singleton()->grammarCheckingEnabledStateChanged(enabled); } void WKTextCheckerCheckSpelling(WKPageRef page, bool startBeforeSelection) { - WebTextChecker::shared()->checkSpelling(toImpl(page), startBeforeSelection); + WebTextChecker::singleton()->checkSpelling(toImpl(page), startBeforeSelection); } void WKTextCheckerChangeSpellingToWord(WKPageRef page, WKStringRef word) { - WebTextChecker::shared()->changeSpellingToWord(toImpl(page), toWTFString(word)); + WebTextChecker::singleton()->changeSpellingToWord(toImpl(page), toWTFString(word)); } + +#endif diff --git a/Source/WebKit2/UIProcess/API/C/WKTextChecker.h b/Source/WebKit2/UIProcess/API/C/WKTextChecker.h index af72c75b7..f52d9c700 100644 --- a/Source/WebKit2/UIProcess/API/C/WKTextChecker.h +++ b/Source/WebKit2/UIProcess/API/C/WKTextChecker.h @@ -26,12 +26,16 @@ #ifndef WKTextChecker_h #define WKTextChecker_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif +WK_EXPORT void WKTextCheckerSetTestingMode(bool enabled); + +#if defined(BUILDING_GTK__) + // TextChecker Client typedef bool (*WKTextCheckerContinousSpellCheckingAllowed)(const void *clientInfo); typedef bool (*WKTextCheckerContinousSpellCheckingEnabled)(const void *clientInfo); @@ -84,6 +88,8 @@ WK_EXPORT void WKTextCheckerGrammarCheckingEnabledStateChanged(bool); WK_EXPORT void WKTextCheckerCheckSpelling(WKPageRef page, bool startBeforeSelection); WK_EXPORT void WKTextCheckerChangeSpellingToWord(WKPageRef page, WKStringRef word); +#endif + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.cpp b/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.cpp new file mode 100644 index 000000000..bb73853ba --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKUserContentControllerRef.h" + +#include "APIUserContentExtension.h" +#include "APIUserScript.h" +#include "WKAPICast.h" +#include "WebUserContentControllerProxy.h" + +using namespace WebKit; + +WKTypeID WKUserContentControllerGetTypeID() +{ + return toAPI(WebUserContentControllerProxy::APIType); +} + +WKUserContentControllerRef WKUserContentControllerCreate() +{ + return toAPI(&WebUserContentControllerProxy::create().leakRef()); +} + +WKArrayRef WKUserContentControllerCopyUserScripts(WKUserContentControllerRef userContentControllerRef) +{ + Ref<API::Array> userScripts = toImpl(userContentControllerRef)->userScripts().copy(); + return toAPI(&userScripts.leakRef()); +} + +void WKUserContentControllerAddUserScript(WKUserContentControllerRef userContentControllerRef, WKUserScriptRef userScriptRef) +{ + toImpl(userContentControllerRef)->addUserScript(*toImpl(userScriptRef)); +} + +void WKUserContentControllerRemoveAllUserScripts(WKUserContentControllerRef userContentControllerRef) +{ + toImpl(userContentControllerRef)->removeAllUserScripts(); +} + +void WKUserContentControllerAddUserContentFilter(WKUserContentControllerRef userContentControllerRef, WKUserContentFilterRef userContentFilterRef) +{ +#if ENABLE(CONTENT_EXTENSIONS) + toImpl(userContentControllerRef)->addUserContentExtension(*toImpl(userContentFilterRef)); +#endif +} + +void WKUserContentControllerRemoveAllUserContentFilters(WKUserContentControllerRef userContentControllerRef) +{ +#if ENABLE(CONTENT_EXTENSIONS) + toImpl(userContentControllerRef)->removeAllUserContentExtensions(); +#endif +} diff --git a/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.h b/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.h new file mode 100644 index 000000000..d462e99b1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserContentControllerRef.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKUserContentControllerRef_h +#define WKUserContentControllerRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKUserContentControllerGetTypeID(); + +WK_EXPORT WKUserContentControllerRef WKUserContentControllerCreate(); + +WK_EXPORT WKArrayRef WKUserContentControllerCopyUserScripts(WKUserContentControllerRef userContentController); +WK_EXPORT void WKUserContentControllerAddUserScript(WKUserContentControllerRef userContentController, WKUserScriptRef userScript); +WK_EXPORT void WKUserContentControllerRemoveAllUserScripts(WKUserContentControllerRef userContentController); + +WK_EXPORT void WKUserContentControllerAddUserContentFilter(WKUserContentControllerRef userContentController, WKUserContentFilterRef userContentFilter); +WK_EXPORT void WKUserContentControllerRemoveAllUserContentFilters(WKUserContentControllerRef userContentController); + +#ifdef __cplusplus +} +#endif + +#endif /* WKUserContentControllerRef_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.cpp b/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.cpp new file mode 100644 index 000000000..6fe872e62 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKUserContentExtensionStoreRef.h" + +#include "APIUserContentExtensionStore.h" +#include "WKAPICast.h" + +using namespace WebKit; + +WKTypeID WKUserContentExtensionStoreGetTypeID() +{ +#if ENABLE(CONTENT_EXTENSIONS) + return toAPI(API::UserContentExtensionStore::APIType); +#else + return 0; +#endif +} diff --git a/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.h b/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.h new file mode 100644 index 000000000..53598ec80 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserContentExtensionStoreRef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKUserContentExtensionStoreRef_h +#define WKUserContentExtensionStoreRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKUserContentExtensionStoreGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif /* WKUserContentExtensionStoreRef_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp new file mode 100644 index 000000000..4403cd75f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "config.h" +#include "WKUserMediaPermissionCheck.h" + +#include "UserMediaPermissionCheckProxy.h" +#include "WKAPICast.h" +#include "WKArray.h" +#include "WKMutableArray.h" +#include "WKString.h" + +using namespace WebKit; + +WKTypeID WKUserMediaPermissionCheckGetTypeID() +{ + return toAPI(UserMediaPermissionCheckProxy::APIType); +} + +void WKUserMediaPermissionCheckSetUserMediaAccessInfo(WKUserMediaPermissionCheckRef userMediaPermissionRequestRef, WKStringRef mediaDeviceIdentifierHashSalt, bool allowed) +{ + toImpl(userMediaPermissionRequestRef)->setUserMediaAccessInfo(toWTFString(mediaDeviceIdentifierHashSalt), allowed); +} + diff --git a/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h new file mode 100644 index 000000000..d257845e4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionCheck.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WKUserMediaPermissionCheck_h +#define WKUserMediaPermissionCheck_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKUserMediaPermissionCheckGetTypeID(); + +WK_EXPORT void WKUserMediaPermissionCheckSetUserMediaAccessInfo(WKUserMediaPermissionCheckRef, WKStringRef, bool); + +#ifdef __cplusplus +} +#endif + +#endif /* WKMediaDevicesRequest_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp new file mode 100644 index 000000000..453669512 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 Igalia S.L + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "WKUserMediaPermissionRequest.h" + +#include "UserMediaPermissionRequestProxy.h" +#include "WKAPICast.h" +#include "WKArray.h" +#include "WKMutableArray.h" +#include "WKString.h" + +using namespace WebKit; + +WKTypeID WKUserMediaPermissionRequestGetTypeID() +{ + return toAPI(UserMediaPermissionRequestProxy::APIType); +} + + +void WKUserMediaPermissionRequestAllow(WKUserMediaPermissionRequestRef userMediaPermissionRequestRef, WKStringRef audioDeviceUID, WKStringRef videoDeviceUID) +{ + toImpl(userMediaPermissionRequestRef)->allow(toWTFString(audioDeviceUID), toWTFString(videoDeviceUID)); +} + +static UserMediaPermissionRequestProxy::UserMediaAccessDenialReason toWK(UserMediaPermissionRequestDenialReason reason) +{ + switch (reason) { + case kWKNoConstraints: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints; + break; + case kWKUserMediaDisabled: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled; + break; + case kWKNoCaptureDevices: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoCaptureDevices; + break; + case kWKInvalidConstraint: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint; + break; + case kWKHardwareError: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::HardwareError; + break; + case kWKPermissionDenied: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied; + break; + case kWKOtherFailure: + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure; + break; + } + + ASSERT_NOT_REACHED(); + return UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure; + +} + +void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef userMediaPermissionRequestRef, UserMediaPermissionRequestDenialReason reason) +{ + toImpl(userMediaPermissionRequestRef)->deny(toWK(reason)); +} + +WKArrayRef WKUserMediaPermissionRequestVideoDeviceUIDs(WKUserMediaPermissionRequestRef userMediaPermissionRef) +{ + WKMutableArrayRef array = WKMutableArrayCreate(); +#if ENABLE(MEDIA_STREAM) + for (auto& deviceUID : toImpl(userMediaPermissionRef)->videoDeviceUIDs()) + WKArrayAppendItem(array, toAPI(API::String::create(deviceUID).ptr())); +#endif + return array; +} + +WKArrayRef WKUserMediaPermissionRequestAudioDeviceUIDs(WKUserMediaPermissionRequestRef userMediaPermissionRef) +{ + WKMutableArrayRef array = WKMutableArrayCreate(); +#if ENABLE(MEDIA_STREAM) + for (auto& deviceUID : toImpl(userMediaPermissionRef)->audioDeviceUIDs()) + WKArrayAppendItem(array, toAPI(API::String::create(deviceUID).ptr())); +#endif + return array; +} diff --git a/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h new file mode 100644 index 000000000..2f9c1b4e8 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserMediaPermissionRequest.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Igalia S.L + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WKUserMediaPermissionRequest_h +#define WKUserMediaPermissionRequest_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKUserMediaPermissionRequestGetTypeID(); + +enum { + kWKNoConstraints = 0, + kWKUserMediaDisabled, + kWKNoCaptureDevices, + kWKInvalidConstraint, + kWKHardwareError, + kWKPermissionDenied, + kWKOtherFailure +}; +typedef uint32_t UserMediaPermissionRequestDenialReason; + +WK_EXPORT void WKUserMediaPermissionRequestAllow(WKUserMediaPermissionRequestRef, WKStringRef audioDeviceUID, WKStringRef videoDeviceUID); +WK_EXPORT void WKUserMediaPermissionRequestDeny(WKUserMediaPermissionRequestRef, UserMediaPermissionRequestDenialReason); + +WK_EXPORT WKArrayRef WKUserMediaPermissionRequestVideoDeviceUIDs(WKUserMediaPermissionRequestRef); +WK_EXPORT WKArrayRef WKUserMediaPermissionRequestAudioDeviceUIDs(WKUserMediaPermissionRequestRef); + +#ifdef __cplusplus +} +#endif + +#endif /* WKUserMediaPermissionRequest_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKMediaCacheManager.cpp b/Source/WebKit2/UIProcess/API/C/WKUserScriptRef.cpp index 6e2ecce06..17e762961 100644 --- a/Source/WebKit2/UIProcess/API/C/WKMediaCacheManager.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKUserScriptRef.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,29 +24,34 @@ */ #include "config.h" -#include "WKMediaCacheManager.h" +#include "WKUserScriptRef.h" +#include "APIUserScript.h" #include "WKAPICast.h" -#include "WebMediaCacheManagerProxy.h" using namespace WebKit; -WKTypeID WKMediaCacheManagerGetTypeID() +WKTypeID WKUserScriptGetTypeID() { - return toAPI(WebMediaCacheManagerProxy::APIType); + return toAPI(API::UserScript::APIType); } -void WKMediaCacheManagerGetHostnamesWithMediaCache(WKMediaCacheManagerRef mediaCacheManagerRef, void* context, WKMediaCacheManagerGetHostnamesWithMediaCacheFunction callback) +WKUserScriptRef WKUserScriptCreateWithSource(WKStringRef sourceRef, _WKUserScriptInjectionTime injectionTime, bool forMainFrameOnly) { - toImpl(mediaCacheManagerRef)->getHostnamesWithMediaCache(ArrayCallback::create(context, callback)); + return toAPI(&API::UserScript::create(WebCore::UserScript { toWTFString(sourceRef), API::UserScript::generateUniqueURL(), { }, { }, toUserScriptInjectionTime(injectionTime), forMainFrameOnly ? WebCore::InjectInTopFrameOnly : WebCore::InjectInAllFrames }, API::UserContentWorld::normalWorld()).leakRef()); } -void WKMediaCacheManagerClearCacheForHostname(WKMediaCacheManagerRef mediaCacheManagerRef, WKStringRef hostname) +WKStringRef WKUserScriptCopySource(WKUserScriptRef userScriptRef) { - toImpl(mediaCacheManagerRef)->clearCacheForHostname(toWTFString(hostname)); + return toCopiedAPI(toImpl(userScriptRef)->userScript().source()); } -void WKMediaCacheManagerClearCacheForAllHostnames(WKMediaCacheManagerRef mediaCacheManagerRef) +_WKUserScriptInjectionTime WKUserScriptGetInjectionTime(WKUserScriptRef userScriptRef) { - toImpl(mediaCacheManagerRef)->clearCacheForAllHostnames(); + return toWKUserScriptInjectionTime(toImpl(userScriptRef)->userScript().injectionTime()); +} + +bool WKUserScriptGetMainFrameOnly(WKUserScriptRef userScriptRef) +{ + return toImpl(userScriptRef)->userScript().injectedFrames() == WebCore::InjectInTopFrameOnly; } diff --git a/Source/WebKit2/UIProcess/API/C/WKUserScriptRef.h b/Source/WebKit2/UIProcess/API/C/WKUserScriptRef.h new file mode 100644 index 000000000..610f9fb58 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKUserScriptRef.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKUserScriptRef_h +#define WKUserScriptRef_h + +#include <WebKit/WKBase.h> +#include <WebKit/WKUserScriptInjectionTime.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKUserScriptGetTypeID(); + +WK_EXPORT WKUserScriptRef WKUserScriptCreateWithSource(WKStringRef source, _WKUserScriptInjectionTime injectionTime, bool forMainFrameOnly); + +WK_EXPORT WKStringRef WKUserScriptCopySource(WKUserScriptRef userScript); +WK_EXPORT _WKUserScriptInjectionTime WKUserScriptGetInjectionTime(WKUserScriptRef userScript); +WK_EXPORT bool WKUserScriptGetMainFrameOnly(WKUserScriptRef userScript); + +#ifdef __cplusplus +} +#endif + +#endif /* WKUserScriptRef_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKVibration.h b/Source/WebKit2/UIProcess/API/C/WKVibration.h index c18000bf1..965749c86 100644 --- a/Source/WebKit2/UIProcess/API/C/WKVibration.h +++ b/Source/WebKit2/UIProcess/API/C/WKVibration.h @@ -26,7 +26,7 @@ #ifndef WKVibration_h #define WKVibration_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.cpp b/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.cpp new file mode 100644 index 000000000..e30af5666 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the followlayoutSizeing disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list Viewof conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKViewportAttributes.h" + +#include "WKAPICast.h" +#include "WebViewportAttributes.h" + +using namespace WebKit; + +WKTypeID WKViewportAttributesGetTypeID() +{ + return toAPI(WebViewportAttributes::APIType); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.h b/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.h new file mode 100644 index 000000000..8ab84edac --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKViewportAttributes.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list Viewof conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKViewportAttributes_h +#define WKViewportAttributes_h + +#include <WebKit/WKBase.h> +#include <WebKit/WKGeometry.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKViewportAttributesGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif /* WKViewportAttributes_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.cpp b/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.cpp new file mode 100644 index 000000000..a77c1a89d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKWebsiteDataStoreRef.h" + +#include "APIWebsiteDataStore.h" +#include "WKAPICast.h" +#include "WebsiteDataType.h" + +WKTypeID WKWebsiteDataStoreGetTypeID() +{ + return WebKit::toAPI(API::WebsiteDataStore::APIType); +} + +WKWebsiteDataStoreRef WKWebsiteDataStoreGetDefaultDataStore() +{ + return WebKit::toAPI(API::WebsiteDataStore::defaultDataStore().get()); +} + +WKWebsiteDataStoreRef WKWebsiteDataStoreCreateNonPersistentDataStore() +{ + return WebKit::toAPI(&API::WebsiteDataStore::createNonPersistentDataStore().leakRef()); +} + +void WKWebsiteDataStoreSetResourceLoadStatisticsEnabled(WKWebsiteDataStoreRef dataStoreRef, bool enable) +{ + WebKit::toImpl(dataStoreRef)->setResourceLoadStatisticsEnabled(enable); +} + +bool WKWebsiteDataStoreGetResourceLoadStatisticsEnabled(WKWebsiteDataStoreRef dataStoreRef) +{ + return WebKit::toImpl(dataStoreRef)->resourceLoadStatisticsEnabled(); +} + +void WKWebsiteDataStoreRemoveAllIndexedDatabases(WKWebsiteDataStoreRef dataStoreRef) +{ + OptionSet<WebKit::WebsiteDataType> dataTypes = WebKit::WebsiteDataType::IndexedDBDatabases; + WebKit::toImpl(dataStoreRef)->websiteDataStore().removeData(dataTypes, std::chrono::system_clock::time_point::min(), [] { }); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.h b/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.h new file mode 100644 index 000000000..da57838d2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKWebsiteDataStoreRef.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKWebsiteDataStoreRef_h +#define WKWebsiteDataStoreRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKWebsiteDataStoreGetTypeID(); + +WK_EXPORT WKWebsiteDataStoreRef WKWebsiteDataStoreGetDefaultDataStore(); +WK_EXPORT WKWebsiteDataStoreRef WKWebsiteDataStoreCreateNonPersistentDataStore(); + +WK_EXPORT bool WKWebsiteDataStoreGetResourceLoadStatisticsEnabled(WKWebsiteDataStoreRef dataStoreRef); +WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsEnabled(WKWebsiteDataStoreRef dataStoreRef, bool enable); +WK_EXPORT void WKWebsiteDataStoreRemoveAllIndexedDatabases(WKWebsiteDataStoreRef dataStoreRef); + +#ifdef __cplusplus +} +#endif + +#endif /* WKWebsiteDataStoreRef_h */ diff --git a/Source/WebKit2/UIProcess/API/C/WKWebsitePolicies.cpp b/Source/WebKit2/UIProcess/API/C/WKWebsitePolicies.cpp new file mode 100644 index 000000000..b9709a68d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKWebsitePolicies.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKWebsitePolicies.h" + +#include "APIWebsitePolicies.h" +#include "WKAPICast.h" +#include "WebsitePolicies.h" + +using namespace WebKit; + +WKTypeID WKWebsitePoliciesGetTypeID() +{ + return toAPI(API::WebsitePolicies::APIType); +} + +WKWebsitePoliciesRef WKWebsitePoliciesCreate() +{ + return toAPI(&API::WebsitePolicies::create().leakRef()); +} + +void WKWebsitePoliciesSetContentBlockersEnabled(WKWebsitePoliciesRef websitePolicies, bool enabled) +{ + toImpl(websitePolicies)->setContentBlockersEnabled(enabled); +} + +bool WKWebsitePoliciesGetContentBlockersEnabled(WKWebsitePoliciesRef websitePolicies) +{ + return toImpl(websitePolicies)->contentBlockersEnabled(); +} + +WKWebsiteAutoplayPolicy WKWebsitePoliciesGetAutoplayPolicy(WKWebsitePoliciesRef websitePolicies) +{ + switch (toImpl(websitePolicies)->autoplayPolicy()) { + case WebKit::WebsiteAutoplayPolicy::Default: + return kWKWebsiteAutoplayPolicyDefault; + case WebsiteAutoplayPolicy::Allow: + return kWKWebsiteAutoplayPolicyAllow; + case WebsiteAutoplayPolicy::AllowWithoutSound: + return kWKWebsiteAutoplayPolicyAllowWithoutSound; + case WebsiteAutoplayPolicy::Deny: + return kWKWebsiteAutoplayPolicyDeny; + } + ASSERT_NOT_REACHED(); + return kWKWebsiteAutoplayPolicyDefault; +} + +void WKWebsitePoliciesSetAutoplayPolicy(WKWebsitePoliciesRef websitePolicies, WKWebsiteAutoplayPolicy policy) +{ + switch (policy) { + case kWKWebsiteAutoplayPolicyDefault: + toImpl(websitePolicies)->setAutoplayPolicy(WebsiteAutoplayPolicy::Default); + return; + case kWKWebsiteAutoplayPolicyAllow: + toImpl(websitePolicies)->setAutoplayPolicy(WebsiteAutoplayPolicy::Allow); + return; + case kWKWebsiteAutoplayPolicyAllowWithoutSound: + toImpl(websitePolicies)->setAutoplayPolicy(WebsiteAutoplayPolicy::AllowWithoutSound); + return; + case kWKWebsiteAutoplayPolicyDeny: + toImpl(websitePolicies)->setAutoplayPolicy(WebsiteAutoplayPolicy::Deny); + return; + } + ASSERT_NOT_REACHED(); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKMediaCacheManager.h b/Source/WebKit2/UIProcess/API/C/WKWebsitePolicies.h index eee1b9291..0c8e34f15 100644 --- a/Source/WebKit2/UIProcess/API/C/WKMediaCacheManager.h +++ b/Source/WebKit2/UIProcess/API/C/WKWebsitePolicies.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,25 +23,31 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKMediaCacheManager_h -#define WKMediaCacheManager_h +#pragma once -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT WKTypeID WKMediaCacheManagerGetTypeID(); +WK_EXPORT WKTypeID WKWebsitePoliciesGetTypeID(); -typedef void (*WKMediaCacheManagerGetHostnamesWithMediaCacheFunction)(WKArrayRef, WKErrorRef, void*); -WK_EXPORT void WKMediaCacheManagerGetHostnamesWithMediaCache(WKMediaCacheManagerRef mediaCacheManager, void* context, WKMediaCacheManagerGetHostnamesWithMediaCacheFunction function); +enum WKWebsiteAutoplayPolicy { + kWKWebsiteAutoplayPolicyDefault, + kWKWebsiteAutoplayPolicyAllow, + kWKWebsiteAutoplayPolicyAllowWithoutSound, + kWKWebsiteAutoplayPolicyDeny +}; -WK_EXPORT void WKMediaCacheManagerClearCacheForHostname(WKMediaCacheManagerRef mediaCacheManager, WKStringRef hostname); -WK_EXPORT void WKMediaCacheManagerClearCacheForAllHostnames(WKMediaCacheManagerRef mediaCacheManager); +WK_EXPORT WKWebsitePoliciesRef WKWebsitePoliciesCreate(); + +WK_EXPORT bool WKWebsitePoliciesGetContentBlockersEnabled(WKWebsitePoliciesRef); +WK_EXPORT void WKWebsitePoliciesSetContentBlockersEnabled(WKWebsitePoliciesRef, bool); + +WK_EXPORT WKWebsiteAutoplayPolicy WKWebsitePoliciesGetAutoplayPolicy(WKWebsitePoliciesRef); +WK_EXPORT void WKWebsitePoliciesSetAutoplayPolicy(WKWebsitePoliciesRef, WKWebsiteAutoplayPolicy); #ifdef __cplusplus } #endif - -#endif // WKMediaCacheManager_h diff --git a/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.cpp b/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.cpp new file mode 100644 index 000000000..e9338a662 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKWindowFeaturesRef.h" + +#include "APIWindowFeatures.h" +#include "WKAPICast.h" + +WKTypeID WKWindowFeaturesGetTypeID() +{ + return WebKit::toAPI(API::WindowFeatures::APIType); +} diff --git a/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.h b/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.h new file mode 100644 index 000000000..5dc940477 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/WKWindowFeaturesRef.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKWindowFeaturesRef_h +#define WKWindowFeaturesRef_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT WKTypeID WKWindowFeaturesGetTypeID(); + +#ifdef __cplusplus +} +#endif + +#endif // WKWindowFeaturesRef_h diff --git a/Source/WebKit2/UIProcess/API/C/WebKit2_C.h b/Source/WebKit2/UIProcess/API/C/WebKit2_C.h index 21c9eeaab..4f82b7f92 100644 --- a/Source/WebKit2/UIProcess/API/C/WebKit2_C.h +++ b/Source/WebKit2/UIProcess/API/C/WebKit2_C.h @@ -26,42 +26,46 @@ #ifndef WebKit2_C_h #define WebKit2_C_h -#include <WebKit2/WKBase.h> -#include <WebKit2/WKType.h> +#include <WebKit/WKBase.h> +#include <WebKit/WKType.h> -#include <WebKit2/WKArray.h> -#include <WebKit2/WKBackForwardListRef.h> -#include <WebKit2/WKBackForwardListItemRef.h> -#include <WebKit2/WKConnectionRef.h> -#include <WebKit2/WKContext.h> -#include <WebKit2/WKData.h> -#include <WebKit2/WKDictionary.h> -#include <WebKit2/WKError.h> -#include <WebKit2/WKFormSubmissionListener.h> -#include <WebKit2/WKFrame.h> -#include <WebKit2/WKFramePolicyListener.h> -#include <WebKit2/WKGeolocationManager.h> -#include <WebKit2/WKGeolocationPermissionRequest.h> -#include <WebKit2/WKGeolocationPosition.h> -#include <WebKit2/WKHitTestResult.h> -#include <WebKit2/WKMutableArray.h> -#include <WebKit2/WKMutableDictionary.h> -#include <WebKit2/WKNavigationDataRef.h> -#include <WebKit2/WKNumber.h> -#include <WebKit2/WKOpenPanelParameters.h> -#include <WebKit2/WKOpenPanelResultListener.h> -#include <WebKit2/WKPage.h> -#include <WebKit2/WKPageGroup.h> -#include <WebKit2/WKPreferencesRef.h> -#include <WebKit2/WKString.h> -#include <WebKit2/WKURL.h> -#include <WebKit2/WKURLRequest.h> -#include <WebKit2/WKURLResponse.h> +#include <WebKit/WKArray.h> +#include <WebKit/WKBackForwardListRef.h> +#include <WebKit/WKBackForwardListItemRef.h> +#include <WebKit/WKConnectionRef.h> +#include <WebKit/WKContext.h> +#include <WebKit/WKData.h> +#include <WebKit/WKDictionary.h> +#include <WebKit/WKErrorRef.h> +#include <WebKit/WKFormSubmissionListener.h> +#include <WebKit/WKFrame.h> +#include <WebKit/WKFramePolicyListener.h> +#include <WebKit/WKGeolocationManager.h> +#include <WebKit/WKGeolocationPermissionRequest.h> +#include <WebKit/WKGeolocationPosition.h> +#include <WebKit/WKHitTestResult.h> +#include <WebKit/WKMutableArray.h> +#include <WebKit/WKMutableDictionary.h> +#include <WebKit/WKNavigationDataRef.h> +#include <WebKit/WKNumber.h> +#include <WebKit/WKOpenPanelParametersRef.h> +#include <WebKit/WKOpenPanelResultListener.h> +#include <WebKit/WKPage.h> +#include <WebKit/WKPageConfigurationRef.h> +#include <WebKit/WKPageGroup.h> +#include <WebKit/WKPreferencesRef.h> +#include <WebKit/WKString.h> +#include <WebKit/WKURL.h> +#include <WebKit/WKURLRequest.h> +#include <WebKit/WKURLResponse.h> +#include <WebKit/WKUserContentControllerRef.h> +#include <WebKit/WKUserMediaPermissionRequest.h> +#include <WebKit/WKUserScriptRef.h> #if defined(__OBJC__) && __OBJC__ -#import <WebKit2/WKView.h> +#import <WebKit/WKView.h> #elif !(defined(__APPLE__) && __APPLE__) -#include <WebKit2/WKView.h> +#include <WebKit/WKView.h> #endif #endif /* WebKit2_C_h */ diff --git a/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp b/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp new file mode 100644 index 000000000..118c4d8cb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKIconDatabaseCairo.h" + +#include "WKAPICast.h" +#include "WebIconDatabase.h" + +using namespace WebCore; +using namespace WebKit; + +cairo_surface_t* WKIconDatabaseTryGetCairoSurfaceForURL(WKIconDatabaseRef iconDatabase, WKURLRef url) +{ + return toImpl(iconDatabase)->nativeImageForPageURL(toWTFString(url)).get(); +} diff --git a/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.h b/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.h new file mode 100644 index 000000000..5830177df --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/cairo/WKIconDatabaseCairo.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <WebKit/WKBase.h> + +typedef struct _cairo_surface cairo_surface_t; + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT cairo_surface_t* WKIconDatabaseTryGetCairoSurfaceForURL(WKIconDatabaseRef iconDatabase, WKURLRef url); + +#ifdef __cplusplus +} +#endif diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKAPICastGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKAPICastGtk.h index 9eb0c78ad..a06292b2e 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKAPICastGtk.h +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKAPICastGtk.h @@ -37,6 +37,18 @@ namespace WebKit { WK_ADD_API_MAPPING(WKViewRef, WebKitWebViewBase) +template<> +inline WKViewRef toAPI<>(WebKitWebViewBase* view) +{ + return reinterpret_cast<WKViewRef>(static_cast<void*>(view)); +} + +template<> +inline WebKitWebViewBase* toImpl<>(WKViewRef view) +{ + return static_cast<WebKitWebViewBase*>(static_cast<void*>(const_cast<typename std::remove_const<typename std::remove_pointer<WKViewRef>::type>::type*>(view))); +} + } #endif // WKAPICastGtk_h diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h index a292dda11..cece1057b 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKFullScreenClientGtk.h @@ -26,7 +26,7 @@ #ifndef WKFullScreenClientGtk_h #define WKFullScreenClientGtk_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h index 28242da09..2e60bc793 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKInspectorClientGtk.h @@ -26,7 +26,7 @@ #ifndef WKInspectorClientGtk_h #define WKInspectorClientGtk_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { @@ -37,6 +37,7 @@ typedef void (*WKInspectorClientGtkInspectorDidCloseCallback)(WKInspectorRef ins typedef void (*WKInspectorClientGtkInspectedURLChangedCallback)(WKInspectorRef inspector, WKStringRef url, const void* clientInfo); typedef void (*WKInspectorClientGtkDidChangeAttachedHeightCallback)(WKInspectorRef inspector, unsigned height, const void* clientInfo); typedef void (*WKInspectorClientGtkDidChangeAttachedWidthCallback)(WKInspectorRef inspector, unsigned width, const void* clientInfo); +typedef void (*WKInspectorClientGtkDidChangeAttachAvailabilityCallback)(WKInspectorRef inspector, bool available, const void* clientInfo); typedef struct WKInspectorClientGtkBase { int version; @@ -54,6 +55,7 @@ typedef struct WKInspectorClientGtkV0 { WKInspectorClientGtkInspectorCallback detach; WKInspectorClientGtkDidChangeAttachedHeightCallback didChangeAttachedHeight; WKInspectorClientGtkDidChangeAttachedWidthCallback didChangeAttachedWidth; + WKInspectorClientGtkDidChangeAttachAvailabilityCallback didChangeAttachAvailability; } WKInspectorClientGtkV0; WK_EXPORT void WKInspectorSetInspectorClientGtk(WKInspectorRef inspectorRef, const WKInspectorClientGtkBase* client); diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.cpp b/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.cpp new file mode 100644 index 000000000..2924ba6db --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WKTextCheckerGtk.h" + +#include "TextChecker.h" + +void WKTextCheckerSetSpellCheckingLanguages(const char* const* languages) +{ +#if ENABLE(SPELLCHECK) + Vector<String> spellCheckingLanguages; + for (size_t i = 0; languages[i]; ++i) + spellCheckingLanguages.append(String::fromUTF8(languages[i])); + WebKit::TextChecker::setSpellCheckingLanguages(spellCheckingLanguages); +#endif +} diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.h b/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.h new file mode 100644 index 000000000..1f6e55a66 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKTextCheckerGtk.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKTextCheckerGtk_h +#define WKTextCheckerGtk_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +WK_EXPORT void WKTextCheckerSetSpellCheckingLanguages(const char* const* languages); + +#ifdef __cplusplus +} +#endif + +#endif /* WKTextCheckerGtk_h */ diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKView.cpp b/Source/WebKit2/UIProcess/API/C/gtk/WKView.cpp index 6f0c04bf2..48c41ac77 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKView.cpp +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKView.cpp @@ -33,11 +33,10 @@ #include "WebKitWebViewBasePrivate.h" using namespace WebKit; -using namespace WebCore; -WKViewRef WKViewCreate(WKContextRef contextRef, WKPageGroupRef pageGroupRef) +WKViewRef WKViewCreate(WKPageConfigurationRef configuration) { - return toAPI(webkitWebViewBaseCreate(toImpl(contextRef), toImpl(pageGroupRef), nullptr)); + return toAPI(webkitWebViewBaseCreate(*toImpl(configuration))); } WKPageRef WKViewGetPage(WKViewRef viewRef) diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKView.h b/Source/WebKit2/UIProcess/API/C/gtk/WKView.h index 291dfe1b6..989ab66a2 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKView.h +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKView.h @@ -28,13 +28,13 @@ #ifndef WKView_h #define WKView_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { #endif -WK_EXPORT WKViewRef WKViewCreate(WKContextRef context, WKPageGroupRef pageGroup); +WK_EXPORT WKViewRef WKViewCreate(WKPageConfigurationRef configuration); WK_EXPORT WKPageRef WKViewGetPage(WKViewRef view); diff --git a/Source/WebKit2/UIProcess/API/C/gtk/WKViewPrivate.h b/Source/WebKit2/UIProcess/API/C/gtk/WKViewPrivate.h index 2c1b2d1f0..acabfd3af 100644 --- a/Source/WebKit2/UIProcess/API/C/gtk/WKViewPrivate.h +++ b/Source/WebKit2/UIProcess/API/C/gtk/WKViewPrivate.h @@ -26,7 +26,7 @@ #ifndef WKViewPrivate_h #define WKViewPrivate_h -#include <WebKit2/WKBase.h> +#include <WebKit/WKBase.h> #ifdef __cplusplus extern "C" { diff --git a/Source/WebKit2/UIProcess/API/C/WKBatteryStatus.cpp b/Source/WebKit2/UIProcess/API/C/soup/WKCookieManagerSoup.cpp index 953850d8b..86b31aa47 100644 --- a/Source/WebKit2/UIProcess/API/C/WKBatteryStatus.cpp +++ b/Source/WebKit2/UIProcess/API/C/soup/WKCookieManagerSoup.cpp @@ -24,36 +24,28 @@ */ #include "config.h" -#include "WKBatteryStatus.h" +#include "WKCookieManagerSoup.h" +#include "SoupCookiePersistentStorageType.h" #include "WKAPICast.h" - -#if ENABLE(BATTERY_STATUS) -#include "WebBatteryStatus.h" -#endif +#include "WebCookieManagerProxy.h" using namespace WebKit; -WKTypeID WKBatteryStatusGetTypeID() +inline SoupCookiePersistentStorageType toSoupCookiePersistentStorageType(WKCookieStorageType wkCookieStorageType) { -#if ENABLE(BATTERY_STATUS) - return toAPI(WebBatteryStatus::APIType); -#else - return 0; -#endif + switch (wkCookieStorageType) { + case kWKCookieStorageTypeText: + return SoupCookiePersistentStorageText; + case kWKCookieStorageTypeSQLite: + return SoupCookiePersistentStorageSQLite; + } + + ASSERT_NOT_REACHED(); + return SoupCookiePersistentStorageText; } -WKBatteryStatusRef WKBatteryStatusCreate(bool isCharging, double chargingTime, double dischargingTime, double level) +void WKCookieManagerSetCookiePersistentStorage(WKCookieManagerRef cookieManager, WKStringRef storagePath, WKCookieStorageType storageType) { -#if ENABLE(BATTERY_STATUS) - RefPtr<WebBatteryStatus> status = WebBatteryStatus::create(isCharging, chargingTime, dischargingTime, level); - return toAPI(status.release().leakRef()); -#else - UNUSED_PARAM(isCharging); - UNUSED_PARAM(chargingTime); - UNUSED_PARAM(dischargingTime); - UNUSED_PARAM(level); - return 0; -#endif + toImpl(cookieManager)->setCookiePersistentStorage(toWTFString(storagePath), storageType); } - diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKCookieManagerSoup.h b/Source/WebKit2/UIProcess/API/C/soup/WKCookieManagerSoup.h new file mode 100644 index 000000000..90cafca21 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/C/soup/WKCookieManagerSoup.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKCookieManagerSoup_h +#define WKCookieManagerSoup_h + +#include <WebKit/WKBase.h> + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + kWKCookieStorageTypeText = 0, + kWKCookieStorageTypeSQLite = 1 +}; +typedef uint32_t WKCookieStorageType; + +WK_EXPORT void WKCookieManagerSetCookiePersistentStorage(WKCookieManagerRef cookieManager, WKStringRef storagePath, WKCookieStorageType storageType); + +#ifdef __cplusplus +} +#endif + +#endif // WKCookieManagerSoup_h diff --git a/Source/WebKit2/UIProcess/API/C/soup/WKSoupCustomProtocolRequestManager.h b/Source/WebKit2/UIProcess/API/C/soup/WKSoupCustomProtocolRequestManager.h deleted file mode 100644 index cb0edc72f..000000000 --- a/Source/WebKit2/UIProcess/API/C/soup/WKSoupCustomProtocolRequestManager.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKSoupCustomProtocolRequestManager_h -#define WKSoupCustomProtocolRequestManager_h - -#include <WebKit2/WKBase.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*WKSoupCustomProtocolRequestManagerStartLoadingCallback)(WKSoupCustomProtocolRequestManagerRef soupManagerRef, uint64_t customProtocolID, WKURLRequestRef requestRef, const void* clientInfo); -typedef void (*WKSoupCustomProtocolRequestManagerStopLoadingCallback)(WKSoupCustomProtocolRequestManagerRef soupManagerRef, uint64_t customProtocolID, const void* clientInfo); - -typedef struct WKSoupCustomProtocolRequestManagerClientBase { - int version; - const void* clientInfo; -} WKSoupCustomProtocolRequestManagerClientBase; - -typedef struct WKSoupCustomProtocolRequestManagerClientV0 { - WKSoupCustomProtocolRequestManagerClientBase base; - - WKSoupCustomProtocolRequestManagerStartLoadingCallback startLoading; - WKSoupCustomProtocolRequestManagerStopLoadingCallback stopLoading; -} WKSoupCustomProtocolRequestManagerClientV0; - -WK_EXPORT WKTypeID WKSoupCustomProtocolRequestManagerGetTypeID(); - -WK_EXPORT void WKSoupCustomProtocolRequestManagerSetClient(WKSoupCustomProtocolRequestManagerRef, const WKSoupCustomProtocolRequestManagerClientBase*); - -#ifdef __cplusplus -} -#endif - -#endif /* WKSoupCustomProtocolRequestManager_h */ diff --git a/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.cpp b/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.cpp new file mode 100644 index 000000000..a855116f3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(COORDINATED_GRAPHICS) +#include "WKCoordinatedScene.h" + +#include "CoordinatedGraphicsScene.h" +#include "WKCoordinatedSceneAPICast.h" +#include <WebCore/TextureMapperLayer.h> + +using namespace WebKit; + +WK_EXPORT WKCoordinatedSceneLayer WKCoordinatedSceneFindScrollableContentsLayerAt(WKCoordinatedScene scene, WKPoint point) +{ + return toAPI(toImpl(scene)->findScrollableContentsLayerAt(WebCore::FloatPoint(point.x, point.y))); +} + +WK_EXPORT uint32_t WKCoordinatedSceneGetLayerID(WKCoordinatedSceneLayer layer) +{ + return toImpl(layer)->id(); +} + +WK_EXPORT void WKCoordinatedSceneScrollBy(WKCoordinatedSceneLayer layer, WKSize offset) +{ + toImpl(layer)->scrollBy(WebCore::FloatSize(offset.width, offset.height)); +} +#endif diff --git a/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.h b/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.h new file mode 100644 index 000000000..061212865 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/CoordinatedGraphics/WKCoordinatedScene.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKCoordinatedScene_h +#define WKCoordinatedScene_h + +#include <WebKit/WKGeometry.h> + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct OpaqueCGScene* WKCoordinatedScene; +typedef struct OpaqueCGLayer* WKCoordinatedSceneLayer; + +WK_EXPORT WKCoordinatedSceneLayer WKCoordinatedSceneFindScrollableContentsLayerAt(WKCoordinatedScene, WKPoint); +WK_EXPORT uint32_t WKCoordinatedSceneGetLayerID(WKCoordinatedSceneLayer); +WK_EXPORT void WKCoordinatedSceneScrollBy(WKCoordinatedSceneLayer, WKSize); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // WKCoordinatedScene_h diff --git a/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h b/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h index 6915dd334..19ae5943c 100644 --- a/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h +++ b/Source/WebKit2/UIProcess/API/cpp/WKRetainPtr.h @@ -26,8 +26,12 @@ #ifndef WKRetainPtr_h #define WKRetainPtr_h -#include <WebKit2/WKType.h> +#include <WebKit/WKType.h> #include <algorithm> +#include <wtf/GetPtr.h> +#include <wtf/HashFunctions.h> +#include <wtf/HashTraits.h> +#include <wtf/RefPtr.h> namespace WebKit { @@ -84,6 +88,15 @@ public: WKRelease(ptr); } + // Hash table deleted values, which are only constructed and never copied or destroyed. + WKRetainPtr(WTF::HashTableDeletedValueType) + : m_ptr(hashTableDeletedValue()) + { + } + + bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } + constexpr static T hashTableDeletedValue() { return reinterpret_cast<T>(-1); } + PtrType get() const { return m_ptr; } void clear() @@ -229,25 +242,42 @@ template<typename T, typename U> inline bool operator!=(T* a, const WKRetainPtr< return a != b.get(); } -#if defined(__GNUC__) && !(defined(__CC_ARM) || defined(__ARMCC__)) -#define WK_WARN_UNUSED_RETURN __attribute__((warn_unused_result)) -#else -#define WK_WARN_UNUSED_RETURN -#endif - -template<typename T> inline WKRetainPtr<T> adoptWK(T) WK_WARN_UNUSED_RETURN; - -#undef WK_WARN_UNUSED_RETURN - -template<typename T> inline WKRetainPtr<T> adoptWK(T o) +template<typename T> inline WKRetainPtr<T> adoptWK(T) __attribute__((warn_unused_result)); +template<typename T> inline WKRetainPtr<T> adoptWK(T o) { return WKRetainPtr<T>(AdoptWK, o); } +template<typename T> inline WKRetainPtr<T> retainWK(T ptr) +{ + return ptr; +} + } // namespace WebKit using WebKit::WKRetainPtr; using WebKit::AdoptWK; using WebKit::adoptWK; +using WebKit::retainWK; + +namespace WTF { + +template <typename T> struct IsSmartPtr<WKRetainPtr<T>> { + static const bool value = true; +}; + +template<typename P> struct DefaultHash<WKRetainPtr<P>> { + typedef PtrHash<WKRetainPtr<P>> Hash; +}; + +template<typename P> struct HashTraits<WKRetainPtr<P>> : SimpleClassHashTraits<WKRetainPtr<P>> { + static P emptyValue() { return nullptr; } + + typedef P PeekType; + static PeekType peek(const WKRetainPtr<P>& value) { return value.get(); } + static PeekType peek(P value) { return value; } +}; + +} // namespace WTF #endif // WKRetainPtr_h diff --git a/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp b/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp new file mode 100644 index 000000000..1bc99fb15 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "APIWebsiteDataStore.h" + +#include <WebCore/FileSystem.h> + +namespace API { + +String WebsiteDataStore::defaultApplicationCacheDirectory() +{ + return cacheDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "applications"); +} + +// FIXME: The other directories in this file are shared between all applications using WebKitGTK+. +// Why is only this directory namespaced to a particular application? +String WebsiteDataStore::defaultNetworkCacheDirectory() +{ + return cacheDirectoryFileSystemRepresentation(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_prgname()), "WebKitCache")); +} + +String WebsiteDataStore::defaultIndexedDBDatabaseDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "databases" G_DIR_SEPARATOR_S "indexeddb"); +} + +String WebsiteDataStore::defaultLocalStorageDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "localstorage"); +} + +String WebsiteDataStore::defaultMediaKeysStorageDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "mediakeys"); +} + +String WebsiteDataStore::defaultWebSQLDatabaseDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "databases"); +} + +String WebsiteDataStore::defaultResourceLoadStatisticsDirectory() +{ + return websiteDataDirectoryFileSystemRepresentation("webkitgtk" G_DIR_SEPARATOR_S "ResourceLoadStatistics"); +} + +String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String& directoryName) +{ + return WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_user_cache_dir()), directoryName); +} + +String WebsiteDataStore::websiteDataDirectoryFileSystemRepresentation(const String& directoryName) +{ + return WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(g_get_user_data_dir()), directoryName); +} + +WebKit::WebsiteDataStore::Configuration WebsiteDataStore::defaultDataStoreConfiguration() +{ + WebKit::WebsiteDataStore::Configuration configuration; + + configuration.applicationCacheDirectory = defaultApplicationCacheDirectory(); + configuration.networkCacheDirectory = defaultNetworkCacheDirectory(); + + configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory(); + configuration.localStorageDirectory = defaultLocalStorageDirectory(); + configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory(); + configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory(); + + return configuration; +} + +} // namespace API diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp index 872a274c9..815855091 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp @@ -31,16 +31,22 @@ #include "DrawingAreaProxyImpl.h" #include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" +#include "NativeWebWheelEvent.h" #include "NotImplemented.h" -#include "WebContext.h" +#include "WebColorPickerGtk.h" #include "WebContextMenuProxyGtk.h" #include "WebEventFactory.h" +#include "WebKitColorChooser.h" #include "WebKitWebViewBasePrivate.h" +#include "WebKitWebViewPrivate.h" #include "WebPageProxy.h" #include "WebPopupMenuProxyGtk.h" +#include "WebProcessPool.h" +#include <WebCore/CairoUtilities.h> #include <WebCore/Cursor.h> #include <WebCore/EventNames.h> #include <WebCore/GtkUtilities.h> +#include <WebCore/RefPtrCairo.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> @@ -53,47 +59,26 @@ PageClientImpl::PageClientImpl(GtkWidget* viewWidget) { } -PageClientImpl::~PageClientImpl() -{ -} - -void PageClientImpl::getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent& event, const AtomicString& eventType, Vector<WTF::String>& commandList) -{ - ASSERT(eventType == eventNames().keydownEvent || eventType == eventNames().keypressEvent); - - KeyBindingTranslator::EventType type = eventType == eventNames().keydownEvent ? - KeyBindingTranslator::KeyDown : KeyBindingTranslator::KeyPress; - m_keyBindingTranslator.getEditorCommandsForKeyEvent(const_cast<GdkEventKey*>(&event.nativeEvent()->key), type, commandList); -} - // PageClient's pure virtual functions std::unique_ptr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy() { - return std::make_unique<DrawingAreaProxyImpl>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))); + return std::make_unique<DrawingAreaProxyImpl>(*webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))); } -void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect) +void PageClientImpl::setViewNeedsDisplay(const WebCore::Region& region) { - gtk_widget_queue_draw_area(m_viewWidget, rect.x(), rect.y(), rect.width(), rect.height()); + gtk_widget_queue_draw_region(m_viewWidget, toCairoRegion(region).get()); } -void PageClientImpl::displayView() +void PageClientImpl::requestScroll(const WebCore::FloatPoint&, const WebCore::IntPoint&, bool) { notImplemented(); } -void PageClientImpl::scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) -{ - setViewNeedsDisplay(scrollRect); -} - WebCore::IntSize PageClientImpl::viewSize() { - if (!gtk_widget_get_realized(m_viewWidget)) - return IntSize(); - GtkAllocation allocation; - gtk_widget_get_allocation(m_viewWidget, &allocation); - return IntSize(allocation.width, allocation.height); + auto* drawingArea = static_cast<DrawingAreaProxyImpl*>(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))->drawingArea()); + return drawingArea ? drawingArea->size() : IntSize(); } bool PageClientImpl::isViewWindowActive() @@ -116,14 +101,14 @@ bool PageClientImpl::isViewInWindow() return webkitWebViewBaseIsInWindow(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::PageClientImpl::processDidCrash() +void PageClientImpl::PageClientImpl::processDidExit() { notImplemented(); } void PageClientImpl::didRelaunchProcess() { - notImplemented(); + webkitWebViewBaseDidRelaunchWebProcess(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) @@ -131,7 +116,7 @@ void PageClientImpl::toolTipChanged(const String&, const String& newToolTip) webkitWebViewBaseSetTooltipText(WEBKIT_WEB_VIEW_BASE(m_viewWidget), newToolTip.utf8().data()); } -void PageClientImpl::setCursor(const Cursor& cursor) +void PageClientImpl::setCursor(const WebCore::Cursor& cursor) { if (!gtk_widget_get_realized(m_viewWidget)) return; @@ -147,7 +132,7 @@ void PageClientImpl::setCursor(const Cursor& cursor) gdk_window_set_cursor(window, newCursor); } -void PageClientImpl::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves) +void PageClientImpl::setCursorHiddenUntilMouseMoves(bool /* hiddenUntilMouseMoves */) { notImplemented(); } @@ -189,7 +174,7 @@ FloatRect PageClientImpl::convertToUserSpace(const FloatRect& viewRect) return viewRect; } -IntPoint PageClientImpl::screenToWindow(const IntPoint& point) +IntPoint PageClientImpl::screenToRootView(const IntPoint& point) { IntPoint widgetPositionOnScreen = convertWidgetPointToScreenPoint(m_viewWidget, IntPoint()); IntPoint result(point); @@ -197,7 +182,7 @@ IntPoint PageClientImpl::screenToWindow(const IntPoint& point) return result; } -IntRect PageClientImpl::windowToScreen(const IntRect& rect) +IntRect PageClientImpl::rootViewToScreen(const IntRect& rect) { return IntRect(convertWidgetPointToScreenPoint(m_viewWidget, rect.location()), rect.size()); } @@ -214,49 +199,41 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool gtk_main_do_event(event.nativeEvent()); } -PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page) +RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page) { return WebPopupMenuProxyGtk::create(m_viewWidget, page); } -PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page) -{ - return WebContextMenuProxyGtk::create(m_viewWidget, page); -} - -#if ENABLE(INPUT_TYPE_COLOR) -PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) +std::unique_ptr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData) { - notImplemented(); - return 0; + return std::make_unique<WebContextMenuProxyGtk>(m_viewWidget, page, context, userData); } -#endif -void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) +RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy* page, const WebCore::Color& color, const WebCore::IntRect& rect) { - notImplemented(); + if (WEBKIT_IS_WEB_VIEW(m_viewWidget)) + return WebKitColorChooser::create(*page, color, rect); + return WebColorPickerGtk::create(*page, color, rect); } -#if USE(ACCELERATED_COMPOSITING) -void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext&) +void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - notImplemented(); + webkitWebViewBaseEnterAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget), layerTreeContext); } void PageClientImpl::exitAcceleratedCompositingMode() { - notImplemented(); + webkitWebViewBaseExitAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - notImplemented(); + webkitWebViewBaseUpdateAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget), layerTreeContext); } -#endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::pageClosed() { - notImplemented(); + webkitWebViewBasePageClosed(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } void PageClientImpl::preferencesDidChange() @@ -264,15 +241,27 @@ void PageClientImpl::preferencesDidChange() notImplemented(); } -void PageClientImpl::updateTextInputState() +void PageClientImpl::selectionDidChange() { webkitWebViewBaseUpdateTextInputState(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + if (WEBKIT_IS_WEB_VIEW(m_viewWidget)) + webkitWebViewSelectionDidChange(WEBKIT_WEB_VIEW(m_viewWidget)); +} + +void PageClientImpl::didChangeContentSize(const IntSize& size) +{ + webkitWebViewBaseSetContentsSize(WEBKIT_WEB_VIEW_BASE(m_viewWidget), size); } #if ENABLE(DRAG_SUPPORT) -void PageClientImpl::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) +void PageClientImpl::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage) { - webkitWebViewBaseStartDrag(WEBKIT_WEB_VIEW_BASE(m_viewWidget), dragData, dragImage); + WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(m_viewWidget); + webkitWebViewBaseDragAndDropHandler(webView).startDrag(WTFMove(selection), dragOperation, WTFMove(dragImage)); + + // A drag starting should prevent a double-click from happening. This might + // happen if a drag is followed very quickly by another click (like in the WTR). + webkitWebViewBaseResetClickCounter(webView); } #endif @@ -281,7 +270,7 @@ void PageClientImpl::handleDownloadRequest(DownloadProxy* download) webkitWebViewBaseHandleDownloadRequest(WEBKIT_WEB_VIEW_BASE(m_viewWidget), download); } -void PageClientImpl::didCommitLoadForMainFrame() +void PageClientImpl::didCommitLoadForMainFrame(const String& /* mimeType */, bool /* useCustomContentProvider */ ) { webkitWebViewBaseResetClickCounter(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } @@ -319,23 +308,30 @@ void PageClientImpl::exitFullScreen() webkitWebViewBaseExitFullScreen(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); } -void PageClientImpl::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) +void PageClientImpl::beganEnterFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) { notImplemented(); } -void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) +void PageClientImpl::beganExitFullScreen(const IntRect& /* initialFrame */, const IntRect& /* finalFrame */) { notImplemented(); } #endif // ENABLE(FULLSCREEN_API) +#if ENABLE(TOUCH_EVENTS) void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) { if (wasEventHandled) return; +#if HAVE(GTK_GESTURES) + GestureController& gestureController = webkitWebViewBaseGestureController(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + if (gestureController.handleEvent(event.nativeEvent())) + return; +#endif + // Emulate pointer events if unhandled. const GdkEvent* touchEvent = event.nativeEvent(); @@ -380,5 +376,77 @@ void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool w gtk_widget_event(m_viewWidget, pointerEvent.get()); } +#endif // ENABLE(TOUCH_EVENTS) + +void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& event) +{ + webkitWebViewBaseForwardNextWheelEvent(WEBKIT_WEB_VIEW_BASE(m_viewWidget)); + gtk_main_do_event(event.nativeEvent()); +} + +void PageClientImpl::didFinishLoadingDataForCustomContentProvider(const String&, const IPC::DataReference&) +{ +} + +void PageClientImpl::navigationGestureDidBegin() +{ +} + +void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&) +{ +} + +void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&) +{ +} + +void PageClientImpl::navigationGestureDidEnd() +{ +} + +void PageClientImpl::willRecordNavigationSnapshot(WebBackForwardListItem&) +{ +} + +void PageClientImpl::didRemoveNavigationGestureSnapshot() +{ +} + +void PageClientImpl::didFirstVisuallyNonEmptyLayoutForMainFrame() +{ +} + +void PageClientImpl::didFinishLoadForMainFrame() +{ +} + +void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) +{ +} + +void PageClientImpl::didChangeBackgroundColor() +{ +} + +void PageClientImpl::refView() +{ + g_object_ref(m_viewWidget); +} + +void PageClientImpl::derefView() +{ + g_object_unref(m_viewWidget); +} + +#if ENABLE(VIDEO) && USE(GSTREAMER) +bool PageClientImpl::decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest& request) +{ + if (!WEBKIT_IS_WEB_VIEW(m_viewWidget)) + return false; + + webkitWebViewRequestInstallMissingMediaPlugins(WEBKIT_WEB_VIEW(m_viewWidget), request); + return true; +} +#endif } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h index c420beec7..8d4a31070 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h @@ -1,3 +1,4 @@ + /* * Copyright (C) 2010 Apple Inc. All rights reserved. * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. @@ -29,13 +30,12 @@ #define PageClientImpl_h #include "DefaultUndoController.h" -#include "KeyBindingTranslator.h" #include "PageClient.h" #include "WebFullScreenManagerProxy.h" #include "WebPageProxy.h" -#include "WindowsKeyboardCodes.h" #include <WebCore/IntSize.h> #include <gtk/gtk.h> +#include <memory> namespace WebKit { @@ -48,87 +48,106 @@ class PageClientImpl : public PageClient #endif { public: - ~PageClientImpl(); - static PassOwnPtr<PageClientImpl> create(GtkWidget* viewWidget) - { - return adoptPtr(new PageClientImpl(viewWidget)); - } + explicit PageClientImpl(GtkWidget*); GtkWidget* viewWidget() { return m_viewWidget; } private: - explicit PageClientImpl(GtkWidget*); - // PageClient - virtual std::unique_ptr<DrawingAreaProxy> createDrawingAreaProxy() override; - virtual void setViewNeedsDisplay(const WebCore::IntRect&) override; - virtual void displayView() override; - virtual bool canScrollView() override { return false; } - virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) override; - virtual WebCore::IntSize viewSize() override; - virtual bool isViewWindowActive() override; - virtual bool isViewFocused() override; - virtual bool isViewVisible() override; - virtual bool isViewInWindow() override; - virtual void processDidCrash() override; - virtual void didRelaunchProcess() override; - virtual void pageClosed() override; - virtual void preferencesDidChange() override; - virtual void toolTipChanged(const WTF::String&, const WTF::String&) override; - virtual void setCursor(const WebCore::Cursor&) override; - virtual void setCursorHiddenUntilMouseMoves(bool) override; - virtual void didChangeViewportProperties(const WebCore::ViewportAttributes&) override; - virtual void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) override; - virtual void clearAllEditCommands() override; - virtual bool canUndoRedo(WebPageProxy::UndoOrRedo) override; - virtual void executeUndoRedo(WebPageProxy::UndoOrRedo) override; - virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) override; - virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override; - virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&) override; - virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) override; - virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override; - virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*) override; - virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*) override; + std::unique_ptr<DrawingAreaProxy> createDrawingAreaProxy() override; + void setViewNeedsDisplay(const WebCore::Region&) override; + void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, bool isProgrammaticScroll) override; + WebCore::IntSize viewSize() override; + bool isViewWindowActive() override; + bool isViewFocused() override; + bool isViewVisible() override; + bool isViewInWindow() override; + void processDidExit() override; + void didRelaunchProcess() override; + void pageClosed() override; + void preferencesDidChange() override; + void toolTipChanged(const WTF::String&, const WTF::String&) override; + void setCursor(const WebCore::Cursor&) override; + void setCursorHiddenUntilMouseMoves(bool) override; + void didChangeViewportProperties(const WebCore::ViewportAttributes&) override; + void registerEditCommand(PassRefPtr<WebEditCommandProxy>, WebPageProxy::UndoOrRedo) override; + void clearAllEditCommands() override; + bool canUndoRedo(WebPageProxy::UndoOrRedo) override; + void executeUndoRedo(WebPageProxy::UndoOrRedo) override; + WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) override; + WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) override; + WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) override; + WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) override; + void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) override; + RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) override; + std::unique_ptr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, const ContextMenuContextData&, const UserData&) override; #if ENABLE(INPUT_TYPE_COLOR) - virtual PassRefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, const WebCore::IntRect&) override; + RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& intialColor, const WebCore::IntRect&) override; #endif - virtual void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) override; - virtual void getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent&, const AtomicString&, Vector<WTF::String>&) override; - virtual void updateTextInputState() override; + void selectionDidChange() override; #if ENABLE(DRAG_SUPPORT) - virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) override; + void startDrag(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&& dragImage) override; #endif -#if USE(ACCELERATED_COMPOSITING) - virtual void enterAcceleratedCompositingMode(const LayerTreeContext&) override; - virtual void exitAcceleratedCompositingMode() override; - virtual void updateAcceleratedCompositingMode(const LayerTreeContext&) override; -#endif + void enterAcceleratedCompositingMode(const LayerTreeContext&) override; + void exitAcceleratedCompositingMode() override; + void updateAcceleratedCompositingMode(const LayerTreeContext&) override; - virtual void handleDownloadRequest(DownloadProxy*) override; - virtual void didCommitLoadForMainFrame() override; + void handleDownloadRequest(DownloadProxy*) override; + void didChangeContentSize(const WebCore::IntSize&) override; + void didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) override; + void didFailLoadForMainFrame() override { } // Auxiliary Client Creation #if ENABLE(FULLSCREEN_API) - virtual WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() final; + WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() final; #endif #if ENABLE(FULLSCREEN_API) // WebFullScreenManagerProxyClient - virtual void closeFullScreenManager() override; - virtual bool isFullScreen() override; - virtual void enterFullScreen() override; - virtual void exitFullScreen() override; - virtual void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; - virtual void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; + void closeFullScreenManager() override; + bool isFullScreen() override; + void enterFullScreen() override; + void exitFullScreen() override; + void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; + void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override; +#endif + + void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&) override; + + void navigationGestureDidBegin() override; + void navigationGestureWillEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd(bool, WebBackForwardListItem&) override; + void navigationGestureDidEnd() override; + void willRecordNavigationSnapshot(WebBackForwardListItem&) override; + void didRemoveNavigationGestureSnapshot() override; + + void didFirstVisuallyNonEmptyLayoutForMainFrame() override; + void didFinishLoadForMainFrame() override; + void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override; + +#if ENABLE(TOUCH_EVENTS) + void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override; +#endif + + void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) override; + + void didChangeBackgroundColor() override; + + void refView() override; + void derefView() override; + + void didRestoreScrollPosition() override { } + +#if ENABLE(VIDEO) && USE(GSTREAMER) + bool decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest&) override; #endif - virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override; + WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() override { return WebCore::UserInterfaceLayoutDirection::LTR; } // Members of PageClientImpl class GtkWidget* m_viewWidget; DefaultUndoController m_undoController; - WebCore::KeyBindingTranslator m_keyBindingTranslator; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp index 43cd83ac0..b0bb2b854 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.cpp @@ -25,12 +25,17 @@ #include "WebKitCredentialPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebView.h" +#include <glib/gi18n-lib.h> +#include <wtf/text/CString.h> using namespace WebKit; struct _WebKitAuthenticationDialogPrivate { GRefPtr<WebKitAuthenticationRequest> request; - GtkWidget* authWidget; + CredentialStorageMode credentialStorageMode; + GtkWidget* loginEntry; + GtkWidget* passwordEntry; + GtkWidget* rememberCheckButton; GtkWidget* defaultButton; unsigned long authenticationCancelledID; GRefPtr<GtkStyleContext> styleContext; @@ -41,7 +46,15 @@ WEBKIT_DEFINE_TYPE(WebKitAuthenticationDialog, webkit_authentication_dialog, GTK static void okButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) { WebKitAuthenticationDialogPrivate* priv = authDialog->priv; - WebKitCredential* credential = webkitCredentialCreate(webkitAuthenticationWidgetCreateCredential(WEBKIT_AUTHENTICATION_WIDGET(priv->authWidget))); + const char* username = gtk_entry_get_text(GTK_ENTRY(priv->loginEntry)); + const char* password = gtk_entry_get_text(GTK_ENTRY(priv->passwordEntry)); + bool rememberPassword = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->rememberCheckButton)); + + WebCore::CredentialPersistence persistence = rememberPassword && priv->credentialStorageMode == AllowPersistentStorage ? + WebCore::CredentialPersistencePermanent : WebCore::CredentialPersistenceForSession; + + // FIXME: Use a stack allocated WebKitCredential. + WebKitCredential* credential = webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), persistence)); webkit_authentication_request_authenticate(priv->request.get(), credential); webkit_credential_free(credential); gtk_widget_destroy(GTK_WIDGET(authDialog)); @@ -49,7 +62,7 @@ static void okButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) static void cancelButtonClicked(GtkButton*, WebKitAuthenticationDialog* authDialog) { - webkit_authentication_request_authenticate(authDialog->priv->request.get(), 0); + webkit_authentication_request_authenticate(authDialog->priv->request.get(), nullptr); gtk_widget_destroy(GTK_WIDGET(authDialog)); } @@ -58,34 +71,120 @@ static void authenticationCancelled(WebKitAuthenticationRequest*, WebKitAuthenti gtk_widget_destroy(GTK_WIDGET(authDialog)); } -static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog, CredentialStorageMode credentialStorageMode) +static GtkWidget* createLabelWithLineWrap(const char* text) +{ + GtkWidget* label = gtk_label_new(text); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_max_width_chars(GTK_LABEL(label), 40); + return label; +} + +static void webkitAuthenticationDialogInitialize(WebKitAuthenticationDialog* authDialog) { GtkWidget* frame = gtk_frame_new(0); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); GtkWidget* vBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_container_set_border_width(GTK_CONTAINER(vBox), 5); + gtk_container_set_border_width(GTK_CONTAINER(vBox), 12); + + GtkWidget* label = gtk_label_new(nullptr); + // Title of the HTTP authentication dialog. + GUniquePtr<char> title(g_strdup_printf("<b>%s</b>", _("Authentication Required"))); + gtk_label_set_markup(GTK_LABEL(label), title.get()); + gtk_widget_set_halign(label, GTK_ALIGN_CENTER); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(vBox), label, FALSE, FALSE, 0); GtkWidget* buttonBox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); gtk_container_set_border_width(GTK_CONTAINER(buttonBox), 5); gtk_box_set_spacing(GTK_BOX(buttonBox), 6); - GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + GtkWidget* button = gtk_button_new_with_mnemonic(_("_Cancel")); g_signal_connect(button, "clicked", G_CALLBACK(cancelButtonClicked), authDialog); gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); gtk_widget_show(button); - button = gtk_button_new_from_stock(GTK_STOCK_OK); - authDialog->priv->defaultButton = button; + WebKitAuthenticationDialogPrivate* priv = authDialog->priv; + button = gtk_button_new_with_mnemonic(_("_Authenticate")); + priv->defaultButton = button; g_signal_connect(button, "clicked", G_CALLBACK(okButtonClicked), authDialog); gtk_widget_set_can_default(button, TRUE); gtk_box_pack_end(GTK_BOX(buttonBox), button, FALSE, TRUE, 0); gtk_widget_show(button); - authDialog->priv->authWidget = webkitAuthenticationWidgetNew(webkitAuthenticationRequestGetAuthenticationChallenge(authDialog->priv->request.get())->core(), credentialStorageMode); - gtk_box_pack_start(GTK_BOX(vBox), authDialog->priv->authWidget, TRUE, TRUE, 0); - gtk_widget_show(authDialog->priv->authWidget); + GtkWidget* authBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); + gtk_container_set_border_width(GTK_CONTAINER(authBox), 5); + + const WebCore::AuthenticationChallenge& challenge = webkitAuthenticationRequestGetAuthenticationChallenge(priv->request.get())->core(); + // Prompt on the HTTP authentication dialog. + GUniquePtr<char> prompt(g_strdup_printf(_("Authentication required by %s:%i"), + challenge.protectionSpace().host().utf8().data(), challenge.protectionSpace().port())); + label = createLabelWithLineWrap(prompt.get()); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(authBox), label, FALSE, FALSE, 0); + + String realm = challenge.protectionSpace().realm(); + if (!realm.isEmpty()) { + // Label on the HTTP authentication dialog. %s is a (probably English) message from the website. + GUniquePtr<char> message(g_strdup_printf(_("The site says: “%s”"), realm.utf8().data())); + label = createLabelWithLineWrap(message.get()); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(authBox), label, FALSE, FALSE, 0); + } + + // Check button on the HTTP authentication dialog. + priv->rememberCheckButton = gtk_check_button_new_with_mnemonic(_("_Remember password")); + gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(priv->rememberCheckButton))), TRUE); + + priv->loginEntry = gtk_entry_new(); + gtk_widget_set_hexpand(priv->loginEntry, TRUE); + gtk_entry_set_activates_default(GTK_ENTRY(priv->loginEntry), TRUE); + gtk_widget_show(priv->loginEntry); + + // Entry on the HTTP authentication dialog. + GtkWidget* loginLabel = gtk_label_new_with_mnemonic(_("_Username")); + gtk_label_set_mnemonic_widget(GTK_LABEL(loginLabel), priv->loginEntry); + gtk_widget_set_halign(loginLabel, GTK_ALIGN_END); + gtk_style_context_add_class(gtk_widget_get_style_context(loginLabel), GTK_STYLE_CLASS_DIM_LABEL); + gtk_widget_show(loginLabel); + + priv->passwordEntry = gtk_entry_new(); + gtk_widget_set_hexpand(priv->passwordEntry, TRUE); + gtk_entry_set_activates_default(GTK_ENTRY(priv->passwordEntry), TRUE); + gtk_widget_show(priv->passwordEntry); + + // Entry on the HTTP authentication dialog. + GtkWidget* passwordLabel = gtk_label_new_with_mnemonic(_("_Password")); + gtk_label_set_mnemonic_widget(GTK_LABEL(passwordLabel), priv->passwordEntry); + gtk_widget_set_halign(passwordLabel, GTK_ALIGN_END); + gtk_style_context_add_class(gtk_widget_get_style_context(passwordLabel), GTK_STYLE_CLASS_DIM_LABEL); + gtk_widget_show(passwordLabel); + + GtkWidget* grid = gtk_grid_new(); + gtk_grid_set_column_spacing(GTK_GRID(grid), 6); + gtk_grid_set_row_spacing(GTK_GRID(grid), 6); + gtk_grid_attach(GTK_GRID(grid), loginLabel, 0, 0, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->loginEntry, 1, 0, 1, 1); + gtk_grid_attach(GTK_GRID(grid), passwordLabel, 0, 1, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->passwordEntry, 1, 1, 1, 1); + gtk_grid_attach(GTK_GRID(grid), priv->rememberCheckButton, 1, 2, 1, 1); + gtk_widget_show(grid); + gtk_box_pack_start(GTK_BOX(authBox), grid, FALSE, FALSE, 0); + + gtk_entry_set_visibility(GTK_ENTRY(priv->passwordEntry), FALSE); + gtk_widget_set_visible(priv->rememberCheckButton, priv->credentialStorageMode != DisallowPersistentStorage && !realm.isEmpty()); + + const WebCore::Credential& credentialFromPersistentStorage = challenge.proposedCredential(); + if (!credentialFromPersistentStorage.isEmpty()) { + gtk_entry_set_text(GTK_ENTRY(priv->loginEntry), credentialFromPersistentStorage.user().utf8().data()); + gtk_entry_set_text(GTK_ENTRY(priv->passwordEntry), credentialFromPersistentStorage.password().utf8().data()); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->rememberCheckButton), TRUE); + } + + gtk_box_pack_start(GTK_BOX(vBox), authBox, TRUE, TRUE, 0); + gtk_widget_show(authBox); gtk_box_pack_end(GTK_BOX(vBox), buttonBox, FALSE, TRUE, 0); gtk_widget_show(buttonBox); @@ -103,10 +202,19 @@ static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr) { WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; - gtk_style_context_save(priv->styleContext.get()); - gtk_style_context_add_class(priv->styleContext.get(), GTK_STYLE_CLASS_BACKGROUND); - gtk_render_background(priv->styleContext.get(), cr, 0, 0, gtk_widget_get_allocated_width(widget), gtk_widget_get_allocated_height(widget)); - gtk_style_context_restore(priv->styleContext.get()); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba(cr, 0, 0, 0, 0.5); + cairo_paint(cr); + + if (GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget))) { + GtkAllocation allocation; + gtk_widget_get_allocation(child, &allocation); + + gtk_style_context_save(priv->styleContext.get()); + gtk_style_context_add_class(priv->styleContext.get(), GTK_STYLE_CLASS_BACKGROUND); + gtk_render_background(priv->styleContext.get(), cr, allocation.x, allocation.y, allocation.width, allocation.height); + gtk_style_context_restore(priv->styleContext.get()); + } GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->draw(widget, cr); @@ -116,11 +224,33 @@ static gboolean webkitAuthenticationDialogDraw(GtkWidget* widget, cairo_t* cr) static void webkitAuthenticationDialogMap(GtkWidget* widget) { WebKitAuthenticationDialogPrivate* priv = WEBKIT_AUTHENTICATION_DIALOG(widget)->priv; + gtk_widget_grab_focus(priv->loginEntry); gtk_widget_grab_default(priv->defaultButton); GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->map(widget); } +static void webkitAuthenticationDialogSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) +{ + GTK_WIDGET_CLASS(webkit_authentication_dialog_parent_class)->size_allocate(widget, allocation); + + GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget)); + if (!child) + return; + + GtkRequisition naturalSize; + gtk_widget_get_preferred_size(child, 0, &naturalSize); + + GtkAllocation childAllocation; + gtk_widget_get_allocation(child, &childAllocation); + + childAllocation.x += (allocation->width - naturalSize.width) / 2; + childAllocation.y += (allocation->height - naturalSize.height) / 2; + childAllocation.width = naturalSize.width; + childAllocation.height = naturalSize.height; + gtk_widget_size_allocate(child, &childAllocation); +} + static void webkitAuthenticationDialogConstructed(GObject* object) { G_OBJECT_CLASS(webkit_authentication_dialog_parent_class)->constructed(object); @@ -153,12 +283,14 @@ static void webkit_authentication_dialog_class_init(WebKitAuthenticationDialogCl GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(klass); widgetClass->draw = webkitAuthenticationDialogDraw; widgetClass->map = webkitAuthenticationDialogMap; + widgetClass->size_allocate = webkitAuthenticationDialogSizeAllocate; } GtkWidget* webkitAuthenticationDialogNew(WebKitAuthenticationRequest* request, CredentialStorageMode mode) { WebKitAuthenticationDialog* authDialog = WEBKIT_AUTHENTICATION_DIALOG(g_object_new(WEBKIT_TYPE_AUTHENTICATION_DIALOG, NULL)); authDialog->priv->request = request; - webkitAuthenticationDialogInitialize(authDialog, mode); + authDialog->priv->credentialStorageMode = mode; + webkitAuthenticationDialogInitialize(authDialog); return GTK_WIDGET(authDialog); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h index e5e62a7bd..0e5071f53 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationDialog.h @@ -21,10 +21,13 @@ #define WebKitAuthenticationDialog_h #include "WebKitAuthenticationRequest.h" -#include "WebKitAuthenticationWidget.h" -#include "WebKitWebView.h" #include <gtk/gtk.h> +enum CredentialStorageMode { + AllowPersistentStorage, // The user is asked whether to store credential information. + DisallowPersistentStorage // Credential information is only kept in the session. +}; + G_BEGIN_DECLS #define WEBKIT_TYPE_AUTHENTICATION_DIALOG (webkit_authentication_dialog_get_type()) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp index 6f0c3707e..8e2e72561 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAuthenticationRequest.cpp @@ -67,18 +67,35 @@ struct _WebKitAuthenticationRequestPrivate { static guint signals[LAST_SIGNAL] = { 0, }; -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_DEFAULT, ProtectionSpaceAuthenticationSchemeDefault); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC, ProtectionSpaceAuthenticationSchemeHTTPBasic); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST, ProtectionSpaceAuthenticationSchemeHTTPDigest); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM, ProtectionSpaceAuthenticationSchemeHTMLForm); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_NTLM, ProtectionSpaceAuthenticationSchemeNTLM); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE, ProtectionSpaceAuthenticationSchemeNegotiate); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED, ProtectionSpaceAuthenticationSchemeClientCertificateRequested); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED, ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN, ProtectionSpaceAuthenticationSchemeUnknown); - WEBKIT_DEFINE_TYPE(WebKitAuthenticationRequest, webkit_authentication_request, G_TYPE_OBJECT) +static inline WebKitAuthenticationScheme toWebKitAuthenticationScheme(WebCore::ProtectionSpaceAuthenticationScheme coreScheme) +{ + switch (coreScheme) { + case WebCore::ProtectionSpaceAuthenticationSchemeDefault: + return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT; + case WebCore::ProtectionSpaceAuthenticationSchemeHTTPBasic: + return WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC; + case WebCore::ProtectionSpaceAuthenticationSchemeHTTPDigest: + return WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST; + case WebCore::ProtectionSpaceAuthenticationSchemeHTMLForm: + return WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM; + case WebCore::ProtectionSpaceAuthenticationSchemeNTLM: + return WEBKIT_AUTHENTICATION_SCHEME_NTLM; + case WebCore::ProtectionSpaceAuthenticationSchemeNegotiate: + return WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE; + case WebCore::ProtectionSpaceAuthenticationSchemeClientCertificateRequested: + return WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED; + case WebCore::ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested: + return WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED; + case WebCore::ProtectionSpaceAuthenticationSchemeUnknown: + return WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_AUTHENTICATION_SCHEME_DEFAULT; + } +} + static void webkitAuthenticationRequestDispose(GObject* object) { WebKitAuthenticationRequest* request = WEBKIT_AUTHENTICATION_REQUEST(object); @@ -144,7 +161,7 @@ gboolean webkit_authentication_request_can_save_credentials(WebKitAuthentication { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), FALSE); -#if ENABLE(CREDENTIAL_STORAGE) +#if USE(LIBSECRET) return !request->priv->privateBrowsingEnabled; #else return FALSE; @@ -168,7 +185,7 @@ WebKitCredential* webkit_authentication_request_get_proposed_credential(WebKitAu { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), 0); - const WebCore::Credential& credential = request->priv->authenticationChallenge->proposedCredential()->core(); + const WebCore::Credential& credential = request->priv->authenticationChallenge->proposedCredential()->credential(); if (credential.isEmpty()) return 0; @@ -244,7 +261,7 @@ WebKitAuthenticationScheme webkit_authentication_request_get_scheme(WebKitAuthen { g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN); - return static_cast<WebKitAuthenticationScheme>(request->priv->authenticationChallenge->protectionSpace()->authenticationScheme()); + return toWebKitAuthenticationScheme(request->priv->authenticationChallenge->protectionSpace()->authenticationScheme()); } /** @@ -295,8 +312,11 @@ void webkit_authentication_request_authenticate(WebKitAuthenticationRequest* req { g_return_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request)); - RefPtr<WebCredential> webCredential = credential ? WebCredential::create(webkitCredentialGetCredential(credential)) : 0; - request->priv->authenticationChallenge->listener()->useCredential(webCredential.get()); + if (credential) + request->priv->authenticationChallenge->listener()->useCredential(WebCredential::create(webkitCredentialGetCredential(credential)).ptr()); + else + request->priv->authenticationChallenge->listener()->useCredential(nullptr); + request->priv->handledRequest = true; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h b/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h new file mode 100644 index 000000000..c32c099c0 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitAutocleanups_h +#define WebKitAutocleanups_h + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +#ifndef __GI_SCANNER__ + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitAuthenticationRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitBackForwardList, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitBackForwardListItem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitColorChooserRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitContextMenu, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitContextMenuItem, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitCookieManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitDownload, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitEditorState, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFaviconDatabase, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFileChooserRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFindController, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitFormSubmissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitGeolocationPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitHitTestResult, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitInstallMissingMediaPluginsPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationPolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNotification, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNotificationPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPlugin, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintCustomWidget, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintOperation, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitResponsePolicyDecision, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSecurityManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSettings, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURIRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURIResponse, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitURISchemeRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserContentManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserMediaPermissionRequest, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebContext, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebInspector, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebResource, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebView, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebsiteDataManager, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWindowProperties, g_object_unref) + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitCredential, webkit_credential_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitJavascriptResult, webkit_javascript_result_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitMimeInfo, webkit_mime_info_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNavigationAction, webkit_navigation_action_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitNetworkProxySettings, webkit_network_proxy_settings_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSecurityOrigin, webkit_security_origin_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserScript, webkit_user_script_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitUserStyleSheet, webkit_user_style_sheet_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebsiteData, webkit_website_data_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitWebViewSessionState, webkit_web_view_session_state_unref) + +#endif // __GI_SCANNER__ +#endif // G_DEFINE_AUTOPTR_CLEANUP_FUNC + +#endif // WebKitAutocleanups_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp index 6cbddc8aa..0762d0280 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardList.cpp @@ -23,7 +23,7 @@ #include "WebKitBackForwardListPrivate.h" #include "WebKitMarshal.h" #include "WebKitPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> /** * SECTION: WebKitBackForwardList @@ -128,20 +128,25 @@ WebKitBackForwardList* webkitBackForwardListCreate(WebBackForwardList* backForwa return list; } -void webkitBackForwardListChanged(WebKitBackForwardList* backForwardList, WebBackForwardListItem* webAddedItem, API::Array* webRemovedItems) +void webkitBackForwardListChanged(WebKitBackForwardList* backForwardList, WebBackForwardListItem* webAddedItem, const Vector<RefPtr<WebBackForwardListItem>>& webRemovedItems) { WebKitBackForwardListItem* addedItem = webkitBackForwardListGetOrCreateItem(backForwardList, webAddedItem); - GList* removedItems = 0; + GList* removedItems = nullptr; - size_t removedItemsSize = webRemovedItems ? webRemovedItems->size() : 0; WebKitBackForwardListPrivate* priv = backForwardList->priv; - for (size_t i = 0; i < removedItemsSize; ++i) { - WebBackForwardListItem* webItem = static_cast<WebBackForwardListItem*>(webRemovedItems->at(i)); - removedItems = g_list_prepend(removedItems, g_object_ref(G_OBJECT(priv->itemsMap.get(webItem).get()))); - priv->itemsMap.remove(webItem); + for (auto& webItem : webRemovedItems) { + // After a session restore, we still don't have wrappers for the newly added items, so it would be possible that + // the removed items are not in the map. In that case we create a wrapper now to pass it the changed signal, but + // without adding it to the item map. See https://bugs.webkit.org/show_bug.cgi?id=153233. + GRefPtr<WebKitBackForwardListItem> removedItem = priv->itemsMap.get(webItem.get()); + if (removedItem) { + removedItems = g_list_prepend(removedItems, g_object_ref(removedItem.get())); + priv->itemsMap.remove(webItem.get()); + } else + removedItems = g_list_prepend(removedItems, webkitBackForwardListItemGetOrCreate(webItem.get())); } - g_signal_emit(backForwardList, signals[CHANGED], 0, addedItem, removedItems, NULL); + g_signal_emit(backForwardList, signals[CHANGED], 0, addedItem, removedItems, nullptr); g_list_free_full(removedItems, static_cast<GDestroyNotify>(g_object_unref)); } @@ -252,8 +257,8 @@ GList* webkit_back_forward_list_get_back_list_with_limit(WebKitBackForwardList* g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0); WebKitBackForwardListPrivate* priv = backForwardList->priv; - RefPtr<API::Array> apiArray = priv->backForwardItems->backListAsAPIArrayWithLimit(limit); - return webkitBackForwardListCreateList(backForwardList, apiArray.get()); + Ref<API::Array> apiArray = priv->backForwardItems->backListAsAPIArrayWithLimit(limit); + return webkitBackForwardListCreateList(backForwardList, apiArray.ptr()); } /** @@ -283,6 +288,6 @@ GList* webkit_back_forward_list_get_forward_list_with_limit(WebKitBackForwardLis g_return_val_if_fail(WEBKIT_IS_BACK_FORWARD_LIST(backForwardList), 0); WebKitBackForwardListPrivate* priv = backForwardList->priv; - RefPtr<API::Array> apiArray = priv->backForwardItems->forwardListAsAPIArrayWithLimit(limit); - return webkitBackForwardListCreateList(backForwardList, apiArray.get()); + Ref<API::Array> apiArray = priv->backForwardItems->forwardListAsAPIArrayWithLimit(limit); + return webkitBackForwardListCreateList(backForwardList, apiArray.ptr()); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp index ae18b05ec..b295c9904 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListItem.cpp @@ -23,7 +23,8 @@ #include "WebKitBackForwardListPrivate.h" #include "WebKitPrivate.h" #include <wtf/HashMap.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -48,7 +49,7 @@ struct _WebKitBackForwardListItemPrivate { WEBKIT_DEFINE_TYPE(WebKitBackForwardListItem, webkit_back_forward_list_item, G_TYPE_INITIALLY_UNOWNED) -static void webkit_back_forward_list_item_class_init(WebKitBackForwardListItemClass* listItemClass) +static void webkit_back_forward_list_item_class_init(WebKitBackForwardListItemClass*) { } @@ -56,13 +57,13 @@ typedef HashMap<WebBackForwardListItem*, WebKitBackForwardListItem*> HistoryItem static HistoryItemsMap& historyItemsMap() { - DEFINE_STATIC_LOCAL(HistoryItemsMap, itemsMap, ()); + static NeverDestroyed<HistoryItemsMap> itemsMap; return itemsMap; } static void webkitBackForwardListItemFinalized(gpointer webListItem, GObject* finalizedListItem) { - ASSERT(G_OBJECT(historyItemsMap().get(static_cast<WebBackForwardListItem*>(webListItem))) == finalizedListItem); + ASSERT_UNUSED(finalizedListItem, G_OBJECT(historyItemsMap().get(static_cast<WebBackForwardListItem*>(webListItem))) == finalizedListItem); historyItemsMap().remove(static_cast<WebBackForwardListItem*>(webListItem)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h index ef9052dc9..88ec1d01c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitBackForwardListPrivate.h @@ -32,6 +32,6 @@ WebKitBackForwardList* webkitBackForwardListCreate(WebKit::WebBackForwardList*); WebKitBackForwardListItem* webkitBackForwardListItemGetOrCreate(WebKit::WebBackForwardListItem*); WebKit::WebBackForwardListItem* webkitBackForwardListItemGetItem(WebKitBackForwardListItem*); -void webkitBackForwardListChanged(WebKitBackForwardList*, WebKit::WebBackForwardListItem* webAddedItem, API::Array* webRemovedItems); +void webkitBackForwardListChanged(WebKitBackForwardList*, WebKit::WebBackForwardListItem* webAddedItem, const Vector<RefPtr<WebKit::WebBackForwardListItem>>&); #endif // WebKitBackForwardListPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp deleted file mode 100644 index 3c1e4c6a8..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitBatteryProvider.h" - -#if ENABLE(BATTERY_STATUS) - -#include "WebBatteryManagerProxy.h" -#include "WebBatteryStatus.h" -#include <limits> - -using namespace WebKit; - -static inline WebKitBatteryProvider* toBatteryProvider(const void* clientInfo) -{ - return static_cast<WebKitBatteryProvider*>(const_cast<void*>(clientInfo)); -} - -static void startUpdatingCallback(WKBatteryManagerRef batteryManager, const void* clientInfo) -{ - toBatteryProvider(clientInfo)->startUpdating(); -} - -static void stopUpdatingCallback(WKBatteryManagerRef batteryManager, const void* clientInfo) -{ - toBatteryProvider(clientInfo)->stopUpdating(); -} - -PassRefPtr<WebKitBatteryProvider> WebKitBatteryProvider::create(WebBatteryManagerProxy* batteryManager) -{ - return adoptRef(new WebKitBatteryProvider(batteryManager)); -} - -WebKitBatteryProvider::WebKitBatteryProvider(WebBatteryManagerProxy* batteryManager) - : m_batteryManager(batteryManager) - , m_provider(this) -{ - ASSERT(batteryManager); - - WKBatteryProviderV0 wkBatteryProvider = { - { - 0, // version - this // clientInfo - }, - startUpdatingCallback, - stopUpdatingCallback - }; - WKBatteryManagerSetProvider(toAPI(batteryManager), &wkBatteryProvider.base); -} - -WebKitBatteryProvider::~WebKitBatteryProvider() -{ - m_provider.stopUpdating(); -} - -void WebKitBatteryProvider::startUpdating() -{ - m_provider.startUpdating(); -} - -void WebKitBatteryProvider::stopUpdating() -{ - m_provider.stopUpdating(); -} - -void WebKitBatteryProvider::updateBatteryStatus(WebCore::BatteryProviderUPowerStatus status, double secondsRemaining, double batteryLevel) -{ - RefPtr<WebBatteryStatus> batteryStatus; - - switch (status) { - case WebCore::NotAvailable: - // When an implementation cannot report battery status, the default values should be used. - batteryStatus = WebBatteryStatus::create(true, std::numeric_limits<double>::infinity(), - std::numeric_limits<double>::infinity(), 1.0); - break; - case WebCore::Charging: - batteryStatus = WebBatteryStatus::create(true, secondsRemaining, 0, batteryLevel); - break; - case WebCore::Discharging: - batteryStatus = WebBatteryStatus::create(false, 0, secondsRemaining, batteryLevel); - break; - default: - ASSERT_NOT_REACHED(); - } - - m_batteryManager->providerUpdateBatteryStatus(batteryStatus.get()); -} - -#endif // ENABLE(BATTERY_STATUS) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h deleted file mode 100644 index 7f05db6c7..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitBatteryProvider.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebKitBatteryProvider_h -#define WebKitBatteryProvider_h - -#if ENABLE(BATTERY_STATUS) - -#include "WebKitPrivate.h" -#include <WebCore/BatteryProviderUPowerClient.h> -#include <WebCore/BatteryProviderUPower.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> - -namespace WebKit { - -class WebKitBatteryProvider : public RefCounted<WebKitBatteryProvider>, public WebCore::BatteryProviderUPowerClient { -public: - static PassRefPtr<WebKitBatteryProvider> create(WebBatteryManagerProxy*); - virtual ~WebKitBatteryProvider(); - - void startUpdating(); - void stopUpdating(); - -private: - WebKitBatteryProvider(WebBatteryManagerProxy*); - - // WebCore::BatteryProviderUPowerClient - virtual void updateBatteryStatus(WebCore::BatteryProviderUPowerStatus, double secondsRemaining, double batteryLevel); - - RefPtr<WebBatteryManagerProxy> m_batteryManager; - WebCore::BatteryProviderUPower m_provider; -}; - -} - -#endif // ENABLE(BATTERY_STATUS) - -#endif // WebKitBatteryProvider_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp deleted file mode 100644 index 12df1aaca..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitCertificateInfo.h" - -#include "WebKitCertificateInfoPrivate.h" -#include <wtf/text/CString.h> - -using namespace WebKit; -using namespace WebCore; - -/** - * SECTION: WebKitCertificateInfo - * @Short_description: Boxed type to encapsulate TLS certificate information - * @Title: WebKitCertificateInfo - * @See_also: #WebKitWebView, #WebKitWebContext - * - * When a client loads a page over HTTPS where there is an underlying TLS error - * WebKit will fire a #WebKitWebView::load-failed-with-tls-errors signal with a - * #WebKitCertificateInfo and the host of the failing URI. - * - * To handle this signal asynchronously you should make a copy of the - * #WebKitCertificateInfo with webkit_certificate_info_copy(). - */ - -G_DEFINE_BOXED_TYPE(WebKitCertificateInfo, webkit_certificate_info, webkit_certificate_info_copy, webkit_certificate_info_free) - -const CertificateInfo& webkitCertificateInfoGetCertificateInfo(WebKitCertificateInfo* info) -{ - ASSERT(info); - return info->certificateInfo; -} - -/** - * webkit_certificate_info_copy: - * @info: a #WebKitCertificateInfo - * - * Make a copy of the #WebKitCertificateInfo. - * - * Returns: (transfer full): A copy of passed in #WebKitCertificateInfo. - * - * Since: 2.4 - */ -WebKitCertificateInfo* webkit_certificate_info_copy(WebKitCertificateInfo* info) -{ - g_return_val_if_fail(info, 0); - - WebKitCertificateInfo* copy = g_slice_new0(WebKitCertificateInfo); - new (copy) WebKitCertificateInfo(info); - return copy; -} - -/** - * webkit_certificate_info_free: - * @info: a #WebKitCertificateInfo - * - * Free the #WebKitCertificateInfo. - * - * Since: 2.4 - */ -void webkit_certificate_info_free(WebKitCertificateInfo* info) -{ - g_return_if_fail(info); - - info->~WebKitCertificateInfo(); - g_slice_free(WebKitCertificateInfo, info); -} - -/** - * webkit_certificate_info_get_tls_certificate: - * @info: a #WebKitCertificateInfo - * - * Get the #GTlsCertificate associated with this - * #WebKitCertificateInfo. - * - * Returns: (transfer none): The certificate of @info. - * - * Since: 2.4 - */ -GTlsCertificate* webkit_certificate_info_get_tls_certificate(WebKitCertificateInfo *info) -{ - g_return_val_if_fail(info, 0); - - return info->certificateInfo.certificate(); -} - -/** - * webkit_certificate_info_get_tls_errors: - * @info: a #WebKitCertificateInfo - * - * Get the #GTlsCertificateFlags verification status associated with this - * #WebKitCertificateInfo. - * - * Returns: The verification status of @info. - * - * Since: 2.4 - */ -GTlsCertificateFlags webkit_certificate_info_get_tls_errors(WebKitCertificateInfo *info) -{ - g_return_val_if_fail(info, static_cast<GTlsCertificateFlags>(0)); - - return info->certificateInfo.tlsErrors(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp new file mode 100644 index 000000000..71919d8f6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitColorChooser.h" + +#include "WebKitColorChooserRequestPrivate.h" +#include "WebKitWebViewPrivate.h" +#include <WebCore/Color.h> +#include <WebCore/IntRect.h> + +using namespace WebCore; + +namespace WebKit { + +Ref<WebKitColorChooser> WebKitColorChooser::create(WebPageProxy& page, const WebCore::Color& initialColor, const WebCore::IntRect& rect) +{ + return adoptRef(*new WebKitColorChooser(page, initialColor, rect)); +} + +WebKitColorChooser::WebKitColorChooser(WebPageProxy& page, const Color& initialColor, const IntRect& rect) + : WebColorPickerGtk(page, initialColor, rect) + , m_elementRect(rect) +{ +} + +WebKitColorChooser::~WebKitColorChooser() +{ + endPicker(); +} + +void WebKitColorChooser::endPicker() +{ + if (!m_request) { + WebColorPickerGtk::endPicker(); + return; + } + + webkit_color_chooser_request_finish(m_request.get()); +} + +void WebKitColorChooser::colorChooserRequestFinished(WebKitColorChooserRequest*, WebKitColorChooser* colorChooser) +{ + colorChooser->m_request = nullptr; +} + +void WebKitColorChooser::colorChooserRequestRGBAChanged(WebKitColorChooserRequest* request, GParamSpec*, WebKitColorChooser* colorChooser) +{ + GdkRGBA rgba; + webkit_color_chooser_request_get_rgba(request, &rgba); + colorChooser->didChooseColor(rgba); +} + +void WebKitColorChooser::showColorPicker(const Color& color) +{ + m_initialColor = color; + GRefPtr<WebKitColorChooserRequest> request = adoptGRef(webkitColorChooserRequestCreate(this)); + g_signal_connect(request.get(), "notify::rgba", G_CALLBACK(WebKitColorChooser::colorChooserRequestRGBAChanged), this); + g_signal_connect(request.get(), "finished", G_CALLBACK(WebKitColorChooser::colorChooserRequestFinished), this); + + if (webkitWebViewEmitRunColorChooser(WEBKIT_WEB_VIEW(m_webView), request.get())) + m_request = request; + else + WebColorPickerGtk::showColorPicker(color); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h new file mode 100644 index 000000000..0dc9762c6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooser.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitColorChooser_h +#define WebKitColorChooser_h + +#include "WebColorPickerGtk.h" +#include "WebKitPrivate.h" +#include <wtf/glib/GRefPtr.h> + +typedef struct _WebKitColorChooserRequest WebKitColorChooserRequest; + +namespace WebCore { +class Color; +class IntRect; +} + +namespace WebKit { + +class WebKitColorChooser final : public WebColorPickerGtk { +public: + static Ref<WebKitColorChooser> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + virtual ~WebKitColorChooser(); + + const WebCore::IntRect& elementRect() const { return m_elementRect; } + +private: + WebKitColorChooser(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + + void endPicker() override; + void showColorPicker(const WebCore::Color&) override; + + static void colorChooserRequestFinished(WebKitColorChooserRequest*, WebKitColorChooser*); + static void colorChooserRequestRGBAChanged(WebKitColorChooserRequest*, GParamSpec*, WebKitColorChooser*); + + GRefPtr<WebKitColorChooserRequest> m_request; + WebCore::IntRect m_elementRect; +}; + +} // namespace WebKit + +#endif // WebKitColorChooser_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp new file mode 100644 index 000000000..98dad2514 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebKitColorChooserRequest.h" + +#include "WebKitColorChooserRequestPrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitColorChooserRequest + * @Short_description: A request to open a color chooser + * @Title: WebKitColorChooserRequest + * @See_also: #WebKitWebView + * + * Whenever the user interacts with an <input type='color' /> + * HTML element, WebKit will need to show a dialog to choose a color. For that + * to happen in a general way, instead of just opening a #GtkColorChooser + * (which might be not desirable in some cases, which could prefer to use their + * own color chooser dialog), WebKit will fire the + * #WebKitWebView::run-color-chooser signal with a #WebKitColorChooserRequest + * object, which will allow the client application to specify the color to be + * selected, to inspect the details of the request (e.g. to get initial color) + * and to cancel the request, in case nothing was selected. + * + * In case the client application does not wish to handle this signal, + * WebKit will provide a default handler which will asynchronously run + * a regular #GtkColorChooserDialog for the user to interact with. + */ + +enum { + PROP_0, + + PROP_RGBA +}; + +enum { + FINISHED, + + LAST_SIGNAL +}; + +struct _WebKitColorChooserRequestPrivate { + WebKitColorChooser* colorChooser; + GdkRGBA rgba; + bool handled; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitColorChooserRequest, webkit_color_chooser_request, G_TYPE_OBJECT) + +static void webkitColorChooserRequestDispose(GObject* object) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + if (!request->priv->handled) + webkit_color_chooser_request_finish(request); + + G_OBJECT_CLASS(webkit_color_chooser_request_parent_class)->dispose(object); +} + +static void webkitColorChooserRequestGetProperty(GObject* object, guint propertyID, GValue* value, GParamSpec* paramSpec) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + + switch (propertyID) { + case PROP_RGBA: + g_value_set_boxed(value, &request->priv->rgba); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + } +} + +static void webkitColorChooserRequestSetProperty(GObject* object, guint propertyID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST(object); + + switch (propertyID) { + case PROP_RGBA: + webkit_color_chooser_request_set_rgba(request, static_cast<GdkRGBA*>(g_value_get_boxed(value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyID, paramSpec); + } +} + +static void webkit_color_chooser_request_class_init(WebKitColorChooserRequestClass* requestClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(requestClass); + objectClass->dispose = webkitColorChooserRequestDispose; + objectClass->get_property = webkitColorChooserRequestGetProperty; + objectClass->set_property = webkitColorChooserRequestSetProperty; + + /** + * WebKitWebView:rgba: + * + * The #GdkRGBA color of the request + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_RGBA, + g_param_spec_boxed("rgba", + _("Current RGBA color"), + _("The current RGBA color for the request"), + GDK_TYPE_RGBA, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT))); + + /** + * WebKitColorChooserRequest::finished: + * @request: the #WebKitColorChooserRequest on which the signal is emitted + * + * Emitted when the @request finishes. This signal can be emitted because the + * user completed the @request calling webkit_color_chooser_request_finish(), + * or cancelled it with webkit_color_chooser_request_cancel() or because the + * color input element is removed from the DOM. + * + * Since: 2.8 + */ + signals[FINISHED] = + g_signal_new( + "finished", + G_TYPE_FROM_CLASS(requestClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * webkit_color_chooser_request_set_rgba: + * @request: a #WebKitFileChooserRequest + * @rgba: a pointer #GdkRGBA + * + * Sets the current #GdkRGBA color of @request + * + * Since: 2.8 + */ +void webkit_color_chooser_request_set_rgba(WebKitColorChooserRequest* request, const GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rgba); + + if (gdk_rgba_equal(&request->priv->rgba, rgba)) + return; + + request->priv->rgba = *rgba; + g_object_notify(G_OBJECT(request), "rgba"); +} + +/** + * webkit_color_chooser_request_get_rgba: + * @request: a #WebKitColorChooserRequest + * @rgba: (out): a #GdkRGBA to fill in with the current color. + * + * Gets the current #GdkRGBA color of @request + * + * Since: 2.8 + */ +void webkit_color_chooser_request_get_rgba(WebKitColorChooserRequest* request, GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rgba); + + *rgba = request->priv->rgba; +} + +/** + * webkit_color_chooser_request_get_element_rectangle: + * @request: a #WebKitColorChooserRequest + * @rect: (out): a #GdkRectangle to fill in with the element area + * + * Gets the bounding box of the color input element. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_get_element_rectangle(WebKitColorChooserRequest* request, GdkRectangle* rect) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + g_return_if_fail(rect); + + *rect = request->priv->colorChooser->elementRect(); +} + +/** + * webkit_color_chooser_request_finish: + * @request: a #WebKitColorChooserRequest + * + * Finishes @request and the input element keeps the current value of + * #WebKitColorChooserRequest:rgba. + * The signal #WebKitColorChooserRequest::finished + * is emitted to notify that the request has finished. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_finish(WebKitColorChooserRequest* request) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + + if (request->priv->handled) + return; + + request->priv->handled = true; + g_signal_emit(request, signals[FINISHED], 0); +} + +/** + * webkit_color_chooser_request_cancel: + * @request: a #WebKitColorChooserRequest + * + * Cancels @request and the input element changes to use the initial color + * it has before the request started. + * The signal #WebKitColorChooserRequest::finished + * is emitted to notify that the request has finished. + * + * Since: 2.8 + */ +void webkit_color_chooser_request_cancel(WebKitColorChooserRequest* request) +{ + g_return_if_fail(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request)); + + if (request->priv->handled) + return; + + request->priv->handled = true; + request->priv->colorChooser->cancel(); + g_signal_emit(request, signals[FINISHED], 0); +} + +WebKitColorChooserRequest* webkitColorChooserRequestCreate(WebKitColorChooser* colorChooser) +{ + WebKitColorChooserRequest* request = WEBKIT_COLOR_CHOOSER_REQUEST( + g_object_new(WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, "rgba", colorChooser->initialColor(), nullptr)); + request->priv->colorChooser = colorChooser; + return request; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h new file mode 100644 index 000000000..33a4ebb35 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequest.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitColorChooserRequest_h +#define WebKitColorChooserRequest_h + +#include <gtk/gtk.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_COLOR_CHOOSER_REQUEST (webkit_color_chooser_request_get_type()) +#define WEBKIT_COLOR_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequest)) +#define WEBKIT_IS_COLOR_CHOOSER_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST)) +#define WEBKIT_COLOR_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequestClass)) +#define WEBKIT_IS_COLOR_CHOOSER_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST)) +#define WEBKIT_COLOR_CHOOSER_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_COLOR_CHOOSER_REQUEST, WebKitColorChooserRequestClass)) + +typedef struct _WebKitColorChooserRequest WebKitColorChooserRequest; +typedef struct _WebKitColorChooserRequestClass WebKitColorChooserRequestClass; +typedef struct _WebKitColorChooserRequestPrivate WebKitColorChooserRequestPrivate; + +struct _WebKitColorChooserRequest { + GObject parent; + + /*< private >*/ + WebKitColorChooserRequestPrivate *priv; +}; + +struct _WebKitColorChooserRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_color_chooser_request_get_type (void); + +WEBKIT_API void +webkit_color_chooser_request_get_rgba (WebKitColorChooserRequest *request, + GdkRGBA *rgba); + +WEBKIT_API void +webkit_color_chooser_request_set_rgba (WebKitColorChooserRequest *request, + const GdkRGBA *rgba); + +WEBKIT_API void +webkit_color_chooser_request_get_element_rectangle (WebKitColorChooserRequest *request, + GdkRectangle *rect); + +WEBKIT_API void +webkit_color_chooser_request_finish (WebKitColorChooserRequest *request); + +WEBKIT_API void +webkit_color_chooser_request_cancel (WebKitColorChooserRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h new file mode 100644 index 000000000..3acfe2821 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitColorChooserRequestPrivate.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * Copyright (c) 2012, Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebKitColorChooserRequestPrivate_h +#define WebKitColorChooserRequestPrivate_h + +#include "WebKitColorChooser.h" +#include "WebKitColorChooserRequest.h" + +WebKitColorChooserRequest* webkitColorChooserRequestCreate(WebKit::WebKitColorChooser*); + +#endif // WebKitColorChooserRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp index bbbed0ddc..ff0879648 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.cpp @@ -24,6 +24,7 @@ #include "WebContextMenuItem.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" +#include <wtf/glib/GRefPtr.h> using namespace WebKit; using namespace WebCore; @@ -50,6 +51,7 @@ using namespace WebCore; struct _WebKitContextMenuPrivate { GList* items; WebKitContextMenuItem* parentItem; + GRefPtr<GVariant> userData; }; WEBKIT_DEFINE_TYPE(WebKitContextMenu, webkit_context_menu, G_TYPE_OBJECT) @@ -66,21 +68,27 @@ static void webkit_context_menu_class_init(WebKitContextMenuClass* listClass) gObjectClass->dispose = webkitContextMenuDispose; } -void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<ContextMenuItem>& contextMenuItems) +void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<WebContextMenuItemData>& contextMenuItems) { for (GList* item = menu->priv->items; item; item = g_list_next(item)) { WebKitContextMenuItem* menuItem = WEBKIT_CONTEXT_MENU_ITEM(item->data); - contextMenuItems.append(ContextMenuItem(webkitContextMenuItemRelease(menuItem))); + contextMenuItems.append(webkitContextMenuItemToWebContextMenuItemData(menuItem)); } } -WebKitContextMenu* webkitContextMenuCreate(API::Array* items) +void webkitContextMenuPopulate(WebKitContextMenu* menu, Vector<WebContextMenuItemGtk>& contextMenuItems) +{ + for (GList* item = menu->priv->items; item; item = g_list_next(item)) { + WebKitContextMenuItem* menuItem = WEBKIT_CONTEXT_MENU_ITEM(item->data); + contextMenuItems.append(webkitContextMenuItemToWebContextMenuItemGtk(menuItem)); + } +} + +WebKitContextMenu* webkitContextMenuCreate(const Vector<WebContextMenuItemData>& items) { WebKitContextMenu* menu = webkit_context_menu_new(); - for (size_t i = 0; i < items->size(); ++i) { - WebContextMenuItem* item = static_cast<WebContextMenuItem*>(items->at(i)); + for (const auto& item : items) webkit_context_menu_prepend(menu, webkitContextMenuItemCreate(item)); - } menu->priv->items = g_list_reverse(menu->priv->items); return menu; @@ -316,3 +324,42 @@ void webkit_context_menu_remove_all(WebKitContextMenu* menu) g_list_free_full(menu->priv->items, reinterpret_cast<GDestroyNotify>(g_object_unref)); menu->priv->items = 0; } + +/** + * webkit_context_menu_set_user_data: + * @menu: a #WebKitContextMenu + * @user_data: a #GVariant + * + * Sets user data to @menu. + * This function can be used from a Web Process extension to set user data + * that can be retrieved from the UI Process using webkit_context_menu_get_user_data(). + * If the @user_data #GVariant is floating, it is consumed. + * + * Since: 2.8 + */ +void webkit_context_menu_set_user_data(WebKitContextMenu* menu, GVariant* userData) +{ + g_return_if_fail(WEBKIT_IS_CONTEXT_MENU(menu)); + g_return_if_fail(userData); + + menu->priv->userData = userData; +} + +/** + * webkit_context_menu_get_user_data: + * @menu: a #WebKitContextMenu + * + * Gets the user data of @menu. + * This function can be used from the UI Process to get user data previously set + * from the Web Process with webkit_context_menu_set_user_data(). + * + * Returns: (transfer none): the user data of @menu, or %NULL if @menu doesn't have user data + * + * Since: 2.8 + */ +GVariant* webkit_context_menu_get_user_data(WebKitContextMenu* menu) +{ + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(menu), nullptr); + + return menu->priv->userData.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h index 22f4bef29..9b50c6470 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenu.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif @@ -105,6 +105,13 @@ webkit_context_menu_remove (WebKitContextMenu *menu, WEBKIT_API void webkit_context_menu_remove_all (WebKitContextMenu *menu); +WEBKIT_API void +webkit_context_menu_set_user_data (WebKitContextMenu *menu, + GVariant *user_data); + +WEBKIT_API GVariant * +webkit_context_menu_get_user_data (WebKitContextMenu *menu); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp index e8cdffd04..cf1ddf955 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.cpp @@ -135,9 +135,9 @@ ContextMenuAction webkitContextMenuActionGetActionTag(WebKitContextMenuAction ac return ContextMenuItemBaseApplicationTag; } -WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenuItem* menuItem) +WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(const WebKit::WebContextMenuItemGtk& menuItem) { - switch (menuItem->action()) { + switch (menuItem.action()) { case ContextMenuItemTagNoAction: return WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION; case ContextMenuItemTagOpenLink: @@ -182,6 +182,8 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu return WEBKIT_CONTEXT_MENU_ACTION_UNICODE; case ContextMenuItemTagSpellingGuess: return WEBKIT_CONTEXT_MENU_ACTION_SPELLING_GUESS; + case ContextMenuItemTagNoGuessesFound: + return WEBKIT_CONTEXT_MENU_ACTION_NO_GUESSES_FOUND; case ContextMenuItemTagIgnoreSpelling: return WEBKIT_CONTEXT_MENU_ACTION_IGNORE_SPELLING; case ContextMenuItemTagLearnSpelling: @@ -201,10 +203,10 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu case ContextMenuItemTagInspectElement: return WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT; case ContextMenuItemTagOpenMediaInNewWindow: - return menuItem->title() == contextMenuItemTagOpenVideoInNewWindow() ? + return menuItem.title() == contextMenuItemTagOpenVideoInNewWindow() ? WEBKIT_CONTEXT_MENU_ACTION_OPEN_VIDEO_IN_NEW_WINDOW : WEBKIT_CONTEXT_MENU_ACTION_OPEN_AUDIO_IN_NEW_WINDOW; case ContextMenuItemTagCopyMediaLinkToClipboard: - return menuItem->title() == contextMenuItemTagCopyVideoLinkToClipboard() ? + return menuItem.title() == contextMenuItemTagCopyVideoLinkToClipboard() ? WEBKIT_CONTEXT_MENU_ACTION_COPY_VIDEO_LINK_TO_CLIPBOARD : WEBKIT_CONTEXT_MENU_ACTION_COPY_AUDIO_LINK_TO_CLIPBOARD; case ContextMenuItemTagToggleMediaControls: return WEBKIT_CONTEXT_MENU_ACTION_TOGGLE_MEDIA_CONTROLS; @@ -213,12 +215,12 @@ WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(ContextMenu case ContextMenuItemTagEnterVideoFullscreen: return WEBKIT_CONTEXT_MENU_ACTION_ENTER_VIDEO_FULLSCREEN; case ContextMenuItemTagMediaPlayPause: - return menuItem->title() == contextMenuItemTagMediaPlay() ? + return menuItem.title() == contextMenuItemTagMediaPlay() ? WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PLAY : WEBKIT_CONTEXT_MENU_ACTION_MEDIA_PAUSE; case ContextMenuItemTagMediaMute: return WEBKIT_CONTEXT_MENU_ACTION_MEDIA_MUTE; case ContextMenuItemTagDownloadMediaToDisk: - return menuItem->title() == contextMenuItemTagDownloadVideoToDisk() ? + return menuItem.title() == contextMenuItemTagDownloadVideoToDisk() ? WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_VIDEO_TO_DISK : WEBKIT_CONTEXT_MENU_ACTION_DOWNLOAD_AUDIO_TO_DISK; case ContextMenuItemBaseApplicationTag: return WEBKIT_CONTEXT_MENU_ACTION_CUSTOM; diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h index c8c9a0dad..cf155e13a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActions.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h index f753bb97c..e00b8e2df 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuActionsPrivate.h @@ -20,12 +20,12 @@ #ifndef WebKitContextMenuActionsPrivate_h #define WebKitContextMenuActionsPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuActions.h" -#include <WebCore/ContextMenuItem.h> bool webkitContextMenuActionIsCheckable(WebKitContextMenuAction); WebCore::ContextMenuAction webkitContextMenuActionGetActionTag(WebKitContextMenuAction); -WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(WebCore::ContextMenuItem*); +WebKitContextMenuAction webkitContextMenuActionGetForContextMenuItem(const WebKit::WebContextMenuItemGtk&); String webkitContextMenuActionGetLabel(WebKitContextMenuAction); #endif // WebKitPrintOperationPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp index ea5e42757..6671dc93a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuClient.cpp @@ -20,32 +20,44 @@ #include "config.h" #include "WebKitContextMenuClient.h" -#include "WebKitPrivate.h" +#include "APIContextMenuClient.h" +#include "WebContextMenuItem.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" using namespace WebKit; -static void getContextMenuFromProposedMenu(WKPageRef, WKArrayRef proposedMenu, WKArrayRef*, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo) -{ - webkitWebViewPopulateContextMenu(WEBKIT_WEB_VIEW(clientInfo), toImpl(proposedMenu), toImpl(hitTestResult)); -} +class ContextMenuClient final: public API::ContextMenuClient { +public: + explicit ContextMenuClient(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + bool getContextMenuFromProposedMenu(WebPageProxy&, const Vector<RefPtr<WebContextMenuItem>>& proposedMenu, Vector<RefPtr<WebContextMenuItem>>&, const WebHitTestResultData& hitTestResultData, API::Object* userData) override + { + GRefPtr<GVariant> variant; + if (userData) { + ASSERT(userData->type() == API::Object::Type::String); + CString userDataString = static_cast<API::String*>(userData)->string().utf8(); + variant = adoptGRef(g_variant_parse(nullptr, userDataString.data(), userDataString.data() + userDataString.length(), nullptr, nullptr)); + } + + Vector<WebContextMenuItemData> menuItems; + menuItems.reserveInitialCapacity(proposedMenu.size()); + for (auto& item : proposedMenu) + menuItems.uncheckedAppend(item->data()); + webkitWebViewPopulateContextMenu(m_webView, menuItems, hitTestResultData, variant.get()); + return true; + } + + WebKitWebView* m_webView; +}; void attachContextMenuClientToView(WebKitWebView* webView) { - WKPageContextMenuClientV3 wkContextMenuClient = { - { - 3, // version - webView, // clientInfo - }, - 0, // getContextMenuFromProposedMenu_deprecatedForUseWithV0 - 0, // customContextMenuItemSelected - 0, // contextMenuDismissed - getContextMenuFromProposedMenu, - 0, // showContextMenu - 0, // hideContextMenu - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageContextMenuClient(wkPage, &wkContextMenuClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setContextMenuClient(std::make_unique<ContextMenuClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp index c5e4553aa..5a3a47273 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.cpp @@ -22,17 +22,16 @@ #include "APIArray.h" #include "WebContextMenuItem.h" -#include "WebContextMenuItemData.h" +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuActionsPrivate.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" #include <WebCore/ContextMenu.h> #include <WebCore/ContextMenuItem.h> #include <gtk/gtk.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <memory> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> using namespace WebKit; using namespace WebCore; @@ -57,13 +56,13 @@ struct _WebKitContextMenuItemPrivate { webkitContextMenuSetParentItem(subMenu.get(), 0); } - OwnPtr<ContextMenuItem> menuItem; + std::unique_ptr<WebContextMenuItemGtk> menuItem; GRefPtr<WebKitContextMenu> subMenu; }; WEBKIT_DEFINE_TYPE(WebKitContextMenuItem, webkit_context_menu_item, G_TYPE_INITIALLY_UNOWNED) -static void webkit_context_menu_item_class_init(WebKitContextMenuItemClass* itemClass) +static void webkit_context_menu_item_class_init(WebKitContextMenuItemClass*) { } @@ -85,71 +84,44 @@ static void webkitContextMenuItemSetSubMenu(WebKitContextMenuItem* item, GRefPtr return; if (item->priv->subMenu) - webkitContextMenuSetParentItem(item->priv->subMenu.get(), 0); + webkitContextMenuSetParentItem(item->priv->subMenu.get(), nullptr); item->priv->subMenu = subMenu; if (subMenu) webkitContextMenuSetParentItem(subMenu.get(), item); } -WebKitContextMenuItem* webkitContextMenuItemCreate(WebContextMenuItem* webItem) +WebKitContextMenuItem* webkitContextMenuItemCreate(const WebContextMenuItemData& itemData) { WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - WebContextMenuItemData* itemData = webItem->data(); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(itemData->type(), itemData->action(), itemData->title(), itemData->enabled(), itemData->checked())); - const Vector<WebContextMenuItemData>& subMenu = itemData->submenu(); - if (!subMenu.size()) - return item; - - Vector<RefPtr<API::Object>> subMenuItems; - subMenuItems.reserveInitialCapacity(subMenu.size()); - for (size_t i = 0; i < subMenu.size(); ++i) - subMenuItems.uncheckedAppend(WebContextMenuItem::create(subMenu[i]).get()); - webkitContextMenuItemSetSubMenu(item, adoptGRef(webkitContextMenuCreate(API::Array::create(std::move(subMenuItems)).get()))); - return item; -} - -static WebKitContextMenuItem* webkitContextMenuItemCreateForGtkItem(GtkMenuItem* menuItem) -{ - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(menuItem)); - webkitContextMenuItemSetSubMenuFromGtkMenu(item, GTK_MENU(gtk_menu_item_get_submenu(menuItem))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(itemData); + const Vector<WebContextMenuItemData>& subMenu = itemData.submenu(); + if (!subMenu.isEmpty()) + webkitContextMenuItemSetSubMenu(item, adoptGRef(webkitContextMenuCreate(subMenu))); return item; } -void webkitContextMenuItemSetSubMenuFromGtkMenu(WebKitContextMenuItem* item, GtkMenu* subMenu) +WebContextMenuItemGtk webkitContextMenuItemToWebContextMenuItemGtk(WebKitContextMenuItem* item) { - if (!subMenu) - return; - - GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(subMenu))); - if (!g_list_length(children.get())) - return; - - webkitContextMenuItemSetSubMenu(item, adoptGRef(webkit_context_menu_new())); - for (GList* listItem = children.get(); listItem; listItem = g_list_next(listItem)) { - GRefPtr<GtkWidget> widget = GTK_WIDGET(listItem->data); - if (!GTK_IS_MENU_ITEM(widget.get())) - continue; - - gtk_container_remove(GTK_CONTAINER(subMenu), widget.get()); - GtkMenuItem* menuItem = GTK_MENU_ITEM(widget.leakRef()); - g_object_force_floating(G_OBJECT(menuItem)); - webkit_context_menu_append(item->priv->subMenu.get(), webkitContextMenuItemCreateForGtkItem(menuItem)); + if (item->priv->subMenu) { + Vector<WebContextMenuItemGtk> subMenuItems; + webkitContextMenuPopulate(item->priv->subMenu.get(), subMenuItems); + return WebContextMenuItemGtk(*item->priv->menuItem, WTFMove(subMenuItems)); } + + return *item->priv->menuItem; } -GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem* item) +WebContextMenuItemData webkitContextMenuItemToWebContextMenuItemData(WebKitContextMenuItem* item) { if (item->priv->subMenu) { - Vector<ContextMenuItem> subMenuItems; + Vector<WebContextMenuItemData> subMenuItems; webkitContextMenuPopulate(item->priv->subMenu.get(), subMenuItems); - ContextMenu subMenu(platformMenuDescription(subMenuItems)); - item->priv->menuItem->setSubMenu(&subMenu); + return WebContextMenuItemData(item->priv->menuItem->action(), item->priv->menuItem->title(), item->priv->menuItem->enabled(), subMenuItems); } - return item->priv->menuItem->releasePlatformDescription(); + return WebContextMenuItemData(item->priv->menuItem->type(), item->priv->menuItem->action(), item->priv->menuItem->title(), item->priv->menuItem->enabled(), item->priv->menuItem->checked()); } /** @@ -162,11 +134,10 @@ GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem* item) */ WebKitContextMenuItem* webkit_context_menu_item_new(GtkAction* action) { - g_return_val_if_fail(GTK_IS_ACTION(action), 0); + g_return_val_if_fail(GTK_IS_ACTION(action), nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(GTK_MENU_ITEM(gtk_action_create_menu_item(action)))); - item->priv->menuItem->setAction(ContextMenuItemBaseApplicationTag); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(action); return item; } @@ -189,11 +160,11 @@ WebKitContextMenuItem* webkit_context_menu_item_new(GtkAction* action) */ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action(WebKitContextMenuAction action) { - g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, 0); + g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); ContextMenuItemType type = webkitContextMenuActionIsCheckable(action) ? CheckableActionType : ActionType; - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(type, webkitContextMenuActionGetActionTag(action), webkitContextMenuActionGetLabel(action))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(type, webkitContextMenuActionGetActionTag(action), webkitContextMenuActionGetLabel(action)); return item; } @@ -211,11 +182,11 @@ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action(WebKitCont */ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action_with_label(WebKitContextMenuAction action, const gchar* label) { - g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, 0); + g_return_val_if_fail(action > WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION && action < WEBKIT_CONTEXT_MENU_ACTION_CUSTOM, nullptr); - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); ContextMenuItemType type = webkitContextMenuActionIsCheckable(action) ? CheckableActionType : ActionType; - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(type, webkitContextMenuActionGetActionTag(action), String::fromUTF8(label))); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(type, webkitContextMenuActionGetActionTag(action), String::fromUTF8(label)); return item; } @@ -231,14 +202,14 @@ WebKitContextMenuItem* webkit_context_menu_item_new_from_stock_action_with_label */ WebKitContextMenuItem* webkit_context_menu_item_new_with_submenu(const gchar* label, WebKitContextMenu* submenu) { - g_return_val_if_fail(label, 0); - g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(submenu), 0); + g_return_val_if_fail(label, nullptr); + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU(submenu), nullptr); if (checkAndWarnIfMenuHasParentItem(submenu)) - return 0; + return nullptr; - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(SubmenuType, ContextMenuItemBaseApplicationTag, String::fromUTF8(label))); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(ActionType, ContextMenuItemBaseApplicationTag, String::fromUTF8(label)); item->priv->subMenu = submenu; webkitContextMenuSetParentItem(submenu, item); @@ -254,8 +225,8 @@ WebKitContextMenuItem* webkit_context_menu_item_new_with_submenu(const gchar* la */ WebKitContextMenuItem* webkit_context_menu_item_new_separator(void) { - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, NULL)); - item->priv->menuItem = WTF::adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); + WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(g_object_new(WEBKIT_TYPE_CONTEXT_MENU_ITEM, nullptr)); + item->priv->menuItem = std::make_unique<WebContextMenuItemGtk>(SeparatorType, ContextMenuItemTagNoAction, String()); return item; } @@ -271,7 +242,7 @@ WebKitContextMenuItem* webkit_context_menu_item_new_separator(void) */ GtkAction* webkit_context_menu_item_get_action(WebKitContextMenuItem* item) { - g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), 0); + g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), nullptr); return item->priv->menuItem->gtkAction(); } @@ -291,7 +262,7 @@ WebKitContextMenuAction webkit_context_menu_item_get_stock_action(WebKitContextM { g_return_val_if_fail(WEBKIT_IS_CONTEXT_MENU_ITEM(item), WEBKIT_CONTEXT_MENU_ACTION_NO_ACTION); - return webkitContextMenuActionGetForContextMenuItem(item->priv->menuItem.get()); + return webkitContextMenuActionGetForContextMenuItem(*item->priv->menuItem); } /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h index 75d60d7d6..33e31241a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItem.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h index 18f8c1a87..be452fd9e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuItemPrivate.h @@ -20,11 +20,12 @@ #ifndef WebKitContextMenuItemPrivate_h #define WebKitContextMenuItemPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenuItem.h" #include "WebKitPrivate.h" -WebKitContextMenuItem* webkitContextMenuItemCreate(WebKit::WebContextMenuItem*); -GtkMenuItem* webkitContextMenuItemRelease(WebKitContextMenuItem*); -void webkitContextMenuItemSetSubMenuFromGtkMenu(WebKitContextMenuItem*, GtkMenu*); +WebKitContextMenuItem* webkitContextMenuItemCreate(const WebKit::WebContextMenuItemData&); +WebKit::WebContextMenuItemGtk webkitContextMenuItemToWebContextMenuItemGtk(WebKitContextMenuItem*); +WebKit::WebContextMenuItemData webkitContextMenuItemToWebContextMenuItemData(WebKitContextMenuItem*); #endif // WebKitContextMenuItemPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h index dcfd16b21..3e4cae7b3 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitContextMenuPrivate.h @@ -20,11 +20,13 @@ #ifndef WebKitContextMenuPrivate_h #define WebKitContextMenuPrivate_h +#include "WebContextMenuItemGtk.h" #include "WebKitContextMenu.h" #include "WebKitPrivate.h" -WebKitContextMenu* webkitContextMenuCreate(API::Array* items); -void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebCore::ContextMenuItem>&); +WebKitContextMenu* webkitContextMenuCreate(const Vector<WebKit::WebContextMenuItemData>&); +void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebKit::WebContextMenuItemGtk>&); +void webkitContextMenuPopulate(WebKitContextMenu*, Vector<WebKit::WebContextMenuItemData>&); void webkitContextMenuSetParentItem(WebKitContextMenu*, WebKitContextMenuItem*); WebKitContextMenuItem* webkitContextMenuGetParentItem(WebKitContextMenu*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp index 2c1ef4568..75a66ec61 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.cpp @@ -20,12 +20,14 @@ #include "config.h" #include "WebKitCookieManager.h" -#include "APIString.h" #include "SoupCookiePersistentStorageType.h" #include "WebCookieManagerProxy.h" #include "WebKitCookieManagerPrivate.h" #include "WebKitEnumTypes.h" -#include <wtf/gobject/GRefPtr.h> +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include "WebsiteDataRecord.h" +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -35,15 +37,11 @@ using namespace WebKit; * @Short_description: Defines how to handle cookies in a #WebKitWebContext * @Title: WebKitCookieManager * - * The #WebKitCookieManager defines how to handle cookies in a - * #WebKitWebContext. Get it from the context with - * webkit_web_context_get_cookie_manager(), and use it to set where to - * store cookies, with webkit_cookie_manager_set_persistent_storage(), - * to get the list of domains with cookies, with - * webkit_cookie_manager_get_domains_with_cookies(), or to set the - * acceptance policy, with webkit_cookie_manager_get_accept_policy() - * (among other actions). - * + * The WebKitCookieManager defines how to set up and handle cookies. + * You can get it from a #WebKitWebsiteDataManager with + * webkit_website_data_manager_get_cookie_manager(), and use it to set where to + * store cookies with webkit_cookie_manager_set_persistent_storage(), + * or to set the acceptance policy, with webkit_cookie_manager_get_accept_policy(). */ enum { @@ -55,22 +53,60 @@ enum { struct _WebKitCookieManagerPrivate { ~_WebKitCookieManagerPrivate() { - webCookieManager->stopObservingCookieChanges(); + auto sessionID = webkitWebsiteDataManagerGetDataStore(dataManager).websiteDataStore().sessionID(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setCookieObserverCallback(sessionID, nullptr); } - RefPtr<WebCookieManagerProxy> webCookieManager; + WebKitWebsiteDataManager* dataManager; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitCookieManager, webkit_cookie_manager, G_TYPE_OBJECT) -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT, SoupCookiePersistentStorageText); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE, SoupCookiePersistentStorageSQLite); +static inline SoupCookiePersistentStorageType toSoupCookiePersistentStorageType(WebKitCookiePersistentStorage kitStorage) +{ + switch (kitStorage) { + case WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT: + return SoupCookiePersistentStorageText; + case WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE: + return SoupCookiePersistentStorageSQLite; + default: + ASSERT_NOT_REACHED(); + return SoupCookiePersistentStorageText; + } +} -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS, HTTPCookieAcceptPolicyAlways); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NEVER, HTTPCookieAcceptPolicyNever); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY, HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain); +static inline WebKitCookieAcceptPolicy toWebKitCookieAcceptPolicy(HTTPCookieAcceptPolicy httpPolicy) +{ + switch (httpPolicy) { + case HTTPCookieAcceptPolicyAlways: + return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; + case HTTPCookieAcceptPolicyNever: + return WEBKIT_COOKIE_POLICY_ACCEPT_NEVER; + case HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: + return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS; + } +} + +static inline HTTPCookieAcceptPolicy toHTTPCookieAcceptPolicy(WebKitCookieAcceptPolicy kitPolicy) +{ + switch (kitPolicy) { + case WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS: + return HTTPCookieAcceptPolicyAlways; + case WEBKIT_COOKIE_POLICY_ACCEPT_NEVER: + return HTTPCookieAcceptPolicyNever; + case WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY: + return HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; + default: + ASSERT_NOT_REACHED(); + return HTTPCookieAcceptPolicyAlways; + } +} static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass) { @@ -91,26 +127,16 @@ static void webkit_cookie_manager_class_init(WebKitCookieManagerClass* findClass G_TYPE_NONE, 0); } -static void cookiesDidChange(WKCookieManagerRef, const void* clientInfo) -{ - g_signal_emit(WEBKIT_COOKIE_MANAGER(clientInfo), signals[CHANGED], 0); -} - -WebKitCookieManager* webkitCookieManagerCreate(WebCookieManagerProxy* webCookieManager) +WebKitCookieManager* webkitCookieManagerCreate(WebKitWebsiteDataManager* dataManager) { - WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, NULL)); - manager->priv->webCookieManager = webCookieManager; - - WKCookieManagerClientV0 wkCookieManagerClient = { - { - 0, // version - manager, // clientInfo - }, - cookiesDidChange - }; - WKCookieManagerSetClient(toAPI(webCookieManager), &wkCookieManagerClient.base); - manager->priv->webCookieManager->startObservingCookieChanges(); - + WebKitCookieManager* manager = WEBKIT_COOKIE_MANAGER(g_object_new(WEBKIT_TYPE_COOKIE_MANAGER, nullptr)); + manager->priv->dataManager = dataManager; + auto sessionID = webkitWebsiteDataManagerGetDataStore(manager->priv->dataManager).websiteDataStore().sessionID(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) { + processPool->supplement<WebCookieManagerProxy>()->setCookieObserverCallback(sessionID, [manager] { + g_signal_emit(manager, signals[CHANGED], 0); + }); + } return manager; } @@ -125,17 +151,19 @@ WebKitCookieManager* webkitCookieManagerCreate(WebCookieManagerProxy* webCookieM * Cookies are initially read from @filename to create an initial set of cookies. * Then, non-session cookies will be written to @filename when the WebKitCookieManager::changed * signal is emitted. - * By default, @cookie_manager doesn't store the cookies persistenly, so you need to call this + * By default, @cookie_manager doesn't store the cookies persistently, so you need to call this * method to keep cookies saved across sessions. + * + * This method should never be called on a #WebKitCookieManager associated to an ephemeral #WebKitWebsiteDataManager. */ void webkit_cookie_manager_set_persistent_storage(WebKitCookieManager* manager, const char* filename, WebKitCookiePersistentStorage storage) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); g_return_if_fail(filename); + g_return_if_fail(!webkit_website_data_manager_is_ephemeral(manager->priv->dataManager)); - manager->priv->webCookieManager->stopObservingCookieChanges(); - manager->priv->webCookieManager->setCookiePersistentStorage(String::fromUTF8(filename), storage); - manager->priv->webCookieManager->startObservingCookieChanges(); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setCookiePersistentStorage(String::fromUTF8(filename), toSoupCookiePersistentStorageType(storage)); } /** @@ -149,13 +177,14 @@ void webkit_cookie_manager_set_accept_policy(WebKitCookieManager* manager, WebKi { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - manager->priv->webCookieManager->setHTTPCookieAcceptPolicy(policy); + for (auto* processPool : webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager)) + processPool->supplement<WebCookieManagerProxy>()->setHTTPCookieAcceptPolicy(toHTTPCookieAcceptPolicy(policy)); } static void webkitCookieManagerGetAcceptPolicyCallback(WKHTTPCookieAcceptPolicy policy, WKErrorRef, void* context) { GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - g_task_return_int(task.get(), policy); + g_task_return_int(task.get(), toWebKitCookieAcceptPolicy(toHTTPCookieAcceptPolicy(policy))); } /** @@ -174,8 +203,17 @@ void webkit_cookie_manager_get_accept_policy(WebKitCookieManager* manager, GCanc { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - GTask* task = g_task_new(manager, cancellable, callback, userData); - manager->priv->webCookieManager->getHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicyCallback::create(task, webkitCookieManagerGetAcceptPolicyCallback)); + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + + // The policy is the same in all process pools having the same session ID, so just ask any. + const auto& processPools = webkitWebsiteDataManagerGetProcessPools(manager->priv->dataManager); + if (processPools.isEmpty()) { + g_task_return_int(task.get(), WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); + return; + } + + processPools[0]->supplement<WebCookieManagerProxy>()->getHTTPCookieAcceptPolicy( + toGenericCallbackFunction<WKHTTPCookieAcceptPolicy, HTTPCookieAcceptPolicy>(task.leakRef(), webkitCookieManagerGetAcceptPolicyCallback)); } /** @@ -197,25 +235,6 @@ WebKitCookieAcceptPolicy webkit_cookie_manager_get_accept_policy_finish(WebKitCo return returnValue == -1 ? WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY : static_cast<WebKitCookieAcceptPolicy>(returnValue); } -static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomains, WKErrorRef, void* context) -{ - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - if (g_task_return_error_if_cancelled(task.get())) - return; - - API::Array* domains = toImpl(wkDomains); - GPtrArray* returnValue = g_ptr_array_sized_new(domains->size()); - for (size_t i = 0; i < domains->size(); ++i) { - API::String* domainString = static_cast<API::String*>(domains->at(i)); - String domain = domainString->string(); - if (domain.isEmpty()) - continue; - g_ptr_array_add(returnValue, g_strdup(domain.utf8().data())); - } - g_ptr_array_add(returnValue, 0); - g_task_return_pointer(task.get(), g_ptr_array_free(returnValue, FALSE), reinterpret_cast<GDestroyNotify>(g_strfreev)); -} - /** * webkit_cookie_manager_get_domains_with_cookies: * @cookie_manager: a #WebKitCookieManager @@ -227,13 +246,32 @@ static void webkitCookieManagerGetDomainsWithCookiesCallback(WKArrayRef wkDomain * * When the operation is finished, @callback will be called. You can then call * webkit_cookie_manager_get_domains_with_cookies_finish() to get the result of the operation. + * + * Deprecated: 2.16: Use webkit_website_data_manager_fetch() instead. */ void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); GTask* task = g_task_new(manager, cancellable, callback, userData); - manager->priv->webCookieManager->getHostnamesWithCookies(ArrayCallback::create(task, webkitCookieManagerGetDomainsWithCookiesCallback)); + webkit_website_data_manager_fetch(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, cancellable, [](GObject* object, GAsyncResult* result, gpointer userData) { + GRefPtr<GTask> task = adoptGRef(G_TASK(userData)); + GError* error = nullptr; + GUniquePtr<GList> dataList(webkit_website_data_manager_fetch_finish(WEBKIT_WEBSITE_DATA_MANAGER(object), result, &error)); + if (error) { + g_task_return_error(task.get(), error); + return; + } + + GPtrArray* domains = g_ptr_array_sized_new(g_list_length(dataList.get())); + for (GList* item = dataList.get(); item; item = g_list_next(item)) { + auto* data = static_cast<WebKitWebsiteData*>(item->data); + g_ptr_array_add(domains, g_strdup(webkit_website_data_get_name(data))); + webkit_website_data_unref(data); + } + g_ptr_array_add(domains, nullptr); + g_task_return_pointer(task.get(), g_ptr_array_free(domains, FALSE), reinterpret_cast<GDestroyNotify>(g_strfreev)); + }, task); } /** @@ -248,11 +286,13 @@ void webkit_cookie_manager_get_domains_with_cookies(WebKitCookieManager* manager * * Returns: (transfer full) (array zero-terminated=1): A %NULL terminated array of domain names * or %NULL in case of error. + * + * Deprecated: 2.16: Use webkit_website_data_manager_fetch_finish() instead. */ gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManager* manager, GAsyncResult* result, GError** error) { - g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), 0); - g_return_val_if_fail(g_task_is_valid(result, manager), 0); + g_return_val_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager), nullptr); + g_return_val_if_fail(g_task_is_valid(result, manager), nullptr); return reinterpret_cast<char**>(g_task_propagate_pointer(G_TASK(result), error)); } @@ -263,13 +303,20 @@ gchar** webkit_cookie_manager_get_domains_with_cookies_finish(WebKitCookieManage * @domain: a domain name * * Remove all cookies of @cookie_manager for the given @domain. + * + * Deprecated: 2.16: Use webkit_website_data_manager_remove() instead. */ void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manager, const gchar* domain) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); g_return_if_fail(domain); - manager->priv->webCookieManager->deleteCookiesForHostname(String::fromUTF8(domain)); + WebsiteDataRecord record; + record.addCookieHostName(String::fromUTF8(domain)); + auto* data = webkitWebsiteDataCreate(WTFMove(record)); + GList dataList = { data, nullptr, nullptr }; + webkit_website_data_manager_remove(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, &dataList, nullptr, nullptr, nullptr); + webkit_website_data_unref(data); } /** @@ -277,10 +324,12 @@ void webkit_cookie_manager_delete_cookies_for_domain(WebKitCookieManager* manage * @cookie_manager: a #WebKitCookieManager * * Delete all cookies of @cookie_manager + * + * Deprecated: 2.16: Use webkit_website_data_manager_clear() instead. */ void webkit_cookie_manager_delete_all_cookies(WebKitCookieManager* manager) { g_return_if_fail(WEBKIT_IS_COOKIE_MANAGER(manager)); - manager->priv->webCookieManager->deleteAllCookies(); + webkit_website_data_manager_clear(manager->priv->dataManager, WEBKIT_WEBSITE_DATA_COOKIES, 0, nullptr, nullptr, nullptr); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h index f25f1a2b0..ee17d2204 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManager.h @@ -107,22 +107,22 @@ webkit_cookie_manager_get_accept_policy_finish (WebKitCookieManager GAsyncResult *result, GError **error); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch) void webkit_cookie_manager_get_domains_with_cookies (WebKitCookieManager *cookie_manager, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); -WEBKIT_API gchar ** +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_fetch_finish) gchar ** webkit_cookie_manager_get_domains_with_cookies_finish (WebKitCookieManager *cookie_manager, GAsyncResult *result, GError **error); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_remove) void webkit_cookie_manager_delete_cookies_for_domain (WebKitCookieManager *cookie_manager, const gchar *domain); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_website_data_manager_clear) void webkit_cookie_manager_delete_all_cookies (WebKitCookieManager *cookie_manager); G_END_DECLS diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h index 6be84afae..75ac6f287 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCookieManagerPrivate.h @@ -17,12 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitCookieManagerPrivate_h -#define WebKitCookieManagerPrivate_h +#pragma once -#include "WebKitCookieManager.h" #include "WebKitPrivate.h" +#include "WebKitWebsiteDataManager.h" -WebKitCookieManager* webkitCookieManagerCreate(WebKit::WebCookieManagerProxy*); - -#endif // WebKitCookieManagerPrivate_h +WebKitCookieManager* webkitCookieManagerCreate(WebKitWebsiteDataManager*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp index 5755fd5c7..a23e7e84b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCredential.cpp @@ -37,15 +37,41 @@ struct _WebKitCredential { CString password; }; -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_NONE, WebCore::CredentialPersistenceNone); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION, WebCore::CredentialPersistenceForSession); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT, WebCore::CredentialPersistencePermanent); - G_DEFINE_BOXED_TYPE(WebKitCredential, webkit_credential, webkit_credential_copy, webkit_credential_free) +static inline WebKitCredentialPersistence toWebKitCredentialPersistence(WebCore::CredentialPersistence corePersistence) +{ + switch (corePersistence) { + case WebCore::CredentialPersistenceNone: + return WEBKIT_CREDENTIAL_PERSISTENCE_NONE; + case WebCore::CredentialPersistenceForSession: + return WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION; + case WebCore::CredentialPersistencePermanent: + return WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_CREDENTIAL_PERSISTENCE_NONE; + } +} + +static inline WebCore::CredentialPersistence toWebCoreCredentialPersistence(WebKitCredentialPersistence kitPersistence) +{ + switch (kitPersistence) { + case WEBKIT_CREDENTIAL_PERSISTENCE_NONE: + return WebCore::CredentialPersistenceNone; + case WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION: + return WebCore::CredentialPersistenceForSession; + case WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT: + return WebCore::CredentialPersistencePermanent; + default: + ASSERT_NOT_REACHED(); + return WebCore::CredentialPersistenceNone; + } +} + WebKitCredential* webkitCredentialCreate(const WebCore::Credential& coreCredential) { - WebKitCredential* credential = g_slice_new(WebKitCredential); + WebKitCredential* credential = static_cast<WebKitCredential*>(fastMalloc(sizeof(WebKitCredential))); new (credential) WebKitCredential(coreCredential); return credential; } @@ -73,7 +99,7 @@ WebKitCredential* webkit_credential_new(const gchar* username, const gchar* pass g_return_val_if_fail(username, 0); g_return_val_if_fail(password, 0); - return webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), static_cast<WebCore::CredentialPersistence>(persistence))); + return webkitCredentialCreate(WebCore::Credential(String::fromUTF8(username), String::fromUTF8(password), toWebCoreCredentialPersistence(persistence))); } /** @@ -106,7 +132,7 @@ void webkit_credential_free(WebKitCredential* credential) g_return_if_fail(credential); credential->~WebKitCredential(); - g_slice_free(WebKitCredential, credential); + fastFree(credential); } /** @@ -178,5 +204,5 @@ WebKitCredentialPersistence webkit_credential_get_persistence(WebKitCredential* { g_return_val_if_fail(credential, WEBKIT_CREDENTIAL_PERSISTENCE_NONE); - return static_cast<WebKitCredentialPersistence>(credential->credential.persistence()); + return toWebKitCredentialPersistence(credential->credential.persistence()); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp new file mode 100644 index 000000000..f04b726f1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitCustomProtocolManagerClient.h" + +#include "APICustomProtocolManagerClient.h" +#include "CustomProtocolManagerProxy.h" +#include "WebKitWebContextPrivate.h" +#include "WebProcessPool.h" + +using namespace WebCore; +using namespace WebKit; + +class CustomProtocolManagerClient final : public API::CustomProtocolManagerClient { +public: + explicit CustomProtocolManagerClient(WebKitWebContext* webContext) + : m_webContext(webContext) + { + } + +private: + void startLoading(CustomProtocolManagerProxy& manager, uint64_t customProtocolID, const ResourceRequest& request) override + { + webkitWebContextStartLoadingCustomProtocol(m_webContext, customProtocolID, request, manager); + } + + void stopLoading(CustomProtocolManagerProxy&, uint64_t customProtocolID) override + { + webkitWebContextStopLoadingCustomProtocol(m_webContext, customProtocolID); + } + + void invalidate(CustomProtocolManagerProxy& manager) override + { + webkitWebContextInvalidateCustomProtocolRequests(m_webContext, manager); + } + + WebKitWebContext* m_webContext; +}; + +void attachCustomProtocolManagerClientToContext(WebKitWebContext* webContext) +{ + webkitWebContextGetProcessPool(webContext).setCustomProtocolManagerClient(std::make_unique<CustomProtocolManagerClient>(webContext)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.h index a365594f8..c9c4c17cc 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitCustomProtocolManagerClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Igalia S.L. + * Copyright (C) 2016 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,11 +17,9 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitRequestManagerClient_h -#define WebKitRequestManagerClient_h +#pragma once #include "WebKitWebContext.h" -void attachRequestManagerClientToContext(WebKitWebContext*); +void attachCustomProtocolManagerClientToContext(WebKitWebContext*); -#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h index 8b637652b..520e9957c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h @@ -38,10 +38,11 @@ # else # define WEBKIT_API __declspec(dllimport) # endif -# define WEBKIT_OBSOLETE_API WEBKIT_API #else # define WEBKIT_API __attribute__((visibility("default"))) -# define WEBKIT_OBSOLETE_API WEBKIT_API __attribute__((deprecated)) #endif +#define WEBKIT_DEPRECATED WEBKIT_API G_DEPRECATED +#define WEBKIT_DEPRECATED_FOR(f) WEBKIT_API G_DEPRECATED_FOR(f) + #endif // WebKitDefines_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index e95e4c065..4fe6cb984 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Igalia S.L. + * Copyright (C) 2012, 2014 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,13 +23,15 @@ #include "DownloadProxy.h" #include "WebKitDownloadPrivate.h" #include "WebKitMarshal.h" +#include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include <WebCore/ErrorsGtk.h> #include <WebCore/ResourceResponse.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> +#include <wtf/text/CString.h> using namespace WebKit; using namespace WebCore; @@ -62,7 +64,8 @@ enum { PROP_DESTINATION, PROP_RESPONSE, - PROP_ESTIMATED_PROGRESS + PROP_ESTIMATED_PROGRESS, + PROP_ALLOW_OVERWRITE }; struct _WebKitDownloadPrivate { @@ -83,12 +86,26 @@ struct _WebKitDownloadPrivate { GUniquePtr<GTimer> timer; gdouble lastProgress; gdouble lastElapsed; + bool allowOverwrite; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitDownload, webkit_download, G_TYPE_OBJECT) +static void webkitDownloadSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + + switch (propId) { + case PROP_ALLOW_OVERWRITE: + webkit_download_set_allow_overwrite(download, g_value_get_boolean(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + static void webkitDownloadGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) { WebKitDownload* download = WEBKIT_DOWNLOAD(object); @@ -103,6 +120,9 @@ static void webkitDownloadGetProperty(GObject* object, guint propId, GValue* val case PROP_ESTIMATED_PROGRESS: g_value_set_double(value, webkit_download_get_estimated_progress(download)); break; + case PROP_ALLOW_OVERWRITE: + g_value_set_boolean(value, webkit_download_get_allow_overwrite(download)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -129,6 +149,7 @@ static gboolean webkitDownloadDecideDestination(WebKitDownload* download, const static void webkit_download_class_init(WebKitDownloadClass* downloadClass) { GObjectClass* objectClass = G_OBJECT_CLASS(downloadClass); + objectClass->set_property = webkitDownloadSetProperty; objectClass->get_property = webkitDownloadGetProperty; downloadClass->decide_destination = webkitDownloadDecideDestination; @@ -178,6 +199,25 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) WEBKIT_PARAM_READABLE)); /** + * WebKitDownload:allow-overwrite: + * + * Whether or not the download is allowed to overwrite an existing file on + * disk. If this property is %FALSE and the destination already exists, + * the download will fail. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_ALLOW_OVERWRITE, + g_param_spec_boolean( + "allow-overwrite", + _("Allow Overwrite"), + _("Whether the destination may be overwritten"), + FALSE, + WEBKIT_PARAM_READWRITE)); + + /** * WebKitDownload::received-data: * @download: the #WebKitDownload * @data_length: the length of data received in bytes @@ -223,13 +263,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * after an error and #WebKitDownload::finished signal is emitted after this one. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(objectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitDownload::decide-destination: @@ -282,13 +323,6 @@ WebKitDownload* webkitDownloadCreate(DownloadProxy* downloadProxy) return download; } -WebKitDownload* webkitDownloadCreateForRequest(DownloadProxy* downloadProxy, const ResourceRequest& request) -{ - WebKitDownload* download = webkitDownloadCreate(downloadProxy); - download->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); - return download; -} - void webkitDownloadSetResponse(WebKitDownload* download, WebKitURIResponse* response) { download->priv->response = response; @@ -340,7 +374,7 @@ void webkitDownloadNotifyProgress(WebKitDownload* download, guint64 bytesReceive void webkitDownloadFailed(WebKitDownload* download, const ResourceError& resourceError) { GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); if (download->priv->timer) g_timer_stop(download->priv->timer.get()); @@ -369,20 +403,26 @@ void webkitDownloadFinished(WebKitDownload* download) g_signal_emit(download, signals[FINISHED], 0, NULL); } -CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename) +String webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename, bool& allowOverwrite) { if (download->priv->isCancelled) - return ""; + return emptyString(); gboolean returnValue; g_signal_emit(download, signals[DECIDE_DESTINATION], 0, suggestedFilename.data(), &returnValue); - return download->priv->destinationURI; + allowOverwrite = download->priv->allowOverwrite; + GUniquePtr<char> destinationPath(g_filename_from_uri(download->priv->destinationURI.data(), nullptr, nullptr)); + if (!destinationPath) + return emptyString(); + return String::fromUTF8(destinationPath.get()); } -void webkitDownloadDestinationCreated(WebKitDownload* download, const CString& destinationURI) +void webkitDownloadDestinationCreated(WebKitDownload* download, const String& destinationPath) { if (download->priv->isCancelled) return; - g_signal_emit(download, signals[CREATED_DESTINATION], 0, destinationURI.data(), nullptr); + GUniquePtr<char> destinationURI(g_filename_to_uri(destinationPath.utf8().data(), nullptr, nullptr)); + ASSERT(destinationURI); + g_signal_emit(download, signals[CREATED_DESTINATION], 0, destinationURI.get()); } /** @@ -567,3 +607,44 @@ WebKitWebView* webkit_download_get_web_view(WebKitDownload* download) return download->priv->webView; } + +/** + * webkit_download_get_allow_overwrite: + * @download: a #WebKitDownload + * + * Returns the current value of the #WebKitDownload:allow-overwrite property, + * which determines whether the download will overwrite an existing file on + * disk, or if it will fail if the destination already exists. + * + * Returns: the current value of the #WebKitDownload:allow-overwrite property + * + * Since: 2.6 + */ +gboolean webkit_download_get_allow_overwrite(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), FALSE); + + return download->priv->allowOverwrite; +} + +/** + * webkit_download_set_allow_overwrite: + * @download: a #WebKitDownload + * @allowed: the new value for the #WebKitDownload:allow-overwrite property + * + * Sets the #WebKitDownload:allow-overwrite property, which determines whether + * the download may overwrite an existing file on disk, or if it will fail if + * the destination already exists. + * + * Since: 2.6 + */ +void webkit_download_set_allow_overwrite(WebKitDownload* download, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + if (allowed == download->priv->allowOverwrite) + return; + + download->priv->allowOverwrite = allowed; + g_object_notify(G_OBJECT(download), "allow-overwrite"); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index 493bfea40..7e6bfeb46 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -92,6 +92,13 @@ webkit_download_get_received_data_length (WebKitDownload *download); WEBKIT_API WebKitWebView * webkit_download_get_web_view (WebKitDownload *download); +WEBKIT_API gboolean +webkit_download_get_allow_overwrite (WebKitDownload *download); + +WEBKIT_API void +webkit_download_set_allow_overwrite (WebKitDownload *download, + gboolean allowed); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp index 198cc68f9..f4e13b9e2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadClient.cpp @@ -20,98 +20,101 @@ #include "config.h" #include "WebKitDownloadClient.h" -#include "APIURLResponse.h" -#include "WebContext.h" +#include "APIDownloadClient.h" #include "WebKitDownloadPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebContextPrivate.h" -#include <WebKit2/WKString.h> -#include <wtf/gobject/GRefPtr.h> +#include "WebKitWebViewPrivate.h" +#include "WebProcessPool.h" +#include <WebKit/WKString.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebCore; using namespace WebKit; -static void didStart(WKContextRef, WKDownloadRef wkDownload, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitWebContextDownloadStarted(WEBKIT_WEB_CONTEXT(clientInfo), download.get()); -} +class DownloadClient final : public API::DownloadClient { +public: + explicit DownloadClient(WebKitWebContext* webContext) + : m_webContext(webContext) + { + } -static void didReceiveResponse(WKContextRef, WKDownloadRef wkDownload, WKURLResponseRef wkResponse, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - if (webkitDownloadIsCancelled(download.get())) - return; +private: + void didStart(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitWebContextDownloadStarted(m_webContext, download.get()); + } - GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(toImpl(wkResponse)->resourceResponse())); - webkitDownloadSetResponse(download.get(), response.get()); -} + void didReceiveAuthenticationChallenge(WebProcessPool*, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallenge) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) + return; -static void didReceiveData(WKContextRef, WKDownloadRef wkDownload, uint64_t length, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadNotifyProgress(download.get(), length); -} + // FIXME: Add API to handle authentication of downloads without a web view associted. + if (auto* webView = webkit_download_get_web_view(download.get())) + webkitWebViewHandleAuthenticationChallenge(webView, authenticationChallenge); + } -static WKStringRef decideDestinationWithSuggestedFilename(WKContextRef, WKDownloadRef wkDownload, WKStringRef filename, bool* allowOverwrite, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - CString destinationURI = webkitDownloadDecideDestinationWithSuggestedFilename(download.get(), - toImpl(filename)->string().utf8()); - return WKStringCreateWithUTF8CString(destinationURI.data()); -} + void didReceiveResponse(WebProcessPool*, DownloadProxy* downloadProxy, const ResourceResponse& resourceResponse) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) + return; -static void didCreateDestination(WKContextRef, WKDownloadRef wkDownload, WKStringRef path, const void* clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadDestinationCreated(download.get(), toImpl(path)->string().utf8()); -} + GRefPtr<WebKitURIResponse> response = adoptGRef(webkitURIResponseCreateForResourceResponse(resourceResponse)); + webkitDownloadSetResponse(download.get(), response.get()); + } -static void didFail(WKContextRef, WKDownloadRef wkDownload, WKErrorRef error, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - if (webkitDownloadIsCancelled(download.get())) { - // Cancellation takes precedence over other errors. + void didReceiveData(WebProcessPool*, DownloadProxy* downloadProxy, uint64_t length) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadNotifyProgress(download.get(), length); + } + + String decideDestinationWithSuggestedFilename(WebProcessPool*, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwrite) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + return webkitDownloadDecideDestinationWithSuggestedFilename(download.get(), filename.utf8(), allowOverwrite); + } + + void didCreateDestination(WebProcessPool*, DownloadProxy* downloadProxy, const String& path) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadDestinationCreated(download.get(), path); + } + + void didFail(WebProcessPool*, DownloadProxy* downloadProxy, const ResourceError& error) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + if (webkitDownloadIsCancelled(download.get())) { + // Cancellation takes precedence over other errors. + webkitDownloadCancelled(download.get()); + } else + webkitDownloadFailed(download.get(), error); + webkitWebContextRemoveDownload(downloadProxy); + } + + void didCancel(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); webkitDownloadCancelled(download.get()); - } else - webkitDownloadFailed(download.get(), toImpl(error)->platformError()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + webkitWebContextRemoveDownload(downloadProxy); + } -static void didCancel(WKContextRef, WKDownloadRef wkDownload, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadCancelled(download.get()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + void didFinish(WebProcessPool*, DownloadProxy* downloadProxy) override + { + GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(downloadProxy); + webkitDownloadFinished(download.get()); + webkitWebContextRemoveDownload(downloadProxy); + } -static void didFinish(WKContextRef wkContext, WKDownloadRef wkDownload, const void *clientInfo) -{ - GRefPtr<WebKitDownload> download = webkitWebContextGetOrCreateDownload(toImpl(wkDownload)); - webkitDownloadFinished(download.get()); - webkitWebContextRemoveDownload(toImpl(wkDownload)); -} + WebKitWebContext* m_webContext; +}; void attachDownloadClientToContext(WebKitWebContext* webContext) { - WKContextDownloadClientV0 wkDownloadClient = { - { - 0, // version - webContext, // ClientInfo - }, - didStart, - 0, // didReceiveAuthenticationChallenge - didReceiveResponse, - didReceiveData, - 0, // shouldDecodeSourceDataOfMIMEType - decideDestinationWithSuggestedFilename, - didCreateDestination, - didFinish, - didFail, - didCancel, - 0, // processDidCrash - }; - WKContextSetDownloadClient(toAPI(webkitWebContextGetContext(webContext)), &wkDownloadClient.base); + webkitWebContextGetProcessPool(webContext).setDownloadClient(std::make_unique<DownloadClient>(webContext)); } - diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h index 980ad732b..2d925de9c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownloadPrivate.h @@ -24,10 +24,8 @@ #include "WebKitPrivate.h" #include <WebCore/ResourceError.h> #include <WebCore/ResourceRequest.h> -#include <wtf/text/CString.h> WebKitDownload* webkitDownloadCreate(WebKit::DownloadProxy*); -WebKitDownload* webkitDownloadCreateForRequest(WebKit::DownloadProxy*, const WebCore::ResourceRequest&); bool webkitDownloadIsCancelled(WebKitDownload*); void webkitDownloadSetResponse(WebKitDownload*, WebKitURIResponse*); void webkitDownloadSetWebView(WebKitDownload*, WebKitWebView*); @@ -35,7 +33,7 @@ void webkitDownloadNotifyProgress(WebKitDownload*, guint64 bytesReceived); void webkitDownloadFailed(WebKitDownload*, const WebCore::ResourceError&); void webkitDownloadCancelled(WebKitDownload*); void webkitDownloadFinished(WebKitDownload*); -CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload*, const CString& suggestedFilename); -void webkitDownloadDestinationCreated(WebKitDownload*, const CString& destinationURI); +String webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload*, const CString& suggestedFilename, bool& allowOverwrite); +void webkitDownloadDestinationCreated(WebKitDownload*, const String& destinationPath); #endif // WebKitDownloadPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h index 437395710..f6a2061ca 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditingCommands.h @@ -94,6 +94,31 @@ G_BEGIN_DECLS */ #define WEBKIT_EDITING_COMMAND_REDO "Redo" +/** + * WEBKIT_EDITING_COMMAND_INSERT_IMAGE: + * + * The insert image command. Creates an image element that is inserted at + * the current cursor position. It receives an URI as argument, + * that is used as the image source. This command should be executed with + * webkit_web_view_execute_editing_command_with_argument(). + * + * Since: 2.10 + */ +#define WEBKIT_EDITING_COMMAND_INSERT_IMAGE "InsertImage" + +/** + * WEBKIT_EDITING_COMMAND_CREATE_LINK: + * + * The create link command. Creates a link element that is inserted at + * the current cursor position. If there's a selection, the selected text + * will be used as the link text, otherwise the URL itself will be used. + * It receives the link URL as argument. This command should be executed + * with webkit_web_view_execute_editing_command_with_argument() + * + * Since: 2.10 + */ +#define WEBKIT_EDITING_COMMAND_CREATE_LINK "CreateLink" + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp new file mode 100644 index 000000000..97d1f8a17 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitEditorState.h" + +#include "EditorState.h" +#include "WebKitEditorStatePrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; + +/** + * SECTION: WebKitEditorState + * @Short_description: Web editor state + * @Title: WebKitEditorState + * @See_also: #WebKitWebView + * + * WebKitEditorState represents the state of a #WebKitWebView editor. + * Use webkit_web_view_get_editor_state() to get WebKitEditorState of + * a #WebKitWebView. + * + * Since: 2.10 + */ + +enum { + PROP_0, + + PROP_TYPING_ATTRIBUTES +}; + +struct _WebKitEditorStatePrivate { + unsigned typingAttributes; +}; + +WEBKIT_DEFINE_TYPE(WebKitEditorState, webkit_editor_state, G_TYPE_OBJECT) + +static void webkitEditorStateGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(object); + + switch (propId) { + case PROP_TYPING_ATTRIBUTES: + g_value_set_uint(value, webkit_editor_state_get_typing_attributes(editorState)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_editor_state_class_init(WebKitEditorStateClass* editorStateClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(editorStateClass); + objectClass->get_property = webkitEditorStateGetProperty; + + /** + * WebKitEditorState:typing-attributes: + * + * Bitmask of #WebKitEditorTypingAttributes flags. + * See webkit_editor_state_get_typing_attributes() for more information. + * + * Since: 2.10 + */ + g_object_class_install_property( + objectClass, + PROP_TYPING_ATTRIBUTES, + g_param_spec_uint( + "typing-attributes", + _("Typing Attributes"), + _("Flags with the typing attributes"), + 0, G_MAXUINT, 0, + WEBKIT_PARAM_READABLE)); +} + +static void webkitEditorStateSetTypingAttributes(WebKitEditorState* editorState, unsigned typingAttributes) +{ + if (typingAttributes == editorState->priv->typingAttributes) + return; + + editorState->priv->typingAttributes = typingAttributes; + g_object_notify(G_OBJECT(editorState), "typing-attributes"); +} + +WebKitEditorState* webkitEditorStateCreate(const EditorState& state) +{ + WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(g_object_new(WEBKIT_TYPE_EDITOR_STATE, nullptr)); + webkitEditorStateChanged(editorState, state); + return editorState; +} + +void webkitEditorStateChanged(WebKitEditorState* editorState, const EditorState& newState) +{ + if (newState.isMissingPostLayoutData) + return; + + unsigned typingAttributes = WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE; + const auto& postLayoutData = newState.postLayoutData(); + if (postLayoutData.typingAttributes & AttributeBold) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD; + if (postLayoutData.typingAttributes & AttributeItalics) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC; + if (postLayoutData.typingAttributes & AttributeUnderline) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE; + if (postLayoutData.typingAttributes & AttributeStrikeThrough) + typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH; + webkitEditorStateSetTypingAttributes(editorState, typingAttributes); +} + +/** + * webkit_editor_state_get_typing_attributes: + * @editor_state: a #WebKitEditorState + * + * Gets the typing attributes at the current cursor position. + * If there is a selection, this returns the typing attributes + * of the the selected text. Note that in case of a selection, + * typing attributes are considered active only when they are + * present throughout the selection. + * + * Returns: a bitmask of #WebKitEditorTypingAttributes flags + * + * Since: 2.10 + */ +guint webkit_editor_state_get_typing_attributes(WebKitEditorState* editorState) +{ + g_return_val_if_fail(WEBKIT_IS_EDITOR_STATE(editorState), WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE); + + return editorState->priv->typingAttributes; +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h new file mode 100644 index 000000000..ae644a90a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitEditorState_h +#define WebKitEditorState_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_EDITOR_STATE (webkit_editor_state_get_type()) +#define WEBKIT_EDITOR_STATE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorState)) +#define WEBKIT_IS_EDITOR_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_EDITOR_STATE)) +#define WEBKIT_EDITOR_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass)) +#define WEBKIT_IS_EDITOR_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_EDITOR_STATE)) +#define WEBKIT_EDITOR_STATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass)) + +typedef struct _WebKitEditorState WebKitEditorState; +typedef struct _WebKitEditorStateClass WebKitEditorStateClass; +typedef struct _WebKitEditorStatePrivate WebKitEditorStatePrivate; + +/** + * WebKitEditorTypingAttributes: + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE: No typing attrubutes. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD: Bold typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC: Italic typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE: Underline typing attribute. + * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH: Strikethrough typing attribute. + * + * Enum values with flags representing typing attributes. + * + * Since: 2.10 + */ +typedef enum +{ + WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE = 1 << 1, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD = 1 << 2, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC = 1 << 3, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE = 1 << 4, + WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH = 1 << 5 +} WebKitEditorTypingAttributes; + +struct _WebKitEditorState { + GObject parent; + + WebKitEditorStatePrivate *priv; +}; + +struct _WebKitEditorStateClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_editor_state_get_type (void); + +WEBKIT_API guint +webkit_editor_state_get_typing_attributes (WebKitEditorState *editor_state); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfoPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h index ab3f1ef39..fdf9a35f5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfoPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. + * Copyright (C) 2015 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,27 +17,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitCertificateInfoPrivate_h -#define WebKitCertificateInfoPrivate_h +#ifndef WebKitEditorStatePrivate_h +#define WebKitEditorStatePrivate_h -#include "WebKitCertificateInfo.h" +#include "WebKitEditorState.h" #include "WebKitPrivate.h" -#include <WebCore/CertificateInfo.h> -struct _WebKitCertificateInfo { - _WebKitCertificateInfo(GTlsCertificate* certificate, GTlsCertificateFlags tlsErrors) - : certificateInfo(certificate, tlsErrors) - { - } +WebKitEditorState* webkitEditorStateCreate(const WebKit::EditorState&); +void webkitEditorStateChanged(WebKitEditorState*, const WebKit::EditorState&); - _WebKitCertificateInfo(WebKitCertificateInfo* info) - : certificateInfo(info->certificateInfo) - { - } - - WebCore::CertificateInfo certificateInfo; -}; - -const WebCore::CertificateInfo& webkitCertificateInfoGetCertificateInfo(WebKitCertificateInfo*); - -#endif // WebKitCertificateInfoPrivate_h +#endif // WebKitEditorStatePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp index c06dc61a5..7419ee721 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp @@ -40,53 +40,26 @@ GQuark webkit_network_error_quark() return g_quark_from_static_string(WebCore::errorDomainNetwork); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_FAILED, NetworkErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_TRANSPORT, NetworkErrorTransport); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL, NetworkErrorUnknownProtocol); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_CANCELLED, NetworkErrorCancelled); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST, NetworkErrorFileDoesNotExist); - GQuark webkit_policy_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPolicy); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_FAILED, PolicyErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE, PolicyErrorCannotShowMimeType); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI, PolicyErrorCannotShowURL); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE, PolicyErrorFrameLoadInterruptedByPolicyChange); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT, PolicyErrorCannotUseRestrictedPort); - GQuark webkit_plugin_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPlugin); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_FAILED, PluginErrorFailed); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN, PluginErrorCannotFindPlugin); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN, PluginErrorCannotLoadPlugin); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE, PluginErrorJavaUnavailable); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED, PluginErrorConnectionCancelled); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD, PluginErrorWillHandleLoad); - GQuark webkit_download_error_quark() { return g_quark_from_static_string(WebCore::errorDomainDownload); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_NETWORK, DownloadErrorNetwork); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, DownloadErrorCancelledByUser); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_DESTINATION, DownloadErrorDestination); - GQuark webkit_print_error_quark() { return g_quark_from_static_string(WebCore::errorDomainPrint); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange); - GQuark webkit_javascript_error_quark() { return g_quark_from_static_string("WebKitJavascriptError"); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h index e7de93bc2..9b6b75b38 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitError.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitError.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS #define WEBKIT_PLUGIN_ERROR webkit_plugin_error_quark () #define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark () #define WEBKIT_PRINT_ERROR webkit_print_error_quark () -#define WEBKIT_JAVASCRIPT_ERROR webkit_print_error_quark () +#define WEBKIT_JAVASCRIPT_ERROR webkit_javascript_error_quark () #define WEBKIT_SNAPSHOT_ERROR webkit_snapshot_error_quark () /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp index 0eda2729e..74654bb4f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFaviconDatabase.cpp @@ -29,8 +29,8 @@ #include <WebCore/RefPtrCairo.h> #include <glib/gi18n-lib.h> #include <wtf/RunLoop.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -181,7 +181,7 @@ static void processPendingIconsForPageURL(WebKitFaviconDatabase* database, const deletePendingIconRequests(database, pendingIconRequests, pageURL); } -static void didChangeIconForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WKURLRef wkPageURL, const void* clientInfo) +static void didChangeIconForPageURLCallback(WKIconDatabaseRef, WKURLRef wkPageURL, const void* clientInfo) { WebKitFaviconDatabase* database = WEBKIT_FAVICON_DATABASE(clientInfo); if (!database->priv->iconDatabase->isUrlImportCompleted()) @@ -203,7 +203,7 @@ static void didChangeIconForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WK g_signal_emit(database, signals[FAVICON_CHANGED], 0, pageURL.utf8().data(), currentIconURL.utf8().data()); } -static void iconDataReadyForPageURLCallback(WKIconDatabaseRef wkIconDatabase, WKURLRef wkPageURL, const void* clientInfo) +static void iconDataReadyForPageURLCallback(WKIconDatabaseRef, WKURLRef wkPageURL, const void* clientInfo) { ASSERT(RunLoop::isMain()); processPendingIconsForPageURL(WEBKIT_FAVICON_DATABASE(clientInfo), toImpl(wkPageURL)->string()); @@ -259,6 +259,12 @@ GQuark webkit_favicon_database_error_quark(void) * This is an asynchronous method. When the operation is finished, callback will * be invoked. You can then call webkit_favicon_database_get_favicon_finish() * to get the result of the operation. + * + * You must call webkit_web_context_set_favicon_database_directory() for + * the #WebKitWebContext associated with this #WebKitFaviconDatabase + * before attempting to use this function; otherwise, + * webkit_favicon_database_get_favicon_finish() will return + * %WEBKIT_FAVICON_DATABASE_ERROR_NOT_INITIALIZED. */ void webkit_favicon_database_get_favicon(WebKitFaviconDatabase* database, const gchar* pageURI, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp index 0855deea3..8b187a44e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequest.cpp @@ -21,14 +21,14 @@ #include "WebKitFileChooserRequest.h" #include "APIArray.h" +#include "APIOpenPanelParameters.h" #include "APIString.h" #include "WebKitFileChooserRequestPrivate.h" -#include "WebOpenPanelParameters.h" #include "WebOpenPanelResultListenerProxy.h" #include <WebCore/FileSystem.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -59,7 +59,7 @@ using namespace WebCore; */ struct _WebKitFileChooserRequestPrivate { - RefPtr<WebOpenPanelParameters> parameters; + RefPtr<API::OpenPanelParameters> parameters; RefPtr<WebOpenPanelResultListenerProxy> listener; GRefPtr<GtkFileFilter> filter; GRefPtr<GPtrArray> mimeTypes; @@ -175,7 +175,7 @@ static void webkit_file_chooser_request_class_init(WebKitFileChooserRequestClass WEBKIT_PARAM_READABLE)); } -WebKitFileChooserRequest* webkitFileChooserRequestCreate(WebOpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) +WebKitFileChooserRequest* webkitFileChooserRequestCreate(API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) { WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(g_object_new(WEBKIT_TYPE_FILE_CHOOSER_REQUEST, NULL)); request->priv->parameters = parameters; @@ -206,7 +206,7 @@ const gchar* const* webkit_file_chooser_request_get_mime_types(WebKitFileChooser if (request->priv->mimeTypes) return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata); - RefPtr<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); + Ref<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); size_t numOfMimeTypes = mimeTypes->size(); if (!numOfMimeTypes) return 0; @@ -247,7 +247,7 @@ GtkFileFilter* webkit_file_chooser_request_get_mime_types_filter(WebKitFileChoos if (request->priv->filter) return request->priv->filter.get(); - RefPtr<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); + Ref<API::Array> mimeTypes = request->priv->parameters->acceptMIMETypes(); size_t numOfMimeTypes = mimeTypes->size(); if (!numOfMimeTypes) return 0; @@ -299,23 +299,15 @@ void webkit_file_chooser_request_select_files(WebKitFileChooserRequest* request, g_return_if_fail(files); GRefPtr<GPtrArray> selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free)); - Vector<RefPtr<API::Object> > choosenFiles; + Vector<String> chosenFiles; for (int i = 0; files[i]; i++) { - GRefPtr<GFile> filename = adoptGRef(g_file_new_for_path(files[i])); - - // Make sure the file path is presented as an URI (escaped - // string, with the 'file://' prefix) to WebCore otherwise the - // FileChooser won't actually choose it. - GUniquePtr<char> uri(g_file_get_uri(filename.get())); - choosenFiles.append(API::URL::create(String::fromUTF8(uri.get()))); - - // Do not use the URI here because this won't reach WebCore. + chosenFiles.append(WebCore::decodeURLEscapeSequences(String::fromUTF8(files[i]))); g_ptr_array_add(selectedFiles.get(), g_strdup(files[i])); } - g_ptr_array_add(selectedFiles.get(), 0); + g_ptr_array_add(selectedFiles.get(), nullptr); // Select the files in WebCore and update local private attributes. - request->priv->listener->chooseFiles(API::Array::create(std::move(choosenFiles)).get()); + request->priv->listener->chooseFiles(chosenFiles); request->priv->selectedFiles = selectedFiles; request->priv->handledRequest = true; } @@ -354,7 +346,7 @@ const gchar* const* webkit_file_chooser_request_get_selected_files(WebKitFileCho request->priv->selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free)); for (size_t i = 0; i < numOfFiles; ++i) { API::String* webFileName = static_cast<API::String*>(selectedFileNames->at(i)); - if (webFileName->isEmpty()) + if (webFileName->stringView().isEmpty()) continue; CString filename = fileSystemRepresentation(webFileName->string()); g_ptr_array_add(request->priv->selectedFiles.get(), g_strdup(filename.data())); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h index 45d133e5b..8191ce748 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFileChooserRequestPrivate.h @@ -23,6 +23,6 @@ #include "WebKitFileChooserRequest.h" #include "WebKitPrivate.h" -WebKitFileChooserRequest* webkitFileChooserRequestCreate(WebKit::WebOpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*); +WebKitFileChooserRequest* webkitFileChooserRequestCreate(API::OpenPanelParameters*, WebKit::WebOpenPanelResultListenerProxy*); #endif // WebKitFileChooserRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp index 8759306e2..0830bccaf 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp @@ -25,7 +25,7 @@ #include "WebKitWebView.h" #include "WebKitWebViewBasePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -73,6 +73,7 @@ typedef enum { struct _WebKitFindControllerPrivate { CString searchText; + // Interpreted as WebKit::FindOptions. uint32_t findOptions; unsigned maxMatchCount; WebKitWebView* webView; @@ -82,23 +83,35 @@ static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT) -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, FindOptionsCaseInsensitive); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, FindOptionsAtWordStarts); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, FindOptionsTreatMedialCapitalAsWordStart); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_BACKWARDS, FindOptionsBackwards); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_WRAP_AROUND, FindOptionsWrapAround); +static inline WebKit::FindOptions toWebFindOptions(uint32_t findOptions) +{ + return static_cast<WebKit::FindOptions>((findOptions & WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE ? FindOptionsCaseInsensitive : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_AT_WORD_STARTS ? FindOptionsAtWordStarts : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START ? FindOptionsTreatMedialCapitalAsWordStart : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_BACKWARDS ? FindOptionsBackwards : 0) + | (findOptions & WEBKIT_FIND_OPTIONS_WRAP_AROUND ? FindOptionsWrapAround : 0)); +} + +static inline WebKitFindOptions toWebKitFindOptions(uint32_t findOptions) +{ + return static_cast<WebKitFindOptions>((findOptions & FindOptionsCaseInsensitive ? WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE : 0) + | (findOptions & FindOptionsAtWordStarts ? WEBKIT_FIND_OPTIONS_AT_WORD_STARTS : 0) + | (findOptions & FindOptionsTreatMedialCapitalAsWordStart ? WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START : 0) + | (findOptions & FindOptionsBackwards ? WEBKIT_FIND_OPTIONS_BACKWARDS : 0) + | (findOptions & FindOptionsWrapAround ? WEBKIT_FIND_OPTIONS_WRAP_AROUND : 0)); +} -static void didFindString(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +static void didFindString(WKPageRef, WKStringRef, unsigned matchCount, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FOUND_TEXT], 0, matchCount); } -static void didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo) +static void didFailToFindString(WKPageRef, WKStringRef, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FAILED_TO_FIND_TEXT], 0); } -static void didCountStringMatches(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +static void didCountStringMatches(WKPageRef, WKStringRef, unsigned matchCount, const void* clientInfo) { g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[COUNTED_MATCHES], 0, matchCount); } @@ -306,7 +319,7 @@ guint32 webkit_find_controller_get_options(WebKitFindController* findController) { g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE); - return findController->priv->findOptions; + return toWebKitFindOptions(findController->priv->findOptions); } /** @@ -349,7 +362,7 @@ static void webKitFindControllerPerform(WebKitFindController* findController, We WebKitFindControllerPrivate* priv = findController->priv; if (operation == CountOperation) { getPage(findController)->countStringMatches(String::fromUTF8(priv->searchText.data()), - static_cast<WebKit::FindOptions>(priv->findOptions), priv->maxMatchCount); + static_cast<WebKit::FindOptions>(priv->findOptions), priv->maxMatchCount); return; } @@ -406,8 +419,7 @@ void webkit_find_controller_search(WebKitFindController* findController, const g { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); g_return_if_fail(searchText); - - webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount); webKitFindControllerPerform(findController, FindOperation); } @@ -424,7 +436,7 @@ void webkit_find_controller_search_next(WebKitFindController* findController) { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); - findController->priv->findOptions &= ~WEBKIT_FIND_OPTIONS_BACKWARDS; + findController->priv->findOptions &= ~FindOptionsBackwards; findController->priv->findOptions &= ~FindOptionsShowHighlight; webKitFindControllerPerform(findController, FindNextPrevOperation); } @@ -442,7 +454,7 @@ void webkit_find_controller_search_previous(WebKitFindController* findController { g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); - findController->priv->findOptions |= WEBKIT_FIND_OPTIONS_BACKWARDS; + findController->priv->findOptions |= FindOptionsBackwards; findController->priv->findOptions &= ~FindOptionsShowHighlight; webKitFindControllerPerform(findController, FindNextPrevOperation); } @@ -464,7 +476,7 @@ void webkit_find_controller_count_matches(WebKitFindController* findController, g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); g_return_if_fail(searchText); - webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerSetSearchData(findController, searchText, toWebFindOptions(findOptions), maxMatchCount); webKitFindControllerPerform(findController, CountOperation); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h index 7bad1d051..8f3e438ff 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h @@ -62,7 +62,7 @@ typedef enum { WEBKIT_FIND_OPTIONS_AT_WORD_STARTS = 1 << 1, WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START = 1 << 2, WEBKIT_FIND_OPTIONS_BACKWARDS = 1 << 3, - WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4, + WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4 } WebKitFindOptions; struct _WebKitFindController { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp index a07f04948..12ec927a8 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormClient.cpp @@ -20,15 +20,17 @@ #include "config.h" #include "WebKitFormClient.h" +#include "APIDictionary.h" +#include "WebFormSubmissionListenerProxy.h" #include "WebKitFormSubmissionRequestPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; -static void willSubmitForm(WKPageRef page, WKFrameRef frame, WKFrameRef sourceFrame, WKDictionaryRef values, WKTypeRef userData, WKFormSubmissionListenerRef listener, const void* clientInfo) +static void willSubmitForm(WKPageRef, WKFrameRef, WKFrameRef, WKDictionaryRef values, WKTypeRef /* userData */, WKFormSubmissionListenerRef listener, const void* clientInfo) { GRefPtr<WebKitFormSubmissionRequest> request = adoptGRef(webkitFormSubmissionRequestCreate(toImpl(values), toImpl(listener))); webkitWebViewSubmitFormRequest(WEBKIT_WEB_VIEW(clientInfo), request.get()); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp index 8519a2cb6..7af2aee10 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequest.cpp @@ -20,11 +20,11 @@ #include "config.h" #include "WebKitFormSubmissionRequest.h" +#include "APIDictionary.h" #include "APIString.h" -#include "ImmutableDictionary.h" #include "WebFormSubmissionListenerProxy.h" #include "WebKitFormSubmissionRequestPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -45,7 +45,7 @@ using namespace WebKit; */ struct _WebKitFormSubmissionRequestPrivate { - RefPtr<ImmutableDictionary> webValues; + RefPtr<API::Dictionary> webValues; RefPtr<WebFormSubmissionListenerProxy> listener; GRefPtr<GHashTable> values; bool handledRequest; @@ -70,7 +70,7 @@ static void webkit_form_submission_request_class_init(WebKitFormSubmissionReques objectClass->dispose = webkitFormSubmissionRequestDispose; } -WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(ImmutableDictionary* values, WebFormSubmissionListenerProxy* listener) +WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(API::Dictionary* values, WebFormSubmissionListenerProxy* listener) { WebKitFormSubmissionRequest* request = WEBKIT_FORM_SUBMISSION_REQUEST(g_object_new(WEBKIT_TYPE_FORM_SUBMISSION_REQUEST, NULL)); request->priv->webValues = values; @@ -96,18 +96,18 @@ GHashTable* webkit_form_submission_request_get_text_fields(WebKitFormSubmissionR return request->priv->values.get(); if (!request->priv->webValues->size()) - return 0; + return nullptr; request->priv->values = adoptGRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free)); - const ImmutableDictionary::MapType& map = request->priv->webValues->map(); - ImmutableDictionary::MapType::const_iterator end = map.end(); - for (ImmutableDictionary::MapType::const_iterator it = map.begin(); it != end; ++it) { + const API::Dictionary::MapType& map = request->priv->webValues->map(); + API::Dictionary::MapType::const_iterator end = map.end(); + for (API::Dictionary::MapType::const_iterator it = map.begin(); it != end; ++it) { API::String* value = static_cast<API::String*>(it->value.get()); g_hash_table_insert(request->priv->values.get(), g_strdup(it->key.utf8().data()), g_strdup(value->string().utf8().data())); } - request->priv->webValues = 0; + request->priv->webValues = nullptr; return request->priv->values.get(); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h index 9fe4751d2..1d2b499f6 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFormSubmissionRequestPrivate.h @@ -23,6 +23,6 @@ #include "WebKitFormSubmissionRequest.h" #include "WebKitPrivate.h" -WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(WebKit::ImmutableDictionary* values, WebKit::WebFormSubmissionListenerProxy*); +WebKitFormSubmissionRequest* webkitFormSubmissionRequestCreate(API::Dictionary* values, WebKit::WebFormSubmissionListenerProxy*); #endif // WebKitFormSubmissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h b/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h index a9898de48..543f4b136 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitForwardDeclarations.h @@ -23,7 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp index f780dafb2..871c3cf3e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationPermissionRequest.cpp @@ -35,6 +35,9 @@ using namespace WebKit; * WebKitGeolocationPermissionRequest represents a request for * permission to decide whether WebKit should provide the user's * location to a website when requested throught the Geolocation API. + * + * When a WebKitGeolocationPermissionRequest is not handled by the user, + * it is denied by default. */ static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp index 261abf81a..6ac0fbc98 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.cpp @@ -38,12 +38,12 @@ static inline WebKitGeolocationProvider* toGeolocationProvider(const void* clien return static_cast<WebKitGeolocationProvider*>(const_cast<void*>(clientInfo)); } -static void startUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +static void startUpdatingCallback(WKGeolocationManagerRef, const void* clientInfo) { toGeolocationProvider(clientInfo)->startUpdating(); } -static void stopUpdatingCallback(WKGeolocationManagerRef geolocationManager, const void* clientInfo) +static void stopUpdatingCallback(WKGeolocationManagerRef, const void* clientInfo) { toGeolocationProvider(clientInfo)->stopUpdating(); } @@ -51,11 +51,12 @@ static void stopUpdatingCallback(WKGeolocationManagerRef geolocationManager, con WebKitGeolocationProvider::~WebKitGeolocationProvider() { m_provider.stopUpdating(); + WKGeolocationManagerSetProvider(toAPI(m_geolocationManager.get()), nullptr); } -PassRefPtr<WebKitGeolocationProvider> WebKitGeolocationProvider::create(WebGeolocationManagerProxy* geolocationManager) +Ref<WebKitGeolocationProvider> WebKitGeolocationProvider::create(WebGeolocationManagerProxy* geolocationManager) { - return adoptRef(new WebKitGeolocationProvider(geolocationManager)); + return adoptRef(*new WebKitGeolocationProvider(geolocationManager)); } WebKitGeolocationProvider::WebKitGeolocationProvider(WebGeolocationManagerProxy* geolocationManager) @@ -92,7 +93,7 @@ void WebKitGeolocationProvider::notifyPositionChanged(int timestamp, double lati m_geolocationManager->providerDidChangePosition(position.get()); } -void WebKitGeolocationProvider::notifyErrorOccurred(const char* message) +void WebKitGeolocationProvider::notifyErrorOccurred(const char* /* message */) { m_geolocationManager->providerDidFailToDeterminePosition(); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h index e6be3eac2..e18dc56ac 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitGeolocationProvider.h @@ -25,7 +25,7 @@ #include "WebKitPrivate.h" #include <WebCore/GeolocationProviderGeoclue.h> #include <WebCore/GeolocationProviderGeoclueClient.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefCounted.h> namespace WebKit { @@ -33,7 +33,7 @@ namespace WebKit { class WebKitGeolocationProvider : public RefCounted<WebKitGeolocationProvider>, public WebCore::GeolocationProviderGeoclueClient { public: virtual ~WebKitGeolocationProvider(); - static PassRefPtr<WebKitGeolocationProvider> create(WebGeolocationManagerProxy*); + static Ref<WebKitGeolocationProvider> create(WebGeolocationManagerProxy*); void startUpdating(); void stopUpdating(); @@ -42,8 +42,8 @@ private: WebKitGeolocationProvider(WebGeolocationManagerProxy*); // GeolocationProviderGeoclueClient interface. - virtual void notifyPositionChanged(int, double, double, double, double, double); - virtual void notifyErrorOccurred(const char*); + void notifyPositionChanged(int, double, double, double, double, double) override; + void notifyErrorOccurred(const char*) override; RefPtr<WebGeolocationManagerProxy> m_geolocationManager; WebCore::GeolocationProviderGeoclue m_provider; diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp index 918d316c0..60b5fb853 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.cpp @@ -20,7 +20,7 @@ #include "config.h" #include "WebKitHitTestResult.h" -#include "WebHitTestResult.h" +#include "WebHitTestResultData.h" #include "WebKitHitTestResultPrivate.h" #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> @@ -221,39 +221,36 @@ static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* hitTestR paramFlags)); } -WebKitHitTestResult* webkitHitTestResultCreate(WebHitTestResult* hitTestResult) +WebKitHitTestResult* webkitHitTestResultCreate(const WebHitTestResultData& hitTestResult) { unsigned context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT; - const String& linkURL = hitTestResult->absoluteLinkURL(); - if (!linkURL.isEmpty()) + if (!hitTestResult.absoluteLinkURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK; - const String& imageURL = hitTestResult->absoluteImageURL(); - if (!imageURL.isEmpty()) + if (!hitTestResult.absoluteImageURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE; - const String& mediaURL = hitTestResult->absoluteMediaURL(); - if (!mediaURL.isEmpty()) + if (!hitTestResult.absoluteMediaURL.isEmpty()) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA; - if (hitTestResult->isContentEditable()) + if (hitTestResult.isContentEditable) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE; - if (hitTestResult->isScrollbar()) + if (hitTestResult.isScrollbar) context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR; - const String& linkTitle = hitTestResult->linkTitle(); - const String& linkLabel = hitTestResult->linkLabel(); + if (hitTestResult.isSelected) + context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT, - "context", context, - "link-uri", !linkURL.isEmpty() ? linkURL.utf8().data() : 0, - "image-uri", !imageURL.isEmpty() ? imageURL.utf8().data() : 0, - "media-uri", !mediaURL.isEmpty() ? mediaURL.utf8().data() : 0, - "link-title", !linkTitle.isEmpty() ? linkTitle.utf8().data() : 0, - "link-label", !linkLabel.isEmpty() ? linkLabel.utf8().data() : 0, - NULL)); + "context", context, + "link-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK ? hitTestResult.absoluteLinkURL.utf8().data() : nullptr, + "image-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE ? hitTestResult.absoluteImageURL.utf8().data() : nullptr, + "media-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA ? hitTestResult.absoluteMediaURL.utf8().data() : nullptr, + "link-title", !hitTestResult.linkTitle.isEmpty() ? hitTestResult.linkTitle.utf8().data() : nullptr, + "link-label", !hitTestResult.linkLabel.isEmpty() ? hitTestResult.linkLabel.utf8().data() : nullptr, + nullptr)); } static bool stringIsEqualToCString(const String& string, const CString& cString) @@ -261,16 +258,17 @@ static bool stringIsEqualToCString(const String& string, const CString& cString) return ((string.isEmpty() && cString.isNull()) || (string.utf8() == cString)); } -bool webkitHitTestResultCompare(WebKitHitTestResult* hitTestResult, WebHitTestResult* webHitTestResult) +bool webkitHitTestResultCompare(WebKitHitTestResult* hitTestResult, const WebHitTestResultData& webHitTestResult) { WebKitHitTestResultPrivate* priv = hitTestResult->priv; - return webHitTestResult->isContentEditable() == webkit_hit_test_result_context_is_editable(hitTestResult) - && webHitTestResult->isScrollbar() == webkit_hit_test_result_context_is_scrollbar(hitTestResult) - && stringIsEqualToCString(webHitTestResult->absoluteLinkURL(), priv->linkURI) - && stringIsEqualToCString(webHitTestResult->linkTitle(), priv->linkTitle) - && stringIsEqualToCString(webHitTestResult->linkLabel(), priv->linkLabel) - && stringIsEqualToCString(webHitTestResult->absoluteImageURL(), priv->imageURI) - && stringIsEqualToCString(webHitTestResult->absoluteMediaURL(), priv->mediaURI); + return webHitTestResult.isContentEditable == webkit_hit_test_result_context_is_editable(hitTestResult) + && webHitTestResult.isScrollbar == webkit_hit_test_result_context_is_scrollbar(hitTestResult) + && webHitTestResult.isSelected == webkit_hit_test_result_context_is_selection(hitTestResult) + && stringIsEqualToCString(webHitTestResult.absoluteLinkURL, priv->linkURI) + && stringIsEqualToCString(webHitTestResult.linkTitle, priv->linkTitle) + && stringIsEqualToCString(webHitTestResult.linkLabel, priv->linkLabel) + && stringIsEqualToCString(webHitTestResult.absoluteImageURL, priv->imageURI) + && stringIsEqualToCString(webHitTestResult.absoluteMediaURL, priv->mediaURI); } /** @@ -357,6 +355,25 @@ gboolean webkit_hit_test_result_context_is_editable(WebKitHitTestResult* hitTest } /** + * webkit_hit_test_result_context_is_selection: + * @hit_test_result: a #WebKitHitTestResult + * + * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION flag is present in + * #WebKitHitTestResult:context. + * + * Returns: %TRUE if there's a selected element at the coordinates of the @hit_test_result, + * or %FALSE otherwise + * + * Since: 2.8 + */ +gboolean webkit_hit_test_result_context_is_selection(WebKitHitTestResult* hitTestResult) +{ + g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE); + + return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION; +} + +/** * webkit_hit_test_result_get_link_uri: * @hit_test_result: a #WebKitHitTestResult * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h index 54611ba92..718573b90 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResult.h @@ -17,7 +17,7 @@ * Boston, MA 02110-1301, USA. */ -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__) #error "Only <webkit2/webkit2.h> can be included directly." #endif @@ -48,6 +48,7 @@ typedef struct _WebKitHitTestResultPrivate WebKitHitTestResultPrivate; * @WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA: a video or audio element. * @WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE: an editable element * @WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR: a scrollbar element. + * @WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION: a selected element. Since 2.8 * * Enum values with flags representing the context of a #WebKitHitTestResult. */ @@ -58,7 +59,8 @@ typedef enum WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE = 1 << 3, WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA = 1 << 4, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE = 1 << 5, - WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6 + WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR = 1 << 6, + WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION = 1 << 7 } WebKitHitTestResultContext; struct _WebKitHitTestResult { @@ -94,6 +96,9 @@ webkit_hit_test_result_context_is_media (WebKitHitTestResult *hit_test_resul WEBKIT_API gboolean webkit_hit_test_result_context_is_editable (WebKitHitTestResult *hit_test_result); +WEBKIT_API gboolean +webkit_hit_test_result_context_is_selection (WebKitHitTestResult *hit_test_result); + WEBKIT_API const gchar * webkit_hit_test_result_get_link_uri (WebKitHitTestResult *hit_test_result); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h index 7ba2c3871..4fdb46deb 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitHitTestResultPrivate.h @@ -23,7 +23,7 @@ #include "WebKitHitTestResult.h" #include "WebKitPrivate.h" -WebKitHitTestResult* webkitHitTestResultCreate(WebKit::WebHitTestResult*); -bool webkitHitTestResultCompare(WebKitHitTestResult*, WebKit::WebHitTestResult*); +WebKitHitTestResult* webkitHitTestResultCreate(const WebKit::WebHitTestResultData&); +bool webkitHitTestResultCompare(WebKitHitTestResult*, const WebKit::WebHitTestResultData&); #endif // WebKitHitTestResultPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp index 1b77b6ea7..0ec44d463 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInjectedBundleClient.cpp @@ -21,17 +21,18 @@ #include "WebKitInjectedBundleClient.h" #include "WebImage.h" +#include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebResourcePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> using namespace WebKit; using namespace WebCore; -static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, const char* messageName, ImmutableDictionary& message) +static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, const char* messageName, API::Dictionary& message) { if (g_str_equal(messageName, "DidInitiateLoadForResource")) { WebFrameProxy* frame = static_cast<WebFrameProxy*>(message.get(String::fromUTF8("Frame"))); @@ -87,9 +88,12 @@ static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, c API::Error* webError = static_cast<API::Error*>(message.get(String::fromUTF8("Error"))); const ResourceError& platformError = webError->platformError(); GUniquePtr<GError> resourceError(g_error_new_literal(g_quark_from_string(platformError.domain().utf8().data()), - platformError.errorCode(), platformError.localizedDescription().utf8().data())); + toWebKitError(platformError.errorCode()), platformError.localizedDescription().utf8().data())); + if (platformError.tlsErrors()) + webkitWebResourceFailedWithTLSErrors(resource.get(), static_cast<GTlsCertificateFlags>(platformError.tlsErrors()), platformError.certificate()); + else + webkitWebResourceFailed(resource.get(), resourceError.get()); - webkitWebResourceFailed(resource.get(), resourceError.get()); webkitWebViewRemoveLoadingWebResource(webView, resourceIdentifier->value()); } else if (g_str_equal(messageName, "DidGetSnapshot")) { API::UInt64* callbackID = static_cast<API::UInt64*>(message.get("CallbackID")); @@ -102,7 +106,7 @@ static void didReceiveWebViewMessageFromInjectedBundle(WebKitWebView* webView, c static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo) { ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID()); - ImmutableDictionary& message = *toImpl(static_cast<WKDictionaryRef>(messageBody)); + API::Dictionary& message = *toImpl(static_cast<WKDictionaryRef>(messageBody)); CString messageNameCString = toImpl(messageName)->string().utf8(); const char* messageNameUTF8 = messageNameCString.data(); @@ -136,5 +140,5 @@ void attachInjectedBundleClientToContext(WebKitWebContext* webContext) 0, // didReceiveSynchronousMessageFromInjectedBundle getInjectedBundleInitializationUserData }; - WKContextSetInjectedBundleClient(toAPI(webkitWebContextGetContext(webContext)), &wkInjectedBundleClient.base); + WKContextSetInjectedBundleClient(toAPI(&webkitWebContextGetProcessPool(webContext)), &wkInjectedBundleClient.base); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp new file mode 100644 index 000000000..d516b61ad --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequest.h" + +#include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h" +#include "WebKitPermissionRequest.h" +#include "WebPageProxy.h" + +#if ENABLE(VIDEO) +#include <WebCore/PlatformDisplay.h> +#include <gtk/gtk.h> +#if PLATFORM(X11) +#include <gdk/gdkx.h> +#endif +#endif + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitInstallMissingMediaPluginsPermissionRequest + * @Short_description: A permission request for installing missing media plugins + * @Title: WebKitInstallMissingMediaPluginsPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitInstallMissingMediaPluginsPermissionRequest represents a request for + * permission to decide whether WebKit should try to start a helper application to + * install missing media plugins when the media backend couldn't play a media because + * the required plugins were not available. + * + * When a WebKitInstallMissingMediaPluginsPermissionRequest is not handled by the user, + * it is allowed by default. + * + * Since: 2.10 + */ + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitInstallMissingMediaPluginsPermissionRequestPrivate { +#if ENABLE(VIDEO) + RefPtr<InstallMissingMediaPluginsPermissionRequest> request; +#endif + CString description; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitInstallMissingMediaPluginsPermissionRequest, webkit_install_missing_media_plugins_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +#if ENABLE(VIDEO) +static GUniquePtr<GstInstallPluginsContext> createGstInstallPluginsContext(GtkWidget* widget) +{ +#if PLATFORM(X11) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + GUniquePtr<GstInstallPluginsContext> context(gst_install_plugins_context_new()); + gst_install_plugins_context_set_xid(context.get(), GDK_WINDOW_XID(gtk_widget_get_window(widget))); + return context; + } +#endif + + return nullptr; +} +#endif + +static void webkitInstallMissingMediaPluginsPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)); + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate* priv = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; +#if ENABLE(VIDEO) + priv->request->allow(createGstInstallPluginsContext(priv->request->page().viewWidget())); +#endif + priv->madeDecision = true; +} + +static void webkitInstallMissingMediaPluginsPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)); + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate* priv = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + +#if ENABLE(VIDEO) + priv->request->deny(); +#endif + priv->madeDecision = true; +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitInstallMissingMediaPluginsPermissionRequestAllow; + iface->deny = webkitInstallMissingMediaPluginsPermissionRequestDeny; +} + +static void webkitInstallMissingMediaPluginsPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is allowing the request for backwards compatibility. + webkitInstallMissingMediaPluginsPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_install_missing_media_plugins_permission_request_parent_class)->dispose(object); +} + +static void webkit_install_missing_media_plugins_permission_request_class_init(WebKitInstallMissingMediaPluginsPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitInstallMissingMediaPluginsPermissionRequestDispose; +} + +#if ENABLE(VIDEO) +WebKitInstallMissingMediaPluginsPermissionRequest* webkitInstallMissingMediaPluginsPermissionRequestCreate(InstallMissingMediaPluginsPermissionRequest& request) +{ + WebKitInstallMissingMediaPluginsPermissionRequest* permissionRequest = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, nullptr)); + permissionRequest->priv->request = &request; + return permissionRequest; +} +#endif + +/** + * webkit_install_missing_media_plugins_permission_request_get_description: + * @request: a #WebKitInstallMissingMediaPluginsPermissionRequest + * + * Gets the description about the missing plugins provided by the media backend when a media couldn't be played. + * + * Returns: a string with the description provided by the media backend. + * + * Since: 2.10 + */ +const char* webkit_install_missing_media_plugins_permission_request_get_description(WebKitInstallMissingMediaPluginsPermissionRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request), nullptr); + +#if ENABLE(VIDEO) + if (!request->priv->description.isNull()) + return request->priv->description.data(); + + const auto& description = request->priv->request->description(); + ASSERT(!description.isEmpty()); + request->priv->description = description.utf8(); +#endif + return request->priv->description.data(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h new file mode 100644 index 000000000..e0632afa5 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequest.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitInstallMissingMediaPluginsPermissionRequest_h +#define WebKitInstallMissingMediaPluginsPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST (webkit_install_missing_media_plugins_permission_request_get_type()) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequest)) +#define WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST)) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequestClass)) +#define WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST)) +#define WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST, WebKitInstallMissingMediaPluginsPermissionRequestClass)) + +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequest WebKitInstallMissingMediaPluginsPermissionRequest; +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequestClass WebKitInstallMissingMediaPluginsPermissionRequestClass; +typedef struct _WebKitInstallMissingMediaPluginsPermissionRequestPrivate WebKitInstallMissingMediaPluginsPermissionRequestPrivate; + +struct _WebKitInstallMissingMediaPluginsPermissionRequest { + GObject parent; + + WebKitInstallMissingMediaPluginsPermissionRequestPrivate *priv; +}; + +struct _WebKitInstallMissingMediaPluginsPermissionRequestClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_install_missing_media_plugins_permission_request_get_type (void); + +WEBKIT_API const gchar * +webkit_install_missing_media_plugins_permission_request_get_description (WebKitInstallMissingMediaPluginsPermissionRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h new file mode 100644 index 000000000..2c7e3bc0d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h +#define WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h + +#include "InstallMissingMediaPluginsPermissionRequest.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequest.h" +#include "WebKitPrivate.h" + +#if ENABLE(VIDEO) +WebKitInstallMissingMediaPluginsPermissionRequest* webkitInstallMissingMediaPluginsPermissionRequestCreate(WebKit::InstallMissingMediaPluginsPermissionRequest&); +#endif + +#endif // WebKitInstallMissingMediaPluginsPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp index 9bbd3f4ed..79ec69b70 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResult.cpp @@ -20,18 +20,18 @@ #include "config.h" #include "WebKitJavascriptResult.h" +#include "APISerializedScriptValue.h" #include "WebKitJavascriptResultPrivate.h" -#include "WebSerializedScriptValue.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; struct _WebKitJavascriptResult { - _WebKitJavascriptResult(WebKitWebView* view, WebSerializedScriptValue* serializedScriptValue) + _WebKitJavascriptResult(WebKitWebView* view, WebCore::SerializedScriptValue& serializedScriptValue) : webView(view) , referenceCount(1) { - value = serializedScriptValue->deserialize(webkit_web_view_get_javascript_global_context(view), 0); + value = serializedScriptValue.deserialize(webkit_web_view_get_javascript_global_context(view), nullptr); } GRefPtr<WebKitWebView> webView; @@ -42,9 +42,9 @@ struct _WebKitJavascriptResult { G_DEFINE_BOXED_TYPE(WebKitJavascriptResult, webkit_javascript_result, webkit_javascript_result_ref, webkit_javascript_result_unref) -WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebSerializedScriptValue* serializedScriptValue) +WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView* webView, WebCore::SerializedScriptValue& serializedScriptValue) { - WebKitJavascriptResult* result = g_slice_new(WebKitJavascriptResult); + WebKitJavascriptResult* result = static_cast<WebKitJavascriptResult*>(fastMalloc(sizeof(WebKitJavascriptResult))); new (result) WebKitJavascriptResult(webView, serializedScriptValue); return result; } @@ -77,7 +77,7 @@ void webkit_javascript_result_unref(WebKitJavascriptResult* javascriptResult) { if (g_atomic_int_dec_and_test(&javascriptResult->referenceCount)) { javascriptResult->~WebKitJavascriptResult(); - g_slice_free(WebKitJavascriptResult, javascriptResult); + fastFree(javascriptResult); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h index e47e94c1b..23e2e7926 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitJavascriptResultPrivate.h @@ -20,10 +20,11 @@ #ifndef WebKitJavascriptResultPrivate_h #define WebKitJavascriptResultPrivate_h +#include <WebCore/SerializedScriptValue.h> #include "WebKitJavascriptResult.h" #include "WebKitPrivate.h" #include "WebKitWebView.h" -WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebKit::WebSerializedScriptValue*); +WebKitJavascriptResult* webkitJavascriptResultCreate(WebKitWebView*, WebCore::SerializedScriptValue&); #endif // WebKitJavascriptResultPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp index 4b2e59c25..f52c8c78e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitLoaderClient.cpp @@ -21,166 +21,107 @@ #include "config.h" #include "WebKitLoaderClient.h" +#include "APILoaderClient.h" #include "WebKitBackForwardListPrivate.h" +#include "WebKitPrivate.h" #include "WebKitURIResponsePrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; using namespace WebCore; -static void didStartProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED); -} - -static void didReceiveServerRedirectForProvisionalLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_REDIRECTED); -} - -static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - const ResourceError& resourceError = toImpl(error)->platformError(); - GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - if (resourceError.tlsErrors()) { - webkitWebViewLoadFailedWithTLSErrors(WEBKIT_WEB_VIEW(clientInfo), resourceError.failingURL().utf8().data(), webError.get(), - static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate()); - } else - webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_STARTED, resourceError.failingURL().utf8().data(), webError.get()); -} - -static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED); -} - -static void didFinishLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewLoadChanged(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_FINISHED); -} - -static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - const ResourceError& resourceError = toImpl(error)->platformError(); - GUniquePtr<GError> webError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - webkitWebViewLoadFailed(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_LOAD_COMMITTED, - resourceError.failingURL().utf8().data(), webError.get()); -} - -static void didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frame)) - return; - - webkitWebViewUpdateURI(WEBKIT_WEB_VIEW(clientInfo)); -} - -static void didReceiveTitleForFrame(WKPageRef page, WKStringRef titleRef, WKFrameRef frameRef, WKTypeRef, const void* clientInfo) -{ - if (!WKFrameIsMainFrame(frameRef)) - return; - - webkitWebViewSetTitle(WEBKIT_WEB_VIEW(clientInfo), toImpl(titleRef)->string().utf8()); -} - -static void didDisplayInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) -{ - webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_DISPLAYED); -} - -static void didRunInsecureContentForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void *clientInfo) -{ - webkitWebViewInsecureContentDetected(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_INSECURE_CONTENT_RUN); -} - -static void didChangeProgress(WKPageRef page, const void* clientInfo) -{ - webkitWebViewSetEstimatedLoadProgress(WEBKIT_WEB_VIEW(clientInfo), WKPageGetEstimatedProgress(page)); -} - -static void didChangeBackForwardList(WKPageRef page, WKBackForwardListItemRef addedItem, WKArrayRef removedItems, const void* clientInfo) -{ - webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(clientInfo)), toImpl(addedItem), toImpl(removedItems)); -} - -static void didReceiveAuthenticationChallengeInFrame(WKPageRef page, WKFrameRef frame, WKAuthenticationChallengeRef authenticationChallenge, const void *clientInfo) -{ - webkitWebViewHandleAuthenticationChallenge(WEBKIT_WEB_VIEW(clientInfo), toImpl(authenticationChallenge)); -} - -static void processDidCrash(WKPageRef page, const void* clientInfo) -{ - webkitWebViewWebProcessCrashed(WEBKIT_WEB_VIEW(clientInfo)); -} +class LoaderClient : public API::LoaderClient { +public: + explicit LoaderClient(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + void didStartProvisionalLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_STARTED); + } + + void didReceiveServerRedirectForProvisionalLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_REDIRECTED); + } + + void didFailProvisionalLoadWithErrorForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + if (resourceError.tlsErrors()) { + webkitWebViewLoadFailedWithTLSErrors(m_webView, resourceError.failingURL().string().utf8().data(), error.get(), + static_cast<GTlsCertificateFlags>(resourceError.tlsErrors()), resourceError.certificate()); + } else + webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_STARTED, resourceError.failingURL().string().utf8().data(), error.get()); + } + + void didCommitLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_COMMITTED); + } + + void didFinishLoadForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + webkitWebViewLoadChanged(m_webView, WEBKIT_LOAD_FINISHED); + } + + void didFailLoadWithErrorForFrame(WebPageProxy&, WebFrameProxy& frame, API::Navigation*, const ResourceError& resourceError, API::Object* /* userData */) override + { + if (!frame.isMainFrame()) + return; + GUniquePtr<GError> error(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + webkitWebViewLoadFailed(m_webView, WEBKIT_LOAD_COMMITTED, resourceError.failingURL().string().utf8().data(), error.get()); + } + + void didDisplayInsecureContentForFrame(WebPageProxy&, WebFrameProxy&, API::Object* /* userData */) override + { + webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_DISPLAYED); + } + + void didRunInsecureContentForFrame(WebPageProxy&, WebFrameProxy&, API::Object* /* userData */) override + { + webkitWebViewInsecureContentDetected(m_webView, WEBKIT_INSECURE_CONTENT_RUN); + } + + void didChangeBackForwardList(WebPageProxy&, WebBackForwardListItem* addedItem, Vector<RefPtr<WebBackForwardListItem>> removedItems) override + { + webkitBackForwardListChanged(webkit_web_view_get_back_forward_list(m_webView), addedItem, removedItems); + } + + void didReceiveAuthenticationChallengeInFrame(WebPageProxy&, WebFrameProxy&, AuthenticationChallengeProxy* authenticationChallenge) override + { + webkitWebViewHandleAuthenticationChallenge(m_webView, authenticationChallenge); + } + + void processDidCrash(WebPageProxy&) override + { + webkitWebViewWebProcessCrashed(m_webView); + } + + WebKitWebView* m_webView; +}; void attachLoaderClientToView(WebKitWebView* webView) { - WKPageLoaderClientV3 wkLoaderClient = { - { - 3, // version - webView, // clientInfo - }, - didStartProvisionalLoadForFrame, - didReceiveServerRedirectForProvisionalLoadForFrame, - didFailProvisionalLoadWithErrorForFrame, - didCommitLoadForFrame, - 0, // didFinishDocumentLoadForFrame - didFinishLoadForFrame, - didFailLoadWithErrorForFrame, - didSameDocumentNavigationForFrame, - didReceiveTitleForFrame, - 0, // didFirstLayoutForFrame - 0, // didFirstVisuallyNonEmptyLayoutForFrame - 0, // didRemoveFrameFromHierarchy - didDisplayInsecureContentForFrame, - didRunInsecureContentForFrame, - 0, // canAuthenticateAgainstProtectionSpaceInFrame - didReceiveAuthenticationChallengeInFrame, - didChangeProgress, // didStartProgress - didChangeProgress, - didChangeProgress, // didFinishProgress - 0, // didBecomeUnresponsive - 0, // didBecomeResponsive - processDidCrash, - didChangeBackForwardList, - 0, // shouldGoToBackForwardListItem - 0, // didFailToInitializePlugin - 0, // didDetectXSSForFrame - 0, // didFirstVisuallyNonEmptyLayoutForFrame - 0, // willGoToBackForwardListItem - 0, // interactionOccurredWhileProcessUnresponsive - 0, // pluginDidFail_deprecatedForUseWithV1 - 0, // didReceiveIntentForFrame - 0, // registerIntentServiceForFrame - 0, // didLayout - 0, // pluginLoadPolicy_deprecatedForUseWithV2 - 0, // pluginDidFail - 0, // pluginLoadPolicy - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageLoaderClient(wkPage, &wkLoaderClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setLoaderClient(std::make_unique<LoaderClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp index 2282ede37..af61dc69a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitMimeInfo.cpp @@ -21,7 +21,7 @@ #include "WebKitMimeInfo.h" #include "WebKitMimeInfoPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> struct _WebKitMimeInfo { @@ -42,7 +42,7 @@ G_DEFINE_BOXED_TYPE(WebKitMimeInfo, webkit_mime_info, webkit_mime_info_ref, webk WebKitMimeInfo* webkitMimeInfoCreate(const WebCore::MimeClassInfo& mimeInfo) { - WebKitMimeInfo* info = g_slice_new(WebKitMimeInfo); + WebKitMimeInfo* info = static_cast<WebKitMimeInfo*>(fastMalloc(sizeof(WebKitMimeInfo))); new (info) WebKitMimeInfo(mimeInfo); return info; } @@ -75,7 +75,7 @@ void webkit_mime_info_unref(WebKitMimeInfo* info) { if (g_atomic_int_dec_and_test(&info->referenceCount)) { info->~WebKitMimeInfo(); - g_slice_free(WebKitMimeInfo, info); + fastFree(info); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp new file mode 100644 index 000000000..bcce8ba42 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNavigationAction.h" + +#include "WebKitNavigationActionPrivate.h" +#include <gdk/gdk.h> +#include <wtf/glib/GRefPtr.h> + +using namespace WebKit; + +G_DEFINE_BOXED_TYPE(WebKitNavigationAction, webkit_navigation_action, webkit_navigation_action_copy, webkit_navigation_action_free) + +WebKitNavigationAction* webkitNavigationActionCreate(WebKitURIRequest* request, const NavigationActionData& navigationActionData) +{ + WebKitNavigationAction* navigation = static_cast<WebKitNavigationAction*>(fastZeroedMalloc(sizeof(WebKitNavigationAction))); + new (navigation) WebKitNavigationAction(request, navigationActionData); + return navigation; +} + +/** + * webkit_navigation_action_copy: + * @navigation: a #WebKitNavigationAction + * + * Make a copy of @navigation. + * + * Returns: (transfer full): A copy of passed in #WebKitNavigationAction + * + * Since: 2.6 + */ +WebKitNavigationAction* webkit_navigation_action_copy(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, nullptr); + + WebKitNavigationAction* copy = static_cast<WebKitNavigationAction*>(fastZeroedMalloc(sizeof(WebKitNavigationAction))); + new (copy) WebKitNavigationAction(navigation); + return copy; +} + +/** + * webkit_navigation_action_free: + * @navigation: a #WebKitNavigationAction + * + * Free the #WebKitNavigationAction + * + * Since: 2.6 + */ +void webkit_navigation_action_free(WebKitNavigationAction* navigation) +{ + g_return_if_fail(navigation); + + navigation->~WebKitNavigationAction(); + fastFree(navigation); +} + +/** + * webkit_navigation_action_get_navigation_type: + * @navigation: a #WebKitNavigationAction + * + * Return the type of action that triggered the navigation. + * + * Returns: a #WebKitNavigationType + * + * Since: 2.6 + */ +WebKitNavigationType webkit_navigation_action_get_navigation_type(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, WEBKIT_NAVIGATION_TYPE_OTHER); + return navigation->type; +} + +/** + * webkit_navigation_action_get_mouse_button: + * @navigation: a #WebKitNavigationAction + * + * Return the number of the mouse button that triggered the navigation, or 0 if + * the navigation was not started by a mouse event. + * + * Returns: the mouse button number or 0 + * + * Since: 2.6 + */ +unsigned webkit_navigation_action_get_mouse_button(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, 0); + return navigation->mouseButton; +} + +/** + * webkit_navigation_action_get_modifiers: + * @navigation: a #WebKitNavigationAction + * + * Return a bitmask of #GdkModifierType values describing the modifier keys that were in effect + * when the navigation was requested + * + * Returns: the modifier keys + * + * Since: 2.6 + */ +unsigned webkit_navigation_action_get_modifiers(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, 0); + return navigation->modifiers; +} + +/** + * webkit_navigation_action_get_request: + * @navigation: a #WebKitNavigationAction + * + * Return the navigation #WebKitURIRequest + * + * Returns: (transfer none): a #WebKitURIRequest + * + * Since: 2.6 + */ +WebKitURIRequest* webkit_navigation_action_get_request(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, nullptr); + return navigation->request.get(); +} + +/** + * webkit_navigation_action_is_user_gesture: + * @navigation: a #WebKitNavigationAction + * + * Return whether the navigation was triggered by a user gesture like a mouse click. + * + * Returns: whether navigation action is a user gesture + * + * Since: 2.6 + */ +gboolean webkit_navigation_action_is_user_gesture(WebKitNavigationAction* navigation) +{ + g_return_val_if_fail(navigation, FALSE); + return navigation->isUserGesture; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h new file mode 100644 index 000000000..ae95586bc --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationAction.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNavigationAction_h +#define WebKitNavigationAction_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitURIRequest.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NAVIGATION_ACTION (webkit_navigation_action_get_type()) + +/** + * WebKitNavigationType: + * @WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: The navigation was triggered by clicking a link. + * @WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: The navigation was triggered by submitting a form. + * @WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: The navigation was triggered by navigating forward or backward. + * @WEBKIT_NAVIGATION_TYPE_RELOAD: The navigation was triggered by reloading. + * @WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: The navigation was triggered by resubmitting a form. + * @WEBKIT_NAVIGATION_TYPE_OTHER: The navigation was triggered by some other action. + * + * Enum values used to denote the various navigation types. + */ +typedef enum { + WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, + WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, + WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, + WEBKIT_NAVIGATION_TYPE_RELOAD, + WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, + WEBKIT_NAVIGATION_TYPE_OTHER +} WebKitNavigationType; + +typedef struct _WebKitNavigationAction WebKitNavigationAction; + + +WEBKIT_API GType +webkit_navigation_action_get_type (void); + +WEBKIT_API WebKitNavigationAction * +webkit_navigation_action_copy (WebKitNavigationAction *navigation); + +WEBKIT_API void +webkit_navigation_action_free (WebKitNavigationAction *navigation); + +WEBKIT_API WebKitNavigationType +webkit_navigation_action_get_navigation_type (WebKitNavigationAction *navigation); + +WEBKIT_API guint +webkit_navigation_action_get_mouse_button (WebKitNavigationAction *navigation); + +WEBKIT_API guint +webkit_navigation_action_get_modifiers (WebKitNavigationAction *navigation); + +WEBKIT_API WebKitURIRequest * +webkit_navigation_action_get_request (WebKitNavigationAction *navigation); + +WEBKIT_API gboolean +webkit_navigation_action_is_user_gesture (WebKitNavigationAction *navigation); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h new file mode 100644 index 000000000..f426404cb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationActionPrivate.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNavigationActionPrivate_h +#define WebKitNavigationActionPrivate_h + +#include "NavigationActionData.h" +#include "WebKitNavigationAction.h" +#include "WebKitPrivate.h" + +struct _WebKitNavigationAction { + _WebKitNavigationAction(WebKitURIRequest* uriRequest, const WebKit::NavigationActionData& navigationActionData) + : type(toWebKitNavigationType(navigationActionData.navigationType)) + , mouseButton(toWebKitMouseButton(navigationActionData.mouseButton)) + , modifiers(toGdkModifiers(navigationActionData.modifiers)) + , isUserGesture(navigationActionData.userGestureTokenIdentifier) + , request(uriRequest) + { + } + + _WebKitNavigationAction(WebKitNavigationAction* navigation) + : type(navigation->type) + , mouseButton(navigation->mouseButton) + , modifiers(navigation->modifiers) + , isUserGesture(navigation->isUserGesture) + , request(navigation->request) + { + } + + WebKitNavigationType type; + unsigned mouseButton; + unsigned modifiers; + bool isUserGesture : 1; + GRefPtr<WebKitURIRequest> request; +}; + +WebKitNavigationAction* webkitNavigationActionCreate(WebKitURIRequest*, const WebKit::NavigationActionData&); + +#endif // WebKitNavigationActionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp index f03446bab..e5769723c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp @@ -20,13 +20,13 @@ #include "config.h" #include "WebKitNavigationPolicyDecision.h" -#include "APIURLRequest.h" -#include "WebEvent.h" #include "WebKitEnumTypes.h" +#include "WebKitNavigationActionPrivate.h" +#include "WebKitNavigationPolicyDecisionPrivate.h" #include "WebKitPolicyDecisionPrivate.h" #include "WebKitURIRequestPrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -44,10 +44,12 @@ using namespace WebCore; */ struct _WebKitNavigationPolicyDecisionPrivate { - WebKitNavigationType navigationType; - unsigned modifiers; - unsigned mouseButton; - GRefPtr<WebKitURIRequest> request; + ~_WebKitNavigationPolicyDecisionPrivate() + { + webkit_navigation_action_free(navigationAction); + } + + WebKitNavigationAction* navigationAction; CString frameName; }; @@ -55,6 +57,7 @@ WEBKIT_DEFINE_TYPE(WebKitNavigationPolicyDecision, webkit_navigation_policy_deci enum { PROP_0, + PROP_NAVIGATION_ACTION, PROP_NAVIGATION_TYPE, PROP_MOUSE_BUTTON, PROP_MODIFIERS, @@ -66,17 +69,20 @@ static void webkitNavigationPolicyDecisionGetProperty(GObject* object, guint pro { WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(object); switch (propId) { + case PROP_NAVIGATION_ACTION: + g_value_set_boxed(value, webkit_navigation_policy_decision_get_navigation_action(decision)); + break; case PROP_NAVIGATION_TYPE: - g_value_set_enum(value, webkit_navigation_policy_decision_get_navigation_type(decision)); + g_value_set_enum(value, webkit_navigation_action_get_navigation_type(decision->priv->navigationAction)); break; case PROP_MOUSE_BUTTON: - g_value_set_enum(value, webkit_navigation_policy_decision_get_mouse_button(decision)); + g_value_set_enum(value, webkit_navigation_action_get_mouse_button(decision->priv->navigationAction)); break; case PROP_MODIFIERS: - g_value_set_uint(value, webkit_navigation_policy_decision_get_modifiers(decision)); + g_value_set_uint(value, webkit_navigation_action_get_modifiers(decision->priv->navigationAction)); break; case PROP_REQUEST: - g_value_set_object(value, webkit_navigation_policy_decision_get_request(decision)); + g_value_set_object(value, webkit_navigation_action_get_request(decision->priv->navigationAction)); break; case PROP_FRAME_NAME: g_value_set_string(value, webkit_navigation_policy_decision_get_frame_name(decision)); @@ -93,11 +99,30 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD objectClass->get_property = webkitNavigationPolicyDecisionGetProperty; /** + * WebKitNavigationPolicyDecision:navigation-action: + * + * The #WebKitNavigationAction that triggered this policy decision. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_NAVIGATION_ACTION, + g_param_spec_boxed( + "navigation-action", + _("Navigation action"), + _("The WebKitNavigationAction triggering this decision"), + WEBKIT_TYPE_NAVIGATION_ACTION, + WEBKIT_PARAM_READABLE)); + + /** * WebKitNavigationPolicyDecision:navigation-type: * * The type of navigation that triggered this policy decision. This is * useful for enacting different policies depending on what type of user * action caused the navigation. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_NAVIGATION_TYPE, @@ -116,6 +141,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * of the button triggering that event. The button numbers match those from GDK. * If the navigation was not triggered by a mouse event, the value of this * property will be 0. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_MOUSE_BUTTON, @@ -133,6 +160,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * #GdkModifierType values describing the modifiers used for that click. * If the navigation was not triggered by a mouse event or no modifiers * were active, the value of this property will be zero. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_MODIFIERS, @@ -147,6 +176,8 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * * This property contains the #WebKitURIRequest associated with this * navigation. + * + * Deprecated: 2.6: Use #WebKitNavigationPolicyDecision:navigation-action instead */ g_object_class_install_property(objectClass, PROP_REQUEST, @@ -174,17 +205,35 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD } /** + * webkit_navigation_policy_decision_get_navigation_action: + * @decision: a #WebKitNavigationPolicyDecision + * + * Gets the value of the #WebKitNavigationPolicyDecision:navigation-action property. + * + * Returns: (transfer none): The #WebKitNavigationAction triggering this policy decision. + * + * Since: 2.6 + */ +WebKitNavigationAction* webkit_navigation_policy_decision_get_navigation_action(WebKitNavigationPolicyDecision* decision) +{ + g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr); + return decision->priv->navigationAction; +} + +/** * webkit_navigation_policy_decision_get_navigation_type: * @decision: a #WebKitNavigationPolicyDecision * * Gets the value of the #WebKitNavigationPolicyDecision:navigation-type property. * * Returns: The type of navigation triggering this policy decision. + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), WEBKIT_NAVIGATION_TYPE_OTHER); - return decision->priv->navigationType; + return webkit_navigation_action_get_navigation_type(decision->priv->navigationAction); } /** @@ -194,11 +243,13 @@ WebKitNavigationType webkit_navigation_policy_decision_get_navigation_type(WebKi * Gets the value of the #WebKitNavigationPolicyDecision:mouse-button property. * * Returns: The mouse button used if this decision was triggered by a mouse event or 0 otherwise + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->mouseButton; + return webkit_navigation_action_get_mouse_button(decision->priv->navigationAction); } /** @@ -208,11 +259,13 @@ guint webkit_navigation_policy_decision_get_mouse_button(WebKitNavigationPolicyD * Gets the value of the #WebKitNavigationPolicyDecision:modifiers property. * * Returns: The modifiers active if this decision was triggered by a mouse event + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyDecision* decision) { g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->modifiers; + return webkit_navigation_action_get_modifiers(decision->priv->navigationAction); } /** @@ -222,11 +275,13 @@ unsigned webkit_navigation_policy_decision_get_modifiers(WebKitNavigationPolicyD * Gets the value of the #WebKitNavigationPolicyDecision:request property. * * Returns: (transfer none): The URI request that is associated with this navigation + * + * Deprecated: 2.6: Use webkit_navigation_policy_decision_get_navigation_action() instead. */ WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigationPolicyDecision* decision) { - g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), 0); - return decision->priv->request.get(); + g_return_val_if_fail(WEBKIT_IS_NAVIGATION_POLICY_DECISION(decision), nullptr); + return webkit_navigation_action_get_request(decision->priv->navigationAction); } /** @@ -243,21 +298,19 @@ const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPol return decision->priv->frameName.data(); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, NavigationTypeLinkClicked); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, NavigationTypeFormSubmitted); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, NavigationTypeBackForward); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_RELOAD, NavigationTypeReload); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, NavigationTypeFormResubmitted); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_NAVIGATION_TYPE_OTHER, NavigationTypeOther); +WebKitPolicyDecision* webkitNavigationPolicyDecisionCreate(const NavigationActionData& navigationActionData, const ResourceRequest& request, WebFramePolicyListenerProxy* listener) +{ + WebKitNavigationPolicyDecision* navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, nullptr)); + GRefPtr<WebKitURIRequest> uriRequest = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); + navigationDecision->priv->navigationAction = webkitNavigationActionCreate(uriRequest.get(), navigationActionData); + WebKitPolicyDecision* decision = WEBKIT_POLICY_DECISION(navigationDecision); + webkitPolicyDecisionSetListener(decision, listener); + return decision; +} -WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WebKitNavigationType navigationType, unsigned mouseButton, unsigned modifiers, API::URLRequest* request, const char* frameName, WebFramePolicyListenerProxy* listener) +WebKitPolicyDecision* webkitNewWindowPolicyDecisionCreate(const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, WebFramePolicyListenerProxy* listener) { - WebKitNavigationPolicyDecision* decision = WEBKIT_NAVIGATION_POLICY_DECISION(g_object_new(WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, NULL)); - decision->priv->navigationType = navigationType; - decision->priv->mouseButton = mouseButton; - decision->priv->modifiers = modifiers; - decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request->resourceRequest())); - decision->priv->frameName = frameName; - webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener); + WebKitPolicyDecision* decision = webkitNavigationPolicyDecisionCreate(navigationActionData, request, listener); + WEBKIT_NAVIGATION_POLICY_DECISION(decision)->priv->frameName = frameName.utf8().data(); return decision; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h index 751397731..0d9fb261a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.h @@ -26,31 +26,12 @@ #include <glib-object.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitNavigationAction.h> #include <webkit2/WebKitPolicyDecision.h> #include <webkit2/WebKitURIRequest.h> G_BEGIN_DECLS -/** - * WebKitNavigationType: - * @WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: The navigation was triggered by clicking a link. - * @WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: The navigation was triggered by submitting a form. - * @WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: The navigation was triggered by navigating forward or backward. - * @WEBKIT_NAVIGATION_TYPE_RELOAD: The navigation was triggered by reloading. - * @WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: The navigation was triggered by resubmitting a form. - * @WEBKIT_NAVIGATION_TYPE_OTHER: The navigation was triggered by some other action. - * - * Enum values used to denote the various navigation types. - */ -typedef enum { - WEBKIT_NAVIGATION_TYPE_LINK_CLICKED, - WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED, - WEBKIT_NAVIGATION_TYPE_BACK_FORWARD, - WEBKIT_NAVIGATION_TYPE_RELOAD, - WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED, - WEBKIT_NAVIGATION_TYPE_OTHER, -} WebKitNavigationType; - #define WEBKIT_TYPE_NAVIGATION_POLICY_DECISION (webkit_navigation_policy_decision_get_type()) #define WEBKIT_NAVIGATION_POLICY_DECISION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecision)) #define WEBKIT_NAVIGATION_POLICY_DECISION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NAVIGATION_POLICY_DECISION, WebKitNavigationPolicyDecisionClass)) @@ -81,16 +62,24 @@ struct _WebKitNavigationPolicyDecisionClass { WEBKIT_API GType webkit_navigation_policy_decision_get_type (void); -WEBKIT_API WebKitNavigationType -webkit_navigation_policy_decision_get_navigation_type (WebKitNavigationPolicyDecision *decision); -WEBKIT_API guint -webkit_navigation_policy_decision_get_mouse_button (WebKitNavigationPolicyDecision *decision); -WEBKIT_API guint -webkit_navigation_policy_decision_get_modifiers (WebKitNavigationPolicyDecision *decision); -WEBKIT_API WebKitURIRequest * -webkit_navigation_policy_decision_get_request (WebKitNavigationPolicyDecision *decision); +WEBKIT_API WebKitNavigationAction * +webkit_navigation_policy_decision_get_navigation_action (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) WebKitNavigationType +webkit_navigation_policy_decision_get_navigation_type (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) guint +webkit_navigation_policy_decision_get_mouse_button (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) guint +webkit_navigation_policy_decision_get_modifiers (WebKitNavigationPolicyDecision *decision); + +WEBKIT_DEPRECATED_FOR(webkit_navigation_policy_decision_get_navigation_action) WebKitURIRequest * +webkit_navigation_policy_decision_get_request (WebKitNavigationPolicyDecision *decision); + WEBKIT_API const gchar * -webkit_navigation_policy_decision_get_frame_name (WebKitNavigationPolicyDecision *decision); +webkit_navigation_policy_decision_get_frame_name (WebKitNavigationPolicyDecision *decision); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h index 84ee827cd..9d94ee00e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecisionPrivate.h @@ -20,9 +20,11 @@ #ifndef WebKitNavigationPolicyDecisionPrivate_h #define WebKitNavigationPolicyDecisionPrivate_h +#include "NavigationActionData.h" #include "WebKitNavigationPolicyDecision.h" #include "WebKitPrivate.h" -WebKitNavigationPolicyDecision* webkitNavigationPolicyDecisionCreate(WebKitNavigationType, unsigned mouseButton, unsigned modifiers, API::URLRequest*, const char* frameName, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitNavigationPolicyDecisionCreate(const WebKit::NavigationActionData&, const WebCore::ResourceRequest&, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitNewWindowPolicyDecisionCreate(const WebKit::NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, WebKit::WebFramePolicyListenerProxy*); #endif // WebKitNavigationPolicyDecisionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp new file mode 100644 index 000000000..11cba3357 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNetworkProxySettings.h" + +#include "WebKitNetworkProxySettingsPrivate.h" +#include <WebCore/SoupNetworkProxySettings.h> +#include <wtf/text/WTFString.h> + +using namespace WebKit; +using namespace WebCore; + +/** + * SECTION: WebKitNetworkProxySettings + * @Short_description: Network Proxy Settings + * @Title: WebKitNetworkProxySettings + * @See_also: #WebKitWebContext + * + * WebKitNetworkProxySettings can be used to provide a custom proxy configuration + * to a #WebKitWebContext. You need to call webkit_web_context_set_network_proxy_settings() + * with %WEBKIT_NETWORK_PROXY_MODE_CUSTOM and a WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +struct _WebKitNetworkProxySettings { + _WebKitNetworkProxySettings() + : settings(SoupNetworkProxySettings::Mode::Custom) + { + } + + explicit _WebKitNetworkProxySettings(const SoupNetworkProxySettings& otherSettings) + : settings(otherSettings) + { + } + + SoupNetworkProxySettings settings; +}; + +G_DEFINE_BOXED_TYPE(WebKitNetworkProxySettings, webkit_network_proxy_settings, webkit_network_proxy_settings_copy, webkit_network_proxy_settings_free) + +const SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings* proxySettings) +{ + ASSERT(proxySettings); + return proxySettings->settings; +} + +/** + * webkit_network_proxy_settings_new: + * @default_proxy_uri: (allow-none): the default proxy URI to use, or %NULL. + * @ignore_hosts: (allow-none): an optional list of hosts/IP addresses to not use a proxy for. + * + * Create a new #WebKitNetworkProxySettings with the given @default_proxy_uri and @ignore_hosts. + * + * The default proxy URI will be used for any URI that doesn't match @ignore_hosts, and doesn't match any + * of the schemes added with webkit_network_proxy_settings_add_proxy_for_scheme(). + * If @default_proxy_uri starts with "socks://", it will be treated as referring to all three of the + * socks5, socks4a, and socks4 proxy types. + * + * @ignore_hosts is a list of hostnames and IP addresses that the resolver should allow direct connections to. + * Entries can be in one of 4 formats: + * <itemizedlist> + * <listitem><para> + * A hostname, such as "example.com", ".example.com", or "*.example.com", any of which match "example.com" or + * any subdomain of it. + * </para></listitem> + * <listitem><para> + * An IPv4 or IPv6 address, such as "192.168.1.1", which matches only that address. + * </para></listitem> + * <listitem><para> + * A hostname or IP address followed by a port, such as "example.com:80", which matches whatever the hostname or IP + * address would match, but only for URLs with the (explicitly) indicated port. In the case of an IPv6 address, the address + * part must appear in brackets: "[::1]:443" + * </para></listitem> + * <listitem><para> + * An IP address range, given by a base address and prefix length, such as "fe80::/10", which matches any address in that range. + * </para></listitem> + * </itemizedlist> + * + * Note that when dealing with Unicode hostnames, the matching is done against the ASCII form of the name. + * Also note that hostname exclusions apply only to connections made to hosts identified by name, and IP address exclusions apply only + * to connections made to hosts identified by address. That is, if example.com has an address of 192.168.1.1, and @ignore_hosts + * contains only "192.168.1.1", then a connection to "example.com" will use the proxy, and a connection to 192.168.1.1" will not. + * + * Returns: (transfer full): A new #WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +WebKitNetworkProxySettings* webkit_network_proxy_settings_new(const char* defaultProxyURI, const char* const* ignoreHosts) +{ + WebKitNetworkProxySettings* proxySettings = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings))); + new (proxySettings) WebKitNetworkProxySettings; + if (defaultProxyURI) + proxySettings->settings.defaultProxyURL = defaultProxyURI; + if (ignoreHosts) + proxySettings->settings.ignoreHosts.reset(g_strdupv(const_cast<char**>(ignoreHosts))); + return proxySettings; +} + +/** + * webkit_network_proxy_settings_copy: + * @proxy_settings: a #WebKitNetworkProxySettings + * + * Make a copy of the #WebKitNetworkProxySettings. + * + * Returns: (transfer full): A copy of passed in #WebKitNetworkProxySettings + * + * Since: 2.16 + */ +WebKitNetworkProxySettings* webkit_network_proxy_settings_copy(WebKitNetworkProxySettings* proxySettings) +{ + g_return_val_if_fail(proxySettings, nullptr); + + WebKitNetworkProxySettings* copy = static_cast<WebKitNetworkProxySettings*>(fastMalloc(sizeof(WebKitNetworkProxySettings))); + new (copy) WebKitNetworkProxySettings(webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings)); + return copy; +} + +/** + * webkit_network_proxy_settings_free: + * @proxy_settings: A #WebKitNetworkProxySettings + * + * Free the #WebKitNetworkProxySettings. + * + * Since: 2.16 + */ +void webkit_network_proxy_settings_free(WebKitNetworkProxySettings* proxySettings) +{ + g_return_if_fail(proxySettings); + + proxySettings->~WebKitNetworkProxySettings(); + fastFree(proxySettings); +} + +/** + * webkit_network_proxy_settings_add_proxy_for_scheme: + * @proxy_settings: a #WebKitNetworkProxySettings + * @scheme: the URI scheme to add a proxy for + * @proxy_uri: the proxy URI to use for @uri_scheme + * + * Adds a URI-scheme-specific proxy. URIs whose scheme matches @uri_scheme will be proxied via @proxy_uri. + * As with the default proxy URI, if @proxy_uri starts with "socks://", it will be treated as referring to + * all three of the socks5, socks4a, and socks4 proxy types. + * + * Since: 2.16 + */ +void webkit_network_proxy_settings_add_proxy_for_scheme(WebKitNetworkProxySettings* proxySettings, const char* scheme, const char* proxyURI) +{ + g_return_if_fail(proxySettings); + g_return_if_fail(scheme); + g_return_if_fail(proxyURI); + + proxySettings->settings.proxyMap.add(scheme, proxyURI); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h new file mode 100644 index 000000000..00c2b39f3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettings.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNetworkProxySettings_h +#define WebKitNetworkProxySettings_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS (webkit_network_proxy_settings_get_type()) + +typedef struct _WebKitNetworkProxySettings WebKitNetworkProxySettings; + +WEBKIT_API GType +webkit_network_proxy_settings_get_type (void); + +WEBKIT_API WebKitNetworkProxySettings * +webkit_network_proxy_settings_new (const gchar *default_proxy_uri, + const gchar* const *ignore_hosts); + +WEBKIT_API WebKitNetworkProxySettings * +webkit_network_proxy_settings_copy (WebKitNetworkProxySettings *proxy_settings); + +WEBKIT_API void +webkit_network_proxy_settings_free (WebKitNetworkProxySettings *proxy_settings); + +WEBKIT_API void +webkit_network_proxy_settings_add_proxy_for_scheme (WebKitNetworkProxySettings *proxy_settings, + const gchar *scheme, + const gchar *proxy_uri); + +G_END_DECLS + +#endif /* WebKitNetworkProxySettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h new file mode 100644 index 000000000..9691226f2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNetworkProxySettingsPrivate.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitNetworkProxySettings.h" +#include "WebKitPrivate.h" +#include <WebCore/SoupNetworkProxySettings.h> + +const WebCore::SoupNetworkProxySettings& webkitNetworkProxySettingsGetNetworkProxySettings(WebKitNetworkProxySettings*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp new file mode 100644 index 000000000..3d1c4949c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.cpp @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNotification.h" + +#include "WebKitNotificationPrivate.h" +#include "WebKitPrivate.h" +#include "WebNotification.h" +#include <glib/gi18n-lib.h> +#include <wtf/text/CString.h> + +/** + * SECTION: WebKitNotification + * @Short_description: Object used to hold information about a notification that should be shown to the user. + * @Title: WebKitNotification + * + * Since: 2.8 + */ + +enum { + PROP_0, + + PROP_ID, + PROP_TITLE, + PROP_BODY, + PROP_TAG +}; + +enum { + CLOSED, + CLICKED, + + LAST_SIGNAL +}; + +struct _WebKitNotificationPrivate { + CString title; + CString body; + CString tag; + guint64 id; + + WebKitWebView* webView; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitNotification, webkit_notification, G_TYPE_OBJECT) + +static void webkitNotificationGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitNotification* notification = WEBKIT_NOTIFICATION(object); + + switch (propId) { + case PROP_ID: + g_value_set_uint64(value, webkit_notification_get_id(notification)); + break; + case PROP_TITLE: + g_value_set_string(value, webkit_notification_get_title(notification)); + break; + case PROP_BODY: + g_value_set_string(value, webkit_notification_get_body(notification)); + break; + case PROP_TAG: + g_value_set_string(value, webkit_notification_get_tag(notification)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_notification_class_init(WebKitNotificationClass* notificationClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(notificationClass); + objectClass->get_property = webkitNotificationGetProperty; + + /** + * WebKitNotification:id: + * + * The unique id for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_ID, + g_param_spec_uint64("id", + _("ID"), + _("The unique id for the notification"), + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:title: + * + * The title for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_TITLE, + g_param_spec_string("title", + _("Title"), + _("The title for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:body: + * + * The body for the notification. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, + PROP_BODY, + g_param_spec_string("body", + _("Body"), + _("The body for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification:tag: + * + * The tag identifier for the notification. + * + * Since: 2.16 + */ + g_object_class_install_property(objectClass, + PROP_TAG, + g_param_spec_string("tag", + _("Tag"), + _("The tag identifier for the notification"), + nullptr, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitNotification::closed: + * @notification: the #WebKitNotification on which the signal is emitted + * + * Emitted when a notification has been withdrawn. + * + * The default handler will close the notification using libnotify, if built with + * support for it. + * + * Since: 2.8 + */ + signals[CLOSED] = + g_signal_new( + "closed", + G_TYPE_FROM_CLASS(notificationClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitNotification::clicked: + * @notification: the #WebKitNotification on which the signal is emitted + * + * Emitted when a notification has been clicked. See webkit_notification_clicked(). + * + * Since: 2.12 + */ + signals[CLICKED] = + g_signal_new( + "clicked", + G_TYPE_FROM_CLASS(notificationClass), + G_SIGNAL_RUN_LAST, + 0, 0, + nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +WebKitNotification* webkitNotificationCreate(WebKitWebView* webView, const WebKit::WebNotification& webNotification) +{ + WebKitNotification* notification = WEBKIT_NOTIFICATION(g_object_new(WEBKIT_TYPE_NOTIFICATION, nullptr)); + notification->priv->id = webNotification.notificationID(); + notification->priv->title = webNotification.title().utf8(); + notification->priv->body = webNotification.body().utf8(); + notification->priv->tag = webNotification.tag().utf8(); + notification->priv->webView = webView; + return notification; +} + +WebKitWebView* webkitNotificationGetWebView(WebKitNotification* notification) +{ + return notification->priv->webView; +} + +/** + * webkit_notification_get_id: + * @notification: a #WebKitNotification + * + * Obtains the unique id for the notification. + * + * Returns: the unique id for the notification + * + * Since: 2.8 + */ +guint64 webkit_notification_get_id(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), 0); + + return notification->priv->id; +} + +/** + * webkit_notification_get_title: + * @notification: a #WebKitNotification + * + * Obtains the title for the notification. + * + * Returns: the title for the notification + * + * Since: 2.8 + */ +const gchar* webkit_notification_get_title(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + return notification->priv->title.data(); +} + +/** + * webkit_notification_get_body: + * @notification: a #WebKitNotification + * + * Obtains the body for the notification. + * + * Returns: the body for the notification + * + * Since: 2.8 + */ +const gchar* webkit_notification_get_body(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + return notification->priv->body.data(); +} + +/** + * webkit_notification_get_tag: + * @notification: a #WebKitNotification + * + * Obtains the tag identifier for the notification. + * + * Returns: (allow-none): the tag for the notification + * + * Since: 2.16 + */ +const gchar* webkit_notification_get_tag(WebKitNotification* notification) +{ + g_return_val_if_fail(WEBKIT_IS_NOTIFICATION(notification), nullptr); + + const gchar* tag = notification->priv->tag.data(); + return notification->priv->tag.length() ? tag : nullptr; +} + +/** + * webkit_notification_close: + * @notification: a #WebKitNotification + * + * Closes the notification. + * + * Since: 2.8 + */ +void webkit_notification_close(WebKitNotification* notification) +{ + g_return_if_fail(WEBKIT_IS_NOTIFICATION(notification)); + + g_signal_emit(notification, signals[CLOSED], 0); +} + +/** + * webkit_notification_clicked: + * @notification: a #WebKitNotification + * + * Tells WebKit the notification has been clicked. This will emit the + * #WebKitNotification::clicked signal. + * + * Since: 2.12 + */ +void webkit_notification_clicked(WebKitNotification* notification) +{ + g_return_if_fail(WEBKIT_IS_NOTIFICATION(notification)); + + g_signal_emit(notification, signals[CLICKED], 0); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h new file mode 100644 index 000000000..1fd9ac646 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotification.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNotification_h +#define WebKitNotification_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitForwardDeclarations.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NOTIFICATION (webkit_notification_get_type()) +#define WEBKIT_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NOTIFICATION, WebKitNotification)) +#define WEBKIT_IS_NOTIFICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_NOTIFICATION)) +#define WEBKIT_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NOTIFICATION, WebKitNotificationClass)) +#define WEBKIT_IS_NOTIFICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_NOTIFICATION)) +#define WEBKIT_NOTIFICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_NOTIFICATION, WebKitNotificationClass)) + +typedef struct _WebKitNotification WebKitNotification; +typedef struct _WebKitNotificationClass WebKitNotificationClass; +typedef struct _WebKitNotificationPrivate WebKitNotificationPrivate; + +struct _WebKitNotification { + GObject parent; + + WebKitNotificationPrivate *priv; +}; + +struct _WebKitNotificationClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); + void (*_webkit_reserved4) (void); + void (*_webkit_reserved5) (void); +}; + +WEBKIT_API GType +webkit_notification_get_type (void); + +WEBKIT_API guint64 +webkit_notification_get_id (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_title (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_body (WebKitNotification *notification); + +WEBKIT_API const gchar * +webkit_notification_get_tag (WebKitNotification *notification); + +WEBKIT_API void +webkit_notification_close (WebKitNotification *notification); + +WEBKIT_API void +webkit_notification_clicked (WebKitNotification *notification); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp new file mode 100644 index 000000000..2df447455 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitNotificationPermissionRequest.h" + +#include "NotificationPermissionRequest.h" +#include "WebKitNotificationPermissionRequestPrivate.h" +#include "WebKitPermissionRequest.h" + +using namespace WebKit; + +/** + * SECTION: WebKitNotificationPermissionRequest + * @Short_description: A permission request for displaying web notifications + * @Title: WebKitNotificationPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitNotificationPermissionRequest represents a request for + * permission to decide whether WebKit should provide the user with + * notifications through the Web Notification API. + * + * When a WebKitNotificationPermissionRequest is not handled by the user, + * it is denied by default. + * + * Since: 2.8 + */ + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitNotificationPermissionRequestPrivate { + RefPtr<NotificationPermissionRequest> request; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitNotificationPermissionRequest, webkit_notification_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +static void webkitNotificationPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)); + + WebKitNotificationPermissionRequestPrivate* priv = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->request->allow(); + priv->madeDecision = true; +} + +static void webkitNotificationPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)); + + WebKitNotificationPermissionRequestPrivate* priv = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->request->deny(); + priv->madeDecision = true; +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitNotificationPermissionRequestAllow; + iface->deny = webkitNotificationPermissionRequestDeny; +} + +static void webkitNotificationPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is denying the request. + webkitNotificationPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_notification_permission_request_parent_class)->dispose(object); +} + +static void webkit_notification_permission_request_class_init(WebKitNotificationPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitNotificationPermissionRequestDispose; +} + +WebKitNotificationPermissionRequest* webkitNotificationPermissionRequestCreate(NotificationPermissionRequest* request) +{ + WebKitNotificationPermissionRequest* notificationPermissionRequest = WEBKIT_NOTIFICATION_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, nullptr)); + notificationPermissionRequest->priv->request = request; + return notificationPermissionRequest; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h new file mode 100644 index 000000000..d2fb41104 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequest.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitNotificationPermissionRequest_h +#define WebKitNotificationPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST (webkit_notification_permission_request_get_type()) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequest)) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequestClass)) +#define WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST)) +#define WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST)) +#define WEBKIT_NOTIFICATION_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST, WebKitNotificationPermissionRequestClass)) + +typedef struct _WebKitNotificationPermissionRequest WebKitNotificationPermissionRequest; +typedef struct _WebKitNotificationPermissionRequestClass WebKitNotificationPermissionRequestClass; +typedef struct _WebKitNotificationPermissionRequestPrivate WebKitNotificationPermissionRequestPrivate; + +struct _WebKitNotificationPermissionRequest { + GObject parent; + + /*< private >*/ + WebKitNotificationPermissionRequestPrivate *priv; +}; + +struct _WebKitNotificationPermissionRequestClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_notification_permission_request_get_type (void); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroupPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequestPrivate.h index 5fd865610..c23707e76 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroupPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPermissionRequestPrivate.h @@ -17,13 +17,12 @@ * Boston, MA 02110-1301, USA. */ -#ifndef WebKitWebViewGroupPrivate_h -#define WebKitWebViewGroupPrivate_h +#ifndef WebKitNotificationPermissionRequestPrivate_h +#define WebKitNotificationPermissionRequestPrivate_h -#include "WebKitWebViewGroup.h" -#include "WebPageGroup.h" +#include "WebKitNotificationPermissionRequest.h" +#include "WebKitPrivate.h" -WebKitWebViewGroup* webkitWebViewGroupCreate(WebKit::WebPageGroup*); -WebKit::WebPageGroup* webkitWebViewGroupGetPageGroup(WebKitWebViewGroup*); +WebKitNotificationPermissionRequest* webkitNotificationPermissionRequestCreate(WebKit::NotificationPermissionRequest*); -#endif // WebKitWebViewGroupPrivate_h +#endif // WebKitNotificationPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h new file mode 100644 index 000000000..49e9a6087 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationPrivate.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNotificationPrivate_h +#define WebKitNotificationPrivate_h + +#include "WebKitNotification.h" +#include "WebKitPrivate.h" +#include "WebNotification.h" +#include <wtf/text/CString.h> + +WebKitNotification* webkitNotificationCreate(WebKitWebView*, const WebKit::WebNotification&); +WebKitWebView* webkitNotificationGetWebView(WebKitNotification*); + +#endif // WebKitNotificationPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp new file mode 100644 index 000000000..b60669adb --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * Copyright (C) 2014 Collabora Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebKitNotificationProvider.h" + +#include "APIArray.h" +#include "APIDictionary.h" +#include "WKNotificationManager.h" +#include "WebKitNotificationPrivate.h" +#include "WebKitWebContextPrivate.h" +#include "WebKitWebViewPrivate.h" +#include "WebNotificationManagerProxy.h" +#include "WebPageProxy.h" +#include <wtf/text/CString.h> + +using namespace WebKit; + +static inline WebKitNotificationProvider* toNotificationProvider(const void* clientInfo) +{ + return static_cast<WebKitNotificationProvider*>(const_cast<void*>(clientInfo)); +} + +static void showCallback(WKPageRef page, WKNotificationRef notification, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->show(toImpl(page), *toImpl(notification)); +} + +static void cancelCallback(WKNotificationRef notification, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->cancel(*toImpl(notification)); +} + +static WKDictionaryRef notificationPermissionsCallback(const void* clientInfo) +{ + return toAPI(toNotificationProvider(clientInfo)->notificationPermissions().leakRef()); +} + +static void clearNotificationsCallback(WKArrayRef notificationIDs, const void* clientInfo) +{ + toNotificationProvider(clientInfo)->clearNotifications(toImpl(notificationIDs)); +} + +WebKitNotificationProvider::~WebKitNotificationProvider() +{ +} + +Ref<WebKitNotificationProvider> WebKitNotificationProvider::create(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext) +{ + return adoptRef(*new WebKitNotificationProvider(notificationManager, webContext)); +} + +WebKitNotificationProvider::WebKitNotificationProvider(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext) + : m_webContext(webContext) + , m_notificationManager(notificationManager) +{ + ASSERT(notificationManager); + + WKNotificationProviderV0 wkNotificationProvider = { + { + 0, // version + this, // clientInfo + }, + showCallback, + cancelCallback, + 0, // didDestroyNotificationCallback, + 0, // addNotificationManagerCallback, + 0, // removeNotificationManagerCallback, + notificationPermissionsCallback, + clearNotificationsCallback, + }; + + WKNotificationManagerSetProvider(toAPI(notificationManager), reinterpret_cast<WKNotificationProviderBase*>(&wkNotificationProvider)); +} + +void WebKitNotificationProvider::notificationCloseCallback(WebKitNotification* notification, WebKitNotificationProvider* provider) +{ + uint64_t notificationID = webkit_notification_get_id(notification); + Vector<RefPtr<API::Object>> arrayIDs; + arrayIDs.append(API::UInt64::create(notificationID)); + provider->m_notificationManager->providerDidCloseNotifications(API::Array::create(WTFMove(arrayIDs)).ptr()); + provider->m_notifications.remove(notificationID); +} + +void WebKitNotificationProvider::notificationClickedCallback(WebKitNotification* notification, WebKitNotificationProvider* provider) +{ + provider->m_notificationManager->providerDidClickNotification(webkit_notification_get_id(notification)); +} + +void WebKitNotificationProvider::withdrawAnyPreviousNotificationMatchingTag(const CString& tag) +{ + if (!tag.length()) + return; + + for (auto& notification : m_notifications.values()) { + if (tag == webkit_notification_get_tag(notification.get())) { + webkit_notification_close(notification.get()); + break; + } + } + +#ifndef NDEBUG + for (auto& notification : m_notifications.values()) + ASSERT(tag != webkit_notification_get_tag(notification.get())); +#endif +} + +void WebKitNotificationProvider::show(WebPageProxy* page, const WebNotification& webNotification) +{ + GRefPtr<WebKitNotification> notification = m_notifications.get(webNotification.notificationID()); + + if (!notification) { + withdrawAnyPreviousNotificationMatchingTag(webNotification.tag().utf8()); + notification = adoptGRef(webkitNotificationCreate(WEBKIT_WEB_VIEW(page->viewWidget()), webNotification)); + g_signal_connect(notification.get(), "closed", G_CALLBACK(notificationCloseCallback), this); + g_signal_connect(notification.get(), "clicked", G_CALLBACK(notificationClickedCallback), this); + m_notifications.set(webNotification.notificationID(), notification); + } + + if (webkitWebViewEmitShowNotification(WEBKIT_WEB_VIEW(page->viewWidget()), notification.get())) + m_notificationManager->providerDidShowNotification(webNotification.notificationID()); +} + +void WebKitNotificationProvider::cancelNotificationByID(uint64_t notificationID) +{ + if (GRefPtr<WebKitNotification> notification = m_notifications.get(notificationID)) + webkit_notification_close(notification.get()); +} + +void WebKitNotificationProvider::cancel(const WebNotification& webNotification) +{ + cancelNotificationByID(webNotification.notificationID()); +} + +void WebKitNotificationProvider::clearNotifications(const API::Array* notificationIDs) +{ + for (const auto& item : notificationIDs->elementsOfType<API::UInt64>()) + cancelNotificationByID(item->value()); +} + +RefPtr<API::Dictionary> WebKitNotificationProvider::notificationPermissions() +{ + webkitWebContextInitializeNotificationPermissions(m_webContext); + return m_notificationPermissions; +} + +void WebKitNotificationProvider::setNotificationPermissions(HashMap<String, RefPtr<API::Object>>&& permissionsMap) +{ + m_notificationPermissions = API::Dictionary::create(WTFMove(permissionsMap)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h new file mode 100644 index 000000000..49c9b9aaf --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitNotificationProvider_h +#define WebKitNotificationProvider_h + +#include "WebKitPrivate.h" +#include "WebKitNotification.h" +#include "WebKitWebContext.h" +#include <wtf/HashMap.h> +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> + +namespace API { +class Array; +} + +namespace WebKit { + +class WebKitNotificationProvider : public RefCounted<WebKitNotificationProvider> { +public: + virtual ~WebKitNotificationProvider(); + static Ref<WebKitNotificationProvider> create(WebNotificationManagerProxy*, WebKitWebContext*); + + void show(WebPageProxy*, const WebNotification&); + void cancel(const WebNotification&); + void clearNotifications(const API::Array*); + + RefPtr<API::Dictionary> notificationPermissions(); + void setNotificationPermissions(HashMap<String, RefPtr<API::Object>>&&); + +private: + WebKitNotificationProvider(WebNotificationManagerProxy*, WebKitWebContext*); + + void cancelNotificationByID(uint64_t); + static void notificationCloseCallback(WebKitNotification*, WebKitNotificationProvider*); + static void notificationClickedCallback(WebKitNotification*, WebKitNotificationProvider*); + + void withdrawAnyPreviousNotificationMatchingTag(const CString&); + + WebKitWebContext* m_webContext; + RefPtr<API::Dictionary> m_notificationPermissions; + RefPtr<WebNotificationManagerProxy> m_notificationManager; + HashMap<uint64_t, GRefPtr<WebKitNotification>> m_notifications; +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp index 2bcb89c50..b6dec1d3a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPlugin.cpp @@ -55,7 +55,7 @@ struct _WebKitPluginPrivate { WEBKIT_DEFINE_TYPE(WebKitPlugin, webkit_plugin, G_TYPE_OBJECT) -static void webkit_plugin_class_init(WebKitPluginClass* pluginClass) +static void webkit_plugin_class_init(WebKitPluginClass*) { } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp index 1eb6b1ec6..243f40990 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyClient.cpp @@ -20,65 +20,48 @@ #include "config.h" #include "WebKitPolicyClient.h" +#include "APIPolicyClient.h" #include "WebKitNavigationPolicyDecisionPrivate.h" #include "WebKitResponsePolicyDecisionPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" -#include <wtf/gobject/GRefPtr.h> +#include "WebsitePolicies.h" +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; -static void decidePolicyForNavigationAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKFrameRef originatingFrame, WKURLRequestRef request, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitNavigationPolicyDecision> decision = - adoptGRef(webkitNavigationPolicyDecisionCreate(static_cast<WebKitNavigationType>(navigationType), - wkEventMouseButtonToWebKitMouseButton(mouseButton), - wkEventModifiersToGdkModifiers(modifiers), - toImpl(request), - 0, /* frame name */ - toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, - WEBKIT_POLICY_DECISION(decision.get())); -} +class PolicyClient: public API::PolicyClient { +public: + explicit PolicyClient(WebKitWebView* webView) + : m_webView(webView) + { + } -static void decidePolicyForNewWindowAction(WKPageRef page, WKFrameRef frame, WKFrameNavigationType navigationType, WKEventModifiers modifiers, WKEventMouseButton mouseButton, WKURLRequestRef request, WKStringRef frameName, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitNavigationPolicyDecision> decision = - adoptGRef(webkitNavigationPolicyDecisionCreate(static_cast<WebKitNavigationType>(navigationType), - wkEventMouseButtonToWebKitMouseButton(mouseButton), - wkEventModifiersToGdkModifiers(modifiers), - toImpl(request), - toImpl(frameName)->string().utf8().data(), - toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION, - WEBKIT_POLICY_DECISION(decision.get())); -} +private: + void decidePolicyForNavigationAction(WebPageProxy&, WebFrameProxy*, const NavigationActionData& navigationActionData, WebFrameProxy* /*originatingFrame*/, const WebCore::ResourceRequest& /*originalRequest*/, const WebCore::ResourceRequest& request, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitNavigationPolicyDecisionCreate(navigationActionData, request, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, decision.get()); + } -static void decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef request, bool canShowMIMEType, WKFramePolicyListenerRef listener, WKTypeRef userData, const void* clientInfo) -{ - GRefPtr<WebKitResponsePolicyDecision> decision = - adoptGRef(webkitResponsePolicyDecisionCreate(toImpl(request), toImpl(response), canShowMIMEType, toImpl(listener))); - webkitWebViewMakePolicyDecision(WEBKIT_WEB_VIEW(clientInfo), - WEBKIT_POLICY_DECISION_TYPE_RESPONSE, - WEBKIT_POLICY_DECISION(decision.get())); -} + void decidePolicyForNewWindowAction(WebPageProxy&, WebFrameProxy&, const NavigationActionData& navigationActionData, const WebCore::ResourceRequest& request, const String& frameName, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitNewWindowPolicyDecisionCreate(navigationActionData, request, frameName, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION, decision.get()); + } + + void decidePolicyForResponse(WebPageProxy&, WebFrameProxy&, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& request, bool canShowMIMEType, Ref<WebFramePolicyListenerProxy>&& listener, API::Object* /*userData*/) override + { + GRefPtr<WebKitPolicyDecision> decision = adoptGRef(webkitResponsePolicyDecisionCreate(request, response, canShowMIMEType, listener.ptr())); + webkitWebViewMakePolicyDecision(m_webView, WEBKIT_POLICY_DECISION_TYPE_RESPONSE, decision.get()); + } + + WebKitWebView* m_webView; +}; void attachPolicyClientToView(WebKitWebView* webView) { - WKPagePolicyClientV1 policyClient = { - { - 1, // version - webView, // clientInfo - }, - 0, // decidePolicyForNavigationAction_deprecatedForUseWithV0 - decidePolicyForNewWindowAction, - 0, // decidePolicyForResponse_deprecatedForUseWithV0 - 0, // unableToImplementPolicy - decidePolicyForNavigationAction, - decidePolicyForResponse - }; - WKPageSetPagePolicyClient(toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))), &policyClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setPolicyClient(std::make_unique<PolicyClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp index ee44eaebb..688728901 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPolicyDecision.cpp @@ -22,6 +22,7 @@ #include "WebFramePolicyListenerProxy.h" #include "WebKitPolicyDecisionPrivate.h" +#include "WebsitePolicies.h" using namespace WebKit; @@ -79,7 +80,7 @@ void webkit_policy_decision_use(WebKitPolicyDecision* decision) if (decision->priv->madePolicyDecision) return; - decision->priv->listener->use(); + decision->priv->listener->use({ }); decision->priv->madePolicyDecision = true; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp new file mode 100644 index 000000000..21037e7a2 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitPrintCustomWidget.h" + +#include "WebKitPrintCustomWidgetPrivate.h" +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> +#include <wtf/glib/GRefPtr.h> + +using namespace WebKit; + +/** + * SECTION: WebKitPrintCustomWidget + * @Short_description: Allows to embed a custom widget in print dialog + * @Title: WebKitPrintCustomWidget + * @See_also: #WebKitPrintOperation + * + * A WebKitPrintCustomWidget allows to embed a custom widget in the print + * dialog by connecting to the #WebKitPrintOperation::create-custom-widget + * signal, creating a new WebKitPrintCustomWidget with + * webkit_print_custom_widget_new() and returning it from there. You can later + * use webkit_print_operation_run_dialog() to display the dialog. + * + * Since: 2.16 + */ + +enum { + APPLY, + UPDATE, + + LAST_SIGNAL +}; + +enum { + PROP_0, + + PROP_WIDGET, + PROP_TITLE +}; + +struct _WebKitPrintCustomWidgetPrivate { + CString title; + GRefPtr<GtkWidget> widget; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +WEBKIT_DEFINE_TYPE(WebKitPrintCustomWidget, webkit_print_custom_widget, G_TYPE_OBJECT) + +static void webkitPrintCustomWidgetGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object); + + switch (propId) { + case PROP_WIDGET: + g_value_set_object(value, webkit_print_custom_widget_get_widget(printCustomWidget)); + break; + case PROP_TITLE: + g_value_set_string(value, webkit_print_custom_widget_get_title(printCustomWidget)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitPrintCustomWidgetSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object); + + switch (propId) { + case PROP_WIDGET: + printCustomWidget->priv->widget = GTK_WIDGET(g_value_get_object(value)); + break; + case PROP_TITLE: + printCustomWidget->priv->title = g_value_get_string(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_print_custom_widget_class_init(WebKitPrintCustomWidgetClass* printCustomWidgetClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(printCustomWidgetClass); + objectClass->get_property = webkitPrintCustomWidgetGetProperty; + objectClass->set_property = webkitPrintCustomWidgetSetProperty; + + /** + * WebKitPrintCustomWidget:widget: + * + * The custom #GtkWidget that will be embedded in the dialog. + * + * Since: 2.16 + */ + g_object_class_install_property( + objectClass, + PROP_WIDGET, + g_param_spec_object( + "widget", + _("Widget"), + _("Widget that will be added to the print dialog."), + GTK_TYPE_WIDGET, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitPrintCustomWidget:title: + * + * The title of the custom widget. + * + * Since: 2.16 + */ + g_object_class_install_property( + objectClass, + PROP_TITLE, + g_param_spec_string( + "title", + _("Title"), + _("Title of the widget that will be added to the print dialog."), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitPrintCustomWidget::update: + * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted + * @page_setup: actual page setup + * @print_settings: actual print settings + * + * Emitted after change of selected printer in the dialog. The actual page setup + * and print settings are available and the custom widget can actualize itself + * according to their values. + * + * Since: 2.16 + */ + signals[UPDATE] = + g_signal_new( + "update", + G_TYPE_FROM_CLASS(printCustomWidgetClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, update), + 0, 0, + g_cclosure_marshal_generic, + G_TYPE_NONE, 2, + GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS); + + /** + * WebKitPrintCustomWidget::apply: + * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted + * + * Emitted right before the printing will start. You should read the information + * from the widget and update the content based on it if necessary. The widget + * is not guaranteed to be valid at a later time. + * + * Since: 2.16 + */ + signals[APPLY] = + g_signal_new( + "apply", + G_TYPE_FROM_CLASS(printCustomWidgetClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, apply), + 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/** + * webkit_print_custom_widget_new: + * @widget: a #GtkWidget + * @title: a @widget's title + * + * Create a new #WebKitPrintCustomWidget with given @widget and @title. The @widget + * ownership is taken and it is destroyed together with the dialog even if this + * object could still be alive at that point. You typically want to pass a container + * widget with multiple widgets in it. + * + * Returns: (transfer full): a new #WebKitPrintOperation. + * + * Since: 2.16 + */ +WebKitPrintCustomWidget* webkit_print_custom_widget_new(GtkWidget* widget, const char* title) +{ + g_return_val_if_fail(GTK_IS_WIDGET(widget), nullptr); + g_return_val_if_fail(title, nullptr); + + return WEBKIT_PRINT_CUSTOM_WIDGET(g_object_new(WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, "widget", widget, "title", title, nullptr)); +} + +/** + * webkit_print_custom_widget_get_widget: + * @print_custom_widget: a #WebKitPrintCustomWidget + * + * Return the value of #WebKitPrintCustomWidget:widget property for the given + * @print_custom_widget object. The returned value will always be valid if called + * from #WebKitPrintCustomWidget::apply or #WebKitPrintCustomWidget::update + * callbacks, but it will be %NULL if called after the + * #WebKitPrintCustomWidget::apply signal is emitted. + * + * Returns: (transfer none): a #GtkWidget. + * + * Since: 2.16 + */ +GtkWidget* webkit_print_custom_widget_get_widget(WebKitPrintCustomWidget* printCustomWidget) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr); + + return printCustomWidget->priv->widget.get(); +} + +/** + * webkit_print_custom_widget_get_title: + * @print_custom_widget: a #WebKitPrintCustomWidget + * + * Return the value of #WebKitPrintCustomWidget:title property for the given + * @print_custom_widget object. + * + * Returns: Title of the @print_custom_widget. + * + * Since: 2.16 + */ +const gchar* webkit_print_custom_widget_get_title(WebKitPrintCustomWidget* printCustomWidget) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr); + + return printCustomWidget->priv->title.data(); +} + +void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget* printCustomWidget) +{ + g_signal_emit(printCustomWidget, signals[APPLY], 0); + printCustomWidget->priv->widget = nullptr; +} + +void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget *printCustomWidget, GtkPageSetup *pageSetup, GtkPrintSettings *printSettings) +{ + g_signal_emit(printCustomWidget, signals[UPDATE], 0, pageSetup, printSettings); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h new file mode 100644 index 000000000..e6cc84a0c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitPrintCustomWidget_h +#define WebKitPrintCustomWidget_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_PRINT_CUSTOM_WIDGET (webkit_print_custom_widget_get_type()) +#define WEBKIT_PRINT_CUSTOM_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidget)) +#define WEBKIT_IS_PRINT_CUSTOM_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET)) +#define WEBKIT_PRINT_CUSTOM_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass)) +#define WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET)) +#define WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass)) + +typedef struct _WebKitPrintCustomWidget WebKitPrintCustomWidget; +typedef struct _WebKitPrintCustomWidgetClass WebKitPrintCustomWidgetClass; +typedef struct _WebKitPrintCustomWidgetPrivate WebKitPrintCustomWidgetPrivate; + +struct _WebKitPrintCustomWidget { + GObject parent; + + WebKitPrintCustomWidgetPrivate *priv; +}; + +struct _WebKitPrintCustomWidgetClass { + GObjectClass parent_class; + + void (* apply) (WebKitPrintCustomWidget *print_custom_widget, + GtkWidget *widget); + void (* update) (WebKitPrintCustomWidget *print_custom_widget, + GtkWidget *widget, + GtkPageSetup *page_setup, + GtkPrintSettings *print_settings); + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_print_custom_widget_get_type (void); + +WEBKIT_API WebKitPrintCustomWidget * +webkit_print_custom_widget_new (GtkWidget *widget, + const char *title); + +WEBKIT_API GtkWidget * +webkit_print_custom_widget_get_widget (WebKitPrintCustomWidget *print_custom_widget); + +WEBKIT_API const gchar * +webkit_print_custom_widget_get_title (WebKitPrintCustomWidget *print_custom_widget); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h new file mode 100644 index 000000000..d251d5055 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrintCustomWidget.h" +#include "WebKitPrivate.h" +#include <gtk/gtk.h> + +void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget*); +void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget*, GtkPageSetup*, GtkPrintSettings*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp index 75b435baf..dab8c9d89 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "WebKitPrintOperation.h" +#include "WebKitPrintCustomWidgetPrivate.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" #include "WebKitWebViewBasePrivate.h" @@ -27,11 +28,11 @@ #include <WebCore/GtkUtilities.h> #include <WebCore/NotImplemented.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> -#ifdef HAVE_GTK_UNIX_PRINTING +#if HAVE(GTK_UNIX_PRINTING) #include <gtk/gtkunixprint.h> #endif @@ -60,6 +61,7 @@ enum { enum { FINISHED, FAILED, + CREATE_CUSTOM_WIDGET, LAST_SIGNAL }; @@ -128,6 +130,15 @@ static void webkitPrintOperationSetProperty(GObject* object, guint propId, const } } +static gboolean webkitPrintOperationAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer) +{ + void* object = g_value_get_object(handlerReturn); + if (object) + g_value_set_object(returnValue, object); + + return !object; +} + static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOperationClass) { GObjectClass* gObjectClass = G_OBJECT_CLASS(printOperationClass); @@ -198,16 +209,45 @@ static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOp * The #WebKitPrintOperation::finished signal is emitted after this one. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(gObjectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * WebKitPrintOperation::create-custom-widget: + * @print_operation: the #WebKitPrintOperation on which the signal was emitted + * + * Emitted when displaying the print dialog with webkit_print_operation_run_dialog(). + * The returned #WebKitPrintCustomWidget will be added to the print dialog and + * it will be owned by the @print_operation. However, the object is guaranteed + * to be alive until the #WebKitPrintCustomWidget::apply is emitted. + * + * Returns: (transfer full): A #WebKitPrintCustomWidget that will be embedded in the dialog. + * + * Since: 2.16 + */ + signals[CREATE_CUSTOM_WIDGET] = + g_signal_new( + "create-custom-widget", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, + webkitPrintOperationAccumulatorObjectHandled, 0, + g_cclosure_marshal_generic, + WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, 0); +} + +#if HAVE(GTK_UNIX_PRINTING) +static void notifySelectedPrinterCallback(GtkPrintUnixDialog* dialog, GParamSpec*, WebKitPrintCustomWidget* printCustomWidget) +{ + webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(printCustomWidget, gtk_print_unix_dialog_get_page_setup(dialog), gtk_print_unix_dialog_get_settings(dialog)); } -#ifdef HAVE_GTK_UNIX_PRINTING static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOperation* printOperation, GtkWindow* parent) { GtkPrintUnixDialog* printDialog = GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(0, parent)); @@ -232,11 +272,23 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe gtk_print_unix_dialog_set_embed_page_setup(printDialog, TRUE); + GRefPtr<WebKitPrintCustomWidget> customWidget; + g_signal_emit(printOperation, signals[CREATE_CUSTOM_WIDGET], 0, &customWidget.outPtr()); + if (customWidget) { + const gchar* widgetTitle = webkit_print_custom_widget_get_title(customWidget.get()); + GtkWidget* widget = webkit_print_custom_widget_get_widget(customWidget.get()); + + g_signal_connect(printDialog, "notify::selected-printer", G_CALLBACK(notifySelectedPrinterCallback), customWidget.get()); + gtk_print_unix_dialog_add_custom_tab(printDialog, widget, gtk_label_new(widgetTitle)); + } + WebKitPrintOperationResponse returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL; if (gtk_dialog_run(GTK_DIALOG(printDialog)) == GTK_RESPONSE_OK) { priv->printSettings = adoptGRef(gtk_print_unix_dialog_get_settings(printDialog)); priv->pageSetup = gtk_print_unix_dialog_get_page_setup(printDialog); returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_PRINT; + if (customWidget) + webkitPrintCustomWidgetEmitCustomWidgetApplySignal(customWidget.get()); } gtk_widget_destroy(GTK_WIDGET(printDialog)); @@ -252,30 +304,31 @@ static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOpe } #endif -static void drawPagesForPrintingCompleted(WKErrorRef wkPrintError, WKErrorRef, void* context) +static void drawPagesForPrintingCompleted(API::Error* wkPrintError, WebKitPrintOperation* printOperation) { - GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context)); - // When running synchronously WebPageProxy::printFrame() calls endPrinting(). if (printOperation->priv->printMode == PrintInfo::PrintModeAsync && printOperation->priv->webView) { WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); page->endPrinting(); } - const WebCore::ResourceError& resourceError = wkPrintError ? toImpl(wkPrintError)->platformError() : WebCore::ResourceError(); + const WebCore::ResourceError& resourceError = wkPrintError ? wkPrintError->platformError() : WebCore::ResourceError(); if (!resourceError.isNull()) { GUniquePtr<GError> printError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()), - resourceError.errorCode(), resourceError.localizedDescription().utf8().data())); - g_signal_emit(printOperation.get(), signals[FAILED], 0, printError.get()); + toWebKitError(resourceError.errorCode()), resourceError.localizedDescription().utf8().data())); + g_signal_emit(printOperation, signals[FAILED], 0, printError.get()); } - g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL); + g_signal_emit(printOperation, signals[FINISHED], 0, NULL); } static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOperation, WebFrameProxy* webFrame, GtkPrintSettings* printSettings, GtkPageSetup* pageSetup) { PrintInfo printInfo(printSettings, pageSetup, printOperation->priv->printMode); WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); - page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted)); + g_object_ref(printOperation); + page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create([printOperation](API::Error* printError, CallbackBase::Error) { + drawPagesForPrintingCompleted(printError, adoptGRef(printOperation).get()); + })); } WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp index d34b9c471..2c971c22d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.cpp @@ -20,6 +20,9 @@ #include "config.h" #include "WebKitPrivate.h" +#include "ErrorsGtk.h" +#include "WebEvent.h" +#include "WebKitError.h" #include <gdk/gdk.h> unsigned wkEventModifiersToGdkModifiers(WKEventModifiers wkModifiers) @@ -33,9 +36,64 @@ unsigned wkEventModifiersToGdkModifiers(WKEventModifiers wkModifiers) modifiers |= GDK_MOD1_MASK; if (wkModifiers & kWKEventModifiersMetaKey) modifiers |= GDK_META_MASK; + if (wkModifiers & kWKEventModifiersCapsLockKey) + modifiers |= GDK_LOCK_MASK; return modifiers; } +unsigned toGdkModifiers(WebKit::WebEvent::Modifiers wkModifiers) +{ + unsigned modifiers = 0; + if (wkModifiers & WebKit::WebEvent::Modifiers::ShiftKey) + modifiers |= GDK_SHIFT_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::ControlKey) + modifiers |= GDK_CONTROL_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::AltKey) + modifiers |= GDK_MOD1_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::MetaKey) + modifiers |= GDK_META_MASK; + if (wkModifiers & WebKit::WebEvent::Modifiers::CapsLockKey) + modifiers |= GDK_LOCK_MASK; + return modifiers; +} + +WebKitNavigationType toWebKitNavigationType(WebCore::NavigationType type) +{ + switch (type) { + case WebCore::NavigationType::LinkClicked: + return WEBKIT_NAVIGATION_TYPE_LINK_CLICKED; + case WebCore::NavigationType::FormSubmitted: + return WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED; + case WebCore::NavigationType::BackForward: + return WEBKIT_NAVIGATION_TYPE_BACK_FORWARD; + case WebCore::NavigationType::Reload: + return WEBKIT_NAVIGATION_TYPE_RELOAD; + case WebCore::NavigationType::FormResubmitted: + return WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED; + case WebCore::NavigationType::Other: + return WEBKIT_NAVIGATION_TYPE_OTHER; + default: + ASSERT_NOT_REACHED(); + return WEBKIT_NAVIGATION_TYPE_OTHER; + } +} + +unsigned toWebKitMouseButton(WebKit::WebMouseEvent::Button button) +{ + switch (button) { + case WebKit::WebMouseEvent::Button::NoButton: + return 0; + case WebKit::WebMouseEvent::Button::LeftButton: + return 1; + case WebKit::WebMouseEvent::Button::MiddleButton: + return 2; + case WebKit::WebMouseEvent::Button::RightButton: + return 3; + } + ASSERT_NOT_REACHED(); + return 0; +} + unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton wkButton) { switch (wkButton) { @@ -51,3 +109,109 @@ unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton wkButton) ASSERT_NOT_REACHED(); return 0; } + +unsigned toWebKitError(unsigned webCoreError) +{ + switch (webCoreError) { + case WebCore::NetworkErrorFailed: + return WEBKIT_NETWORK_ERROR_FAILED; + case WebCore::NetworkErrorTransport: + return WEBKIT_NETWORK_ERROR_TRANSPORT; + case WebCore::NetworkErrorUnknownProtocol: + return WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL; + case WebCore::NetworkErrorCancelled: + return WEBKIT_NETWORK_ERROR_CANCELLED; + case WebCore::NetworkErrorFileDoesNotExist: + return WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST; + case WebCore::PolicyErrorFailed: + return WEBKIT_POLICY_ERROR_FAILED; + case WebCore::PolicyErrorCannotShowMimeType: + return WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE; + case WebCore::PolicyErrorCannotShowURL: + return WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI; + case WebCore::PolicyErrorFrameLoadInterruptedByPolicyChange: + return WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE; + case WebCore::PolicyErrorCannotUseRestrictedPort: + return WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT; + case WebCore::PluginErrorFailed: + return WEBKIT_PLUGIN_ERROR_FAILED; + case WebCore::PluginErrorCannotFindPlugin: + return WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN; + case WebCore::PluginErrorCannotLoadPlugin: + return WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN; + case WebCore::PluginErrorJavaUnavailable: + return WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE; + case WebCore::PluginErrorConnectionCancelled: + return WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED; + case WebCore::PluginErrorWillHandleLoad: + return WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD; + case WebCore::DownloadErrorNetwork: + return WEBKIT_DOWNLOAD_ERROR_NETWORK; + case WebCore::DownloadErrorCancelledByUser: + return WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER; + case WebCore::DownloadErrorDestination: + return WEBKIT_DOWNLOAD_ERROR_DESTINATION; + case WebCore::PrintErrorGeneral: + return WEBKIT_PRINT_ERROR_GENERAL; + case WebCore::PrintErrorPrinterNotFound: + return WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND; + case WebCore::PrintErrorInvalidPageRange: + return WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE; + default: + // This may be a user app defined error, which needs to be passed as-is. + return webCoreError; + } +} + +unsigned toWebCoreError(unsigned webKitError) +{ + switch (webKitError) { + case WEBKIT_NETWORK_ERROR_FAILED: + return WebCore::NetworkErrorFailed; + case WEBKIT_NETWORK_ERROR_TRANSPORT: + return WebCore::NetworkErrorTransport; + case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL: + return WebCore::NetworkErrorUnknownProtocol; + case WEBKIT_NETWORK_ERROR_CANCELLED: + return WebCore::NetworkErrorCancelled; + case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST: + return WebCore::NetworkErrorFileDoesNotExist; + case WEBKIT_POLICY_ERROR_FAILED: + return WebCore::PolicyErrorFailed; + case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE: + return WebCore::PolicyErrorCannotShowMimeType; + case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URI: + return WebCore::PolicyErrorCannotShowURL; + case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE: + return WebCore::PolicyErrorFrameLoadInterruptedByPolicyChange; + case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT: + return WebCore::PolicyErrorCannotUseRestrictedPort; + case WEBKIT_PLUGIN_ERROR_FAILED: + return WebCore::PluginErrorFailed; + case WEBKIT_PLUGIN_ERROR_CANNOT_FIND_PLUGIN: + return WebCore::PluginErrorCannotFindPlugin; + case WEBKIT_PLUGIN_ERROR_CANNOT_LOAD_PLUGIN: + return WebCore::PluginErrorCannotLoadPlugin; + case WEBKIT_PLUGIN_ERROR_JAVA_UNAVAILABLE: + return WebCore::PluginErrorJavaUnavailable; + case WEBKIT_PLUGIN_ERROR_CONNECTION_CANCELLED: + return WebCore::PluginErrorConnectionCancelled; + case WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD: + return WebCore::PluginErrorWillHandleLoad; + case WEBKIT_DOWNLOAD_ERROR_NETWORK: + return WebCore::DownloadErrorNetwork; + case WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER: + return WebCore::DownloadErrorCancelledByUser; + case WEBKIT_DOWNLOAD_ERROR_DESTINATION: + return WebCore::DownloadErrorDestination; + case WEBKIT_PRINT_ERROR_GENERAL: + return WebCore::PrintErrorGeneral; + case WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND: + return WebCore::PrintErrorPrinterNotFound; + case WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE: + return WebCore::PrintErrorInvalidPageRange; + default: + // This may be a user app defined error, which needs to be passed as-is. + return webKitError; + } +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h index bd060ed32..d072a5ef2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h @@ -26,22 +26,22 @@ #ifndef WebKitPrivate_h #define WebKitPrivate_h -#include <WebKit2/WKAPICast.h> -#include <WebKit2/WKDownload.h> -#include <WebKit2/WKFindOptions.h> -#include <WebKit2/WKFullScreenClientGtk.h> -#include <WebKit2/WKGeolocationManager.h> -#include <WebKit2/WKGeolocationPermissionRequest.h> -#include <WebKit2/WKGeolocationPosition.h> -#include <WebKit2/WKIconDatabase.h> -#include <WebKit2/WKInspector.h> -#include <WebKit2/WKInspectorClientGtk.h> -#include <WebKit2/WKRetainPtr.h> -#include <WebKit2/WKSerializedScriptValue.h> -#include <WebKit2/WKSoupCustomProtocolRequestManager.h> -#include <WebKit2/WKString.h> -#include <WebKit2/WKTextChecker.h> -#include <WebKit2/WebKit2_C.h> +#include "WebKitNavigationAction.h" +#include <WebKit/WKAPICast.h> +#include <WebKit/WKDownload.h> +#include <WebKit/WKFindOptions.h> +#include <WebKit/WKFullScreenClientGtk.h> +#include <WebKit/WKGeolocationManager.h> +#include <WebKit/WKGeolocationPermissionRequest.h> +#include <WebKit/WKGeolocationPosition.h> +#include <WebKit/WKIconDatabase.h> +#include <WebKit/WKInspector.h> +#include <WebKit/WKInspectorClientGtk.h> +#include <WebKit/WKRetainPtr.h> +#include <WebKit/WKSerializedScriptValue.h> +#include <WebKit/WKString.h> +#include <WebKit/WKUserMediaPermissionRequest.h> +#include <WebKit/WebKit2_C.h> #include <glib.h> #include <wtf/Assertions.h> @@ -49,20 +49,17 @@ #define WEBKIT_PARAM_WRITABLE (static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)) #define WEBKIT_PARAM_READWRITE (static_cast<GParamFlags>(G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)) -#define COMPILE_ASSERT_MATCHING_ENUM(webkitName, webcoreName) \ - COMPILE_ASSERT(int(webkitName) == int(webcoreName), mismatchingEnums) - #define WEBKIT_DEFINE_ASYNC_DATA_STRUCT(structName) \ static structName* create##structName() \ { \ - structName* data = g_slice_new0(structName); \ + structName* data = static_cast<structName*>(fastZeroedMalloc(sizeof(structName))); \ new (data) structName(); \ return data; \ } \ static void destroy##structName(structName* data) \ { \ data->~structName(); \ - g_slice_free(structName, data); \ + fastFree(data); \ } #define WEBKIT_DEFINE_TYPE(TypeName, type_name, TYPE_PARENT) _WEBKIT_DEFINE_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, 0, { }) @@ -118,10 +115,17 @@ GType type_name##_get_type(void) \ unsigned wkEventModifiersToGdkModifiers(WKEventModifiers); unsigned wkEventMouseButtonToWebKitMouseButton(WKEventMouseButton); +unsigned toGdkModifiers(WebKit::WebEvent::Modifiers); +WebKitNavigationType toWebKitNavigationType(WebCore::NavigationType); +unsigned toWebKitMouseButton(WebKit::WebMouseEvent::Button); +unsigned toWebKitError(unsigned webCoreError); +unsigned toWebCoreError(unsigned webKitError); enum SnapshotRegion { SnapshotRegionVisible, SnapshotRegionFullDocument }; +static const char networkCacheSubdirectory[] = "WebKitCache"; + #endif // WebKitPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp deleted file mode 100644 index 72f91ec2e..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitRequestManagerClient.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitRequestManagerClient.h" - -#include "WebKitWebContextPrivate.h" - -using namespace WebKit; - -static void startLoading(WKSoupCustomProtocolRequestManagerRef soupRequestManagerRef, uint64_t customProtocolID, WKURLRequestRef requestRef, const void* clientInfo) -{ - webkitWebContextStartLoadingCustomProtocol(WEBKIT_WEB_CONTEXT(clientInfo), customProtocolID, toImpl(requestRef)); -} - -static void stopLoading(WKSoupCustomProtocolRequestManagerRef, uint64_t customProtocolID, const void* clientInfo) -{ - webkitWebContextStopLoadingCustomProtocol(WEBKIT_WEB_CONTEXT(clientInfo), customProtocolID); -} - -void attachRequestManagerClientToContext(WebKitWebContext* webContext) -{ - WKSoupCustomProtocolRequestManagerClientV0 wkRequestManagerClient = { - { - 0, // version - webContext // clientInfo - }, - startLoading, - stopLoading - }; - WKSoupCustomProtocolRequestManagerSetClient(toAPI(webkitWebContextGetRequestManager(webContext)), &wkRequestManagerClient.base); -} - diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp index b6054b814..69b241f85 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecision.cpp @@ -20,17 +20,16 @@ #include "config.h" #include "WebKitResponsePolicyDecision.h" -#include "APIURLRequest.h" -#include "APIURLResponse.h" #include "WebKitPolicyDecisionPrivate.h" #include "WebKitPrivate.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; +using namespace WebCore; /** * SECTION: WebKitResponsePolicyDecision @@ -155,12 +154,13 @@ gboolean webkit_response_policy_decision_is_mime_type_supported(WebKitResponsePo return decision->priv->canShowMIMEType; } -WebKitResponsePolicyDecision* webkitResponsePolicyDecisionCreate(API::URLRequest* request, API::URLResponse* response, bool canShowMIMEType, WebFramePolicyListenerProxy* listener) +WebKitPolicyDecision* webkitResponsePolicyDecisionCreate(const ResourceRequest& request, const ResourceResponse& response, bool canShowMIMEType, WebFramePolicyListenerProxy* listener) { - WebKitResponsePolicyDecision* decision = WEBKIT_RESPONSE_POLICY_DECISION(g_object_new(WEBKIT_TYPE_RESPONSE_POLICY_DECISION, NULL)); - decision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request->resourceRequest())); - decision->priv->response = adoptGRef(webkitURIResponseCreateForResourceResponse(response->resourceResponse())); - decision->priv->canShowMIMEType = canShowMIMEType; - webkitPolicyDecisionSetListener(WEBKIT_POLICY_DECISION(decision), listener); + WebKitResponsePolicyDecision* responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(g_object_new(WEBKIT_TYPE_RESPONSE_POLICY_DECISION, nullptr)); + responseDecision->priv->request = adoptGRef(webkitURIRequestCreateForResourceRequest(request)); + responseDecision->priv->response = adoptGRef(webkitURIResponseCreateForResourceResponse(response)); + responseDecision->priv->canShowMIMEType = canShowMIMEType; + WebKitPolicyDecision* decision = WEBKIT_POLICY_DECISION(responseDecision); + webkitPolicyDecisionSetListener(decision, listener); return decision; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h index ff83a7df3..2ff91085b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitResponsePolicyDecisionPrivate.h @@ -23,6 +23,6 @@ #include "WebKitPrivate.h" #include "WebKitResponsePolicyDecision.h" -WebKitResponsePolicyDecision* webkitResponsePolicyDecisionCreate(API::URLRequest*, API::URLResponse*, bool canShowMIMEType, WebKit::WebFramePolicyListenerProxy*); +WebKitPolicyDecision* webkitResponsePolicyDecisionCreate(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, bool canShowMIMEType, WebKit::WebFramePolicyListenerProxy*); #endif // WebKitResponsePolicyDecisionPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp index 863665d71..5f9772407 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp @@ -24,7 +24,7 @@ static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) { - WebKitScriptDialog* copy = g_slice_new0(WebKitScriptDialog); + WebKitScriptDialog* copy = static_cast<WebKitScriptDialog*>(fastZeroedMalloc(sizeof(WebKitScriptDialog))); new (copy) WebKitScriptDialog(dialog); return copy; } @@ -32,7 +32,7 @@ static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) static void webkitScriptDialogFree(WebKitScriptDialog* dialog) { dialog->~WebKitScriptDialog(); - g_slice_free(WebKitScriptDialog, dialog); + fastFree(dialog); } G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkitScriptDialogCopy, webkitScriptDialogFree) @@ -72,17 +72,17 @@ const char* webkit_script_dialog_get_message(WebKitScriptDialog* dialog) * @dialog: a #WebKitScriptDialog * @confirmed: whether user confirmed the dialog * - * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM dialogs when + * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM and %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM dialogs when * #WebKitWebView::script-dialog signal is emitted to set whether the user * confirmed the dialog or not. The default implementation of #WebKitWebView::script-dialog - * signal sets %TRUE when the OK button is clicked and %FALSE otherwise. + * signal sets %TRUE when the OK or Stay buttons are clicked and %FALSE otherwise. * It's an error to use this method with a #WebKitScriptDialog that is not of type - * %WEBKIT_SCRIPT_DIALOG_CONFIRM. + * %WEBKIT_SCRIPT_DIALOG_CONFIRM or %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM */ void webkit_script_dialog_confirm_set_confirmed(WebKitScriptDialog* dialog, gboolean confirmed) { g_return_if_fail(dialog); - g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM || dialog->type == WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM); dialog->confirmed = confirmed; } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h index cf88535ad..71095beed 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h @@ -41,13 +41,16 @@ typedef struct _WebKitScriptDialog WebKitScriptDialog; * confirmation to the user. * @WEBKIT_SCRIPT_DIALOG_PROMPT: Prompt script dialog, used to ask * information to the user. + * @WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: Before unload confirm dialog, + * used to ask confirmation to leave the current page to the user. Since 2.12 * * Enum values used for determining the type of #WebKitScriptDialog */ typedef enum { WEBKIT_SCRIPT_DIALOG_ALERT, WEBKIT_SCRIPT_DIALOG_CONFIRM, - WEBKIT_SCRIPT_DIALOG_PROMPT + WEBKIT_SCRIPT_DIALOG_PROMPT, + WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM } WebKitScriptDialogType; WEBKIT_API GType diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp index 9b849a825..7245dd5ee 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityManager.cpp @@ -20,9 +20,9 @@ #include "config.h" #include "WebKitSecurityManager.h" -#include "WebContext.h" #include "WebKitSecurityManagerPrivate.h" #include "WebKitWebContextPrivate.h" +#include "WebProcessPool.h" #include <WebCore/SchemeRegistry.h> using namespace WebKit; @@ -55,7 +55,7 @@ struct _WebKitSecurityManagerPrivate { WEBKIT_DEFINE_TYPE(WebKitSecurityManager, webkit_security_manager, G_TYPE_OBJECT) -static void webkit_security_manager_class_init(WebKitSecurityManagerClass* klass) +static void webkit_security_manager_class_init(WebKitSecurityManagerClass*) { } @@ -69,7 +69,7 @@ WebKitSecurityManager* webkitSecurityManagerCreate(WebKitWebContext* webContext) static void registerSecurityPolicyForURIScheme(WebKitSecurityManager* manager, const char* scheme, SecurityPolicy policy) { String urlScheme = String::fromUTF8(scheme); - WebContext* webContext = webkitWebContextGetContext(manager->priv->webContext); + auto& processPool = webkitWebContextGetProcessPool(manager->priv->webContext); // We keep the WebCore::SchemeRegistry of the UI process in sync with the // web process one, so that we can return the SecurityPolicy for @@ -77,27 +77,27 @@ static void registerSecurityPolicyForURIScheme(WebKitSecurityManager* manager, c switch (policy) { case SecurityPolicyLocal: WebCore::SchemeRegistry::registerURLSchemeAsLocal(urlScheme); - webContext->registerURLSchemeAsLocal(urlScheme); + processPool.registerURLSchemeAsLocal(urlScheme); break; case SecurityPolicyNoAccess: WebCore::SchemeRegistry::registerURLSchemeAsNoAccess(urlScheme); - webContext->registerURLSchemeAsNoAccess(urlScheme); + processPool.registerURLSchemeAsNoAccess(urlScheme); break; case SecurityPolicyDisplayIsolated: WebCore::SchemeRegistry::registerURLSchemeAsDisplayIsolated(urlScheme); - webContext->registerURLSchemeAsDisplayIsolated(urlScheme); + processPool.registerURLSchemeAsDisplayIsolated(urlScheme); break; case SecurityPolicySecure: WebCore::SchemeRegistry::registerURLSchemeAsSecure(urlScheme); - webContext->registerURLSchemeAsSecure(urlScheme); + processPool.registerURLSchemeAsSecure(urlScheme); break; case SecurityPolicyCORSEnabled: WebCore::SchemeRegistry::registerURLSchemeAsCORSEnabled(urlScheme); - webContext->registerURLSchemeAsCORSEnabled(urlScheme); + processPool.registerURLSchemeAsCORSEnabled(urlScheme); break; case SecurityPolicyEmptyDocument: WebCore::SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme); - webContext->registerURLSchemeAsEmptyDocument(urlScheme); + processPool.registerURLSchemeAsEmptyDocument(urlScheme); break; } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp new file mode 100644 index 000000000..0a5ba63e7 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitSecurityOrigin.h" + +#include "WebKitSecurityOriginPrivate.h" +#include <WebCore/URL.h> +#include <wtf/text/CString.h> + +using namespace WebKit; + +/** + * SECTION: WebKitSecurityOrigin + * @Short_description: A security boundary for websites + * @Title: WebKitSecurityOrigin + * + * #WebKitSecurityOrigin is a representation of a security domain + * defined by websites. A security origin normally consists of a + * protocol, a hostname, and a port number. It is also possible for a + * security origin to be opaque, as defined by the HTML standard, in + * which case it has no associated protocol, host, or port. + * + * Websites with the same security origin can access each other's + * resources for client-side scripting or database access. + * + * Since: 2.16 + */ + +struct _WebKitSecurityOrigin { + _WebKitSecurityOrigin(Ref<WebCore::SecurityOrigin>&& coreSecurityOrigin) + : securityOrigin(WTFMove(coreSecurityOrigin)) + { + } + + Ref<WebCore::SecurityOrigin> securityOrigin; + CString protocol; + CString host; + int referenceCount { 1 }; +}; + +G_DEFINE_BOXED_TYPE(WebKitSecurityOrigin, webkit_security_origin, webkit_security_origin_ref, webkit_security_origin_unref) + +WebKitSecurityOrigin* webkitSecurityOriginCreate(Ref<WebCore::SecurityOrigin>&& coreSecurityOrigin) +{ + WebKitSecurityOrigin* origin = static_cast<WebKitSecurityOrigin*>(fastMalloc(sizeof(WebKitSecurityOrigin))); + new (origin) WebKitSecurityOrigin(WTFMove(coreSecurityOrigin)); + return origin; +} + +WebCore::SecurityOrigin& webkitSecurityOriginGetSecurityOrigin(WebKitSecurityOrigin* origin) +{ + ASSERT(origin); + return origin->securityOrigin.get(); +} + +/** + * webkit_security_origin_new: + * @protocol: The protocol for the new origin + * @host: The host for the new origin + * @port: The port number for the new origin, or 0 to indicate the + * default port for @protocol + * + * Create a new security origin from the provided protocol, host and + * port. + * + * Returns: (transfer full): A #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_new(const gchar* protocol, const gchar* host, guint16 port) +{ + g_return_val_if_fail(protocol, nullptr); + g_return_val_if_fail(host, nullptr); + + std::optional<uint16_t> optionalPort; + if (port) + optionalPort = port; + + return webkitSecurityOriginCreate(WebCore::SecurityOrigin::create(String::fromUTF8(protocol), String::fromUTF8(host), optionalPort)); +} + +/** + * webkit_security_origin_new_for_uri: + * @uri: The URI for the new origin + * + * Create a new security origin from the provided URI. Components of + * @uri other than protocol, host, and port do not affect the created + * #WebKitSecurityOrigin. + * + * Returns: (transfer full): A #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_new_for_uri(const gchar* uri) +{ + g_return_val_if_fail(uri, nullptr); + + return webkitSecurityOriginCreate(WebCore::SecurityOrigin::create(WebCore::URL(WebCore::URL(), String::fromUTF8(uri)))); +} + +/** + * webkit_security_origin_ref: + * @origin: a #WebKitSecurityOrigin + * + * Atomically increments the reference count of @origin by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitSecurityOrigin + * + * Since: 2.16 + */ +WebKitSecurityOrigin* webkit_security_origin_ref(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + g_atomic_int_inc(&origin->referenceCount); + return origin; +} + +/** + * webkit_security_origin_unref: + * @origin: A #WebKitSecurityOrigin + * + * Atomically decrements the reference count of @origin by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitSecurityOrigin is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.16 + */ +void webkit_security_origin_unref(WebKitSecurityOrigin* origin) +{ + g_return_if_fail(origin); + + if (g_atomic_int_dec_and_test(&origin->referenceCount)) { + origin->~WebKitSecurityOrigin(); + fastFree(origin); + } +} + +/** + * webkit_security_origin_get_protocol: + * @origin: a #WebKitSecurityOrigin + * + * Gets the protocol of @origin, or %NULL if @origin is opaque. + * + * Returns: (allow-none): The protocol of the #WebKitSecurityOrigin + * + * Since: 2.16 + */ +const gchar* webkit_security_origin_get_protocol(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + if (origin->securityOrigin->protocol().isEmpty()) + return nullptr; + + if (origin->protocol.isNull()) + origin->protocol = origin->securityOrigin->protocol().utf8(); + return origin->protocol.data(); +} + +/** + * webkit_security_origin_get_host: + * @origin: a #WebKitSecurityOrigin + * + * Gets the hostname of @origin, or %NULL if @origin is opaque or if its + * protocol does not require a host component. + * + * Returns: (allow-none): The host of the #WebKitSecurityOrigin + * + * Since: 2.16 + */ +const gchar* webkit_security_origin_get_host(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + if (origin->securityOrigin->host().isEmpty()) + return nullptr; + + if (origin->host.isNull()) + origin->host = origin->securityOrigin->host().utf8(); + return origin->host.data(); +} + +/** + * webkit_security_origin_get_port: + * @origin: a #WebKitSecurityOrigin + * + * Gets the port of @origin. This function will always return 0 if the + * port is the default port for the given protocol. For example, + * http://example.com has the same security origin as + * http://example.com:80, and this function will return 0 for a + * #WebKitSecurityOrigin constructed from either URI. It will also + * return 0 if @origin is opaque. + * + * Returns: The port of the #WebKitSecurityOrigin. + * + * Since: 2.16 + */ +guint16 webkit_security_origin_get_port(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, 0); + + return origin->securityOrigin->port().value_or(0); +} + +/** + * webkit_security_origin_is_opaque: + * @origin: a #WebKitSecurityOrigin + * + * Gets whether @origin is an opaque security origin, which does not + * possess an associated protocol, host, or port. + * + * Returns: %TRUE if @origin is opaque. + * + * Since: 2.16 + */ +gboolean webkit_security_origin_is_opaque(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, TRUE); + + return origin->securityOrigin->isUnique(); +} + +/** + * webkit_security_origin_to_string: + * @origin: a #WebKitSecurityOrigin + * + * Gets a string representation of @origin. The string representation + * is a valid URI with only protocol, host, and port components. It may + * be %NULL, but usually only if @origin is opaque. + * + * Returns: (allow-none) (transfer full): a URI representing @origin. + * + * Since: 2.16 + */ +gchar* webkit_security_origin_to_string(WebKitSecurityOrigin* origin) +{ + g_return_val_if_fail(origin, nullptr); + + CString cstring = origin->securityOrigin->toString().utf8(); + return cstring == "null" ? nullptr : g_strdup (cstring.data()); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h new file mode 100644 index 000000000..6dca2b77e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOrigin.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitSecurityOrigin_h +#define WebKitSecurityOrigin_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SECURITY_ORIGIN (webkit_security_origin_get_type()) + +typedef struct _WebKitSecurityOrigin WebKitSecurityOrigin; + +WEBKIT_API GType +webkit_security_origin_get_type (void); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_new (const gchar *protocol, + const gchar *host, + guint16 port); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_new_for_uri (const gchar *uri); + +WEBKIT_API WebKitSecurityOrigin * +webkit_security_origin_ref (WebKitSecurityOrigin *origin); + +WEBKIT_API void +webkit_security_origin_unref (WebKitSecurityOrigin *origin); + +WEBKIT_API const gchar * +webkit_security_origin_get_protocol (WebKitSecurityOrigin *origin); + +WEBKIT_API const gchar * +webkit_security_origin_get_host (WebKitSecurityOrigin *origin); + +WEBKIT_API guint16 +webkit_security_origin_get_port (WebKitSecurityOrigin *origin); + +WEBKIT_API gboolean +webkit_security_origin_is_opaque (WebKitSecurityOrigin *origin); + +WEBKIT_API gchar * +webkit_security_origin_to_string (WebKitSecurityOrigin *origin); + +G_END_DECLS + +#endif /* WebKitSecurityOrigin_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h new file mode 100644 index 000000000..cf580f967 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSecurityOriginPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrivate.h" +#include "WebKitSecurityOrigin.h" +#include <WebCore/SecurityOrigin.h> + +WebKitSecurityOrigin* webkitSecurityOriginCreate(Ref<WebCore::SecurityOrigin>&&); +WebCore::SecurityOrigin& webkitSecurityOriginGetSecurityOrigin(WebKitSecurityOrigin*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp index 7c49ccd82..83b70edee 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp @@ -31,18 +31,25 @@ #include "config.h" #include "WebKitSettings.h" -#include "ExperimentalFeatures.h" +#include "HardwareAccelerationManager.h" +#include "WebKitEnumTypes.h" #include "WebKitPrivate.h" #include "WebKitSettingsPrivate.h" -#include <WebCore/UserAgentGtk.h> +#include "WebPageProxy.h" +#include "WebPreferences.h" +#include <WebCore/UserAgent.h> #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> +#if PLATFORM(WAYLAND) +#include <WebCore/PlatformDisplay.h> +#endif + using namespace WebKit; struct _WebKitSettingsPrivate { _WebKitSettingsPrivate() - : preferences(WebPreferences::create()) + : preferences(WebPreferences::create(String(), "WebKit2.", "WebKit2.")) { defaultFontFamily = preferences->standardFontFamily().utf8(); monospaceFontFamily = preferences->fixedFontFamily().utf8(); @@ -70,13 +77,12 @@ struct _WebKitSettingsPrivate { /** * SECTION:WebKitSettings - * @short_description: Control the behaviour of #WebKitWebView<!-- -->s - * @see_also: #WebKitWebViewGroup, #WebKitWebView + * @short_description: Control the behaviour of a #WebKitWebView * - * #WebKitSettings can be applied to a #WebKitWebViewGroup to control text charset, + * #WebKitSettings can be applied to a #WebKitWebView to control text charset, * color, font sizes, printing mode, script support, loading of images and various - * other things on the #WebKitWebView<!-- -->s of the group. - * After creation, a #WebKitSettings object contains default settings. + * other things on a #WebKitWebView. After creation, a #WebKitSettings object + * contains default settings. * * <informalexample><programlisting> * /<!-- -->* Disable JavaScript. *<!-- -->/ @@ -138,7 +144,10 @@ enum { PROP_ENABLE_WRITE_CONSOLE_MESSAGES_TO_STDOUT, PROP_ENABLE_MEDIA_STREAM, PROP_ENABLE_SPATIAL_NAVIGATION, - PROP_ENABLE_MEDIASOURCE + PROP_ENABLE_MEDIASOURCE, + PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS, + PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS, + PROP_HARDWARE_ACCELERATION_POLICY, }; static void webKitSettingsConstructed(GObject* object) @@ -146,14 +155,6 @@ static void webKitSettingsConstructed(GObject* object) G_OBJECT_CLASS(webkit_settings_parent_class)->constructed(object); WebPreferences* prefs = WEBKIT_SETTINGS(object)->priv->preferences.get(); - ExperimentalFeatures features; - bool cssGridLayoutEnabled = features.isEnabled(ExperimentalFeatures::CSSGridLayout); - if (prefs->cssGridLayoutEnabled() != cssGridLayoutEnabled) - prefs->setCSSGridLayoutEnabled(cssGridLayoutEnabled); - bool regionBasedColumnsEnabled = features.isEnabled(ExperimentalFeatures::RegionBasedColumns); - if (prefs->regionBasedColumnsEnabled() != regionBasedColumnsEnabled) - prefs->setRegionBasedColumnsEnabled(regionBasedColumnsEnabled); - prefs->setShouldRespectImageOrientation(true); } @@ -232,7 +233,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu webkit_settings_set_default_charset(settings, g_value_get_string(value)); break; case PROP_ENABLE_PRIVATE_BROWSING: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; webkit_settings_set_enable_private_browsing(settings, g_value_get_boolean(value)); + G_GNUC_END_IGNORE_DEPRECATIONS; break; case PROP_ENABLE_DEVELOPER_EXTRAS: webkit_settings_set_enable_developer_extras(settings, g_value_get_boolean(value)); @@ -312,6 +315,15 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu case PROP_ENABLE_MEDIASOURCE: webkit_settings_set_enable_mediasource(settings, g_value_get_boolean(value)); break; + case PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS: + webkit_settings_set_allow_file_access_from_file_urls(settings, g_value_get_boolean(value)); + break; + case PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS: + webkit_settings_set_allow_universal_access_from_file_urls(settings, g_value_get_boolean(value)); + break; + case PROP_HARDWARE_ACCELERATION_POLICY: + webkit_settings_set_hardware_acceleration_policy(settings, static_cast<WebKitHardwareAccelerationPolicy>(g_value_get_enum(value))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -393,7 +405,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val g_value_set_string(value, webkit_settings_get_default_charset(settings)); break; case PROP_ENABLE_PRIVATE_BROWSING: + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; g_value_set_boolean(value, webkit_settings_get_enable_private_browsing(settings)); + G_GNUC_END_IGNORE_DEPRECATIONS; break; case PROP_ENABLE_DEVELOPER_EXTRAS: g_value_set_boolean(value, webkit_settings_get_enable_developer_extras(settings)); @@ -467,7 +481,15 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val case PROP_ENABLE_MEDIASOURCE: g_value_set_boolean(value, webkit_settings_get_enable_mediasource(settings)); break; - + case PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS: + g_value_set_boolean(value, webkit_settings_get_allow_file_access_from_file_urls(settings)); + break; + case PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS: + g_value_set_boolean(value, webkit_settings_get_allow_universal_access_from_file_urls(settings)); + break; + case PROP_HARDWARE_ACCELERATION_POLICY: + g_value_set_enum(value, webkit_settings_get_hardware_acceleration_policy(settings)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -665,7 +687,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-font-family: + * WebKitSettings:default-font-family: * * The font family to use as the default for content that does not specify a font. */ @@ -678,7 +700,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:monospace-font-family: + * WebKitSettings:monospace-font-family: * * The font family used as the default for content using a monospace font. * @@ -692,7 +714,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:serif-font-family: + * WebKitSettings:serif-font-family: * * The font family used as the default for content using a serif font. */ @@ -705,7 +727,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:sans-serif-font-family: + * WebKitSettings:sans-serif-font-family: * * The font family used as the default for content using a sans-serif font. */ @@ -718,7 +740,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:cursive-font-family: + * WebKitSettings:cursive-font-family: * * The font family used as the default for content using a cursive font. */ @@ -731,7 +753,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:fantasy-font-family: + * WebKitSettings:fantasy-font-family: * * The font family used as the default for content using a fantasy font. */ @@ -744,7 +766,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:pictograph-font-family: + * WebKitSettings:pictograph-font-family: * * The font family used as the default for content using a pictograph font. */ @@ -757,7 +779,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-font-size: + * WebKitSettings:default-font-size: * * The default font size in pixels to use for content displayed if * no font size is specified. @@ -771,7 +793,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:default-monospace-font-size: + * WebKitSettings:default-monospace-font-size: * * The default font size in pixels to use for content displayed in * monospace font if no font size is specified. @@ -785,7 +807,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) readWriteConstructParamFlags)); /** - * WebKitWebSettings:minimum-font-size: + * WebKitSettings:minimum-font-size: * * The minimum font size in points used to display text. This setting * controls the absolute smallest size. Values other than 0 can @@ -817,6 +839,8 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) * * Determines whether or not private browsing is enabled. Private browsing * will disable history, cache and form auto-fill for any pages visited. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ g_object_class_install_property(gObjectClass, PROP_ENABLE_PRIVATE_BROWSING, @@ -1191,7 +1215,7 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) * there is an element they might be trying to reach towards the right, and if * there are multiple elements, which element they probably wants. * - * Since: 2.3 + * Since: 2.4 */ g_object_class_install_property(gObjectClass, PROP_ENABLE_SPATIAL_NAVIGATION, @@ -1220,6 +1244,71 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) _("Whether MediaSource should be enabled."), FALSE, readWriteConstructParamFlags)); + + /** + * WebKitSettings:allow-file-access-from-file-urls: + * + * Whether file access is allowed from file URLs. By default, when + * something is loaded in a #WebKitWebView using a file URI, cross + * origin requests to other file resources are not allowed. This + * setting allows you to change that behaviour, so that it would be + * possible to do a XMLHttpRequest of a local file, for example. + * + * Since: 2.10 + */ + g_object_class_install_property(gObjectClass, + PROP_ALLOW_FILE_ACCESS_FROM_FILE_URLS, + g_param_spec_boolean("allow-file-access-from-file-urls", + _("Allow file access from file URLs"), + _("Whether file access is allowed from file URLs."), + FALSE, + readWriteConstructParamFlags)); + + /** + * WebKitSettings:allow-universal-access-from-file-urls: + * + * Whether or not JavaScript running in the context of a file scheme URL + * should be allowed to access content from any origin. By default, when + * something is loaded in a #WebKitWebView using a file scheme URL, + * access to the local file system and arbitrary local storage is not + * allowed. This setting allows you to change that behaviour, so that + * it would be possible to use local storage, for example. + * + * Since: 2.14 + */ + g_object_class_install_property(gObjectClass, + PROP_ALLOW_UNIVERSAL_ACCESS_FROM_FILE_URLS, + g_param_spec_boolean("allow-universal-access-from-file-urls", + _("Allow universal access from the context of file scheme URLs"), + _("Whether or not universal access is allowed from the context of file scheme URLs"), + FALSE, + readWriteConstructParamFlags)); + + /** + * WebKitSettings:hardware-acceleration-policy: + * + * The #WebKitHardwareAccelerationPolicy to decide how to enable and disable + * hardware acceleration. The default value %WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND + * enables the hardware acceleration when the web contents request it, disabling it again + * when no longer needed. It's possible to enfore hardware acceleration to be always enabled + * by using %WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS. And it's also posible to disable it + * completely using %WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER. Note that disabling hardware + * acceleration might cause some websites to not render correctly or consume more CPU. + * + * Note that changing this setting might not be possible if hardware acceleration is not + * supported by the hardware or the system. In that case you can get the value to know the + * actual policy being used, but changing the setting will not have any effect. + * + * Since: 2.16 + */ + g_object_class_install_property(gObjectClass, + PROP_HARDWARE_ACCELERATION_POLICY, + g_param_spec_enum("hardware-acceleration-policy", + _("Hardware Acceleration Policy"), + _("The policy to decide how to enable and disable hardware acceleration"), + WEBKIT_TYPE_HARDWARE_ACCELERATION_POLICY, + WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND, + readWriteConstructParamFlags)); } WebPreferences* webkitSettingsGetPreferences(WebKitSettings* settings) @@ -1231,7 +1320,7 @@ WebPreferences* webkitSettingsGetPreferences(WebKitSettings* settings) * webkit_settings_new: * * Creates a new #WebKitSettings instance with default values. It must - * be manually attached to a #WebKitWebViewGroup. + * be manually attached to a #WebKitWebView. * See also webkit_settings_new_with_settings(). * * Returns: a new #WebKitSettings instance. @@ -1248,7 +1337,7 @@ WebKitSettings* webkit_settings_new() * %NULL-terminated * * Creates a new #WebKitSettings instance with the given settings. It must - * be manually attached to a #WebKitWebViewGroup. + * be manually attached to a #WebKitWebView. * * Returns: a new #WebKitSettings instance. */ @@ -2090,6 +2179,8 @@ void webkit_settings_set_default_charset(WebKitSettings* settings, const gchar* * Get the #WebKitSettings:enable-private-browsing property. * * Returns: %TRUE If private browsing is enabled or %FALSE otherwise. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ gboolean webkit_settings_get_enable_private_browsing(WebKitSettings* settings) { @@ -2099,11 +2190,13 @@ gboolean webkit_settings_get_enable_private_browsing(WebKitSettings* settings) } /** - * webkit_settings_set_private_caret_browsing: + * webkit_settings_set_enable_private_browsing: * @settings: a #WebKitSettings * @enabled: Value to be set * * Set the #WebKitSettings:enable-private-browsing property. + * + * Deprecated: 2.16. Use #WebKitWebView:is-ephemeral or #WebKitWebContext:is-ephemeral instead. */ void webkit_settings_set_enable_private_browsing(WebKitSettings* settings, gboolean enabled) { @@ -2551,7 +2644,7 @@ gboolean webkit_settings_get_media_playback_requires_user_gesture(WebKitSettings { g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); - return settings->priv->preferences->mediaPlaybackRequiresUserGesture(); + return settings->priv->preferences->requiresUserGestureForMediaPlayback(); } /** @@ -2566,11 +2659,11 @@ void webkit_settings_set_media_playback_requires_user_gesture(WebKitSettings* se g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); WebKitSettingsPrivate* priv = settings->priv; - bool currentValue = priv->preferences->mediaPlaybackRequiresUserGesture(); + bool currentValue = priv->preferences->requiresUserGestureForMediaPlayback(); if (currentValue == enabled) return; - priv->preferences->setMediaPlaybackRequiresUserGesture(enabled); + priv->preferences->setRequiresUserGestureForMediaPlayback(enabled); g_object_notify(G_OBJECT(settings), "media-playback-requires-user-gesture"); } @@ -2587,7 +2680,7 @@ gboolean webkit_settings_get_media_playback_allows_inline(WebKitSettings* settin { g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), TRUE); - return settings->priv->preferences->mediaPlaybackAllowsInline(); + return settings->priv->preferences->allowsInlineMediaPlayback(); } /** @@ -2602,11 +2695,11 @@ void webkit_settings_set_media_playback_allows_inline(WebKitSettings* settings, g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); WebKitSettingsPrivate* priv = settings->priv; - bool currentValue = priv->preferences->mediaPlaybackAllowsInline(); + bool currentValue = priv->preferences->allowsInlineMediaPlayback(); if (currentValue == enabled) return; - priv->preferences->setMediaPlaybackAllowsInline(enabled); + priv->preferences->setAllowsInlineMediaPlayback(enabled); g_object_notify(G_OBJECT(settings), "media-playback-allows-inline"); } @@ -2920,6 +3013,7 @@ void webkit_settings_set_enable_media_stream(WebKitSettings* settings, gboolean return; priv->preferences->setMediaStreamEnabled(enabled); + priv->preferences->setPeerConnectionEnabled(enabled); g_object_notify(G_OBJECT(settings), "enable-media-stream"); } @@ -3002,3 +3096,161 @@ void webkit_settings_set_enable_mediasource(WebKitSettings* settings, gboolean e priv->preferences->setMediaSourceEnabled(enabled); g_object_notify(G_OBJECT(settings), "enable-mediasource"); } + +/** + * webkit_settings_get_allow_file_access_from_file_urls: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:allow-file-access-from-file-urls property. + * + * Returns: %TRUE If file access from file URLs is allowed or %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean webkit_settings_get_allow_file_access_from_file_urls(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->preferences->allowFileAccessFromFileURLs(); +} + +/** + * webkit_settings_set_allow_file_access_from_file_urls: + * @settings: a #WebKitSettings + * @allowed: Value to be set + * + * Set the #WebKitSettings:allow-file-access-from-file-urls property. + * + * Since: 2.10 + */ +void webkit_settings_set_allow_file_access_from_file_urls(WebKitSettings* settings, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->preferences->allowFileAccessFromFileURLs() == allowed) + return; + + priv->preferences->setAllowFileAccessFromFileURLs(allowed); + g_object_notify(G_OBJECT(settings), "allow-file-access-from-file-urls"); +} + +/** + * webkit_settings_get_allow_universal_access_from_file_urls: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:allow-universal-access-from-file-urls property. + * + * Returns: %TRUE If universal access from file URLs is allowed or %FALSE otherwise. + * + * Since: 2.14 + */ +gboolean webkit_settings_get_allow_universal_access_from_file_urls(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->preferences->allowUniversalAccessFromFileURLs(); +} + +/** + * webkit_settings_set_allow_universal_access_from_file_urls: + * @settings: a #WebKitSettings + * @allowed: Value to be set + * + * Set the #WebKitSettings:allow-universal-access-from-file-urls property. + * + * Since: 2.14 + */ +void webkit_settings_set_allow_universal_access_from_file_urls(WebKitSettings* settings, gboolean allowed) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->preferences->allowUniversalAccessFromFileURLs() == allowed) + return; + + priv->preferences->setAllowUniversalAccessFromFileURLs(allowed); + g_object_notify(G_OBJECT(settings), "allow-universal-access-from-file-urls"); +} + +/** + * webkit_settings_get_hardware_acceleration_policy: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:hardware-acceleration-policy property. + * + * Return: a #WebKitHardwareAccelerationPolicy + * + * Since: 2.16 + */ +WebKitHardwareAccelerationPolicy webkit_settings_get_hardware_acceleration_policy(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND); + + WebKitSettingsPrivate* priv = settings->priv; + if (!priv->preferences->acceleratedCompositingEnabled()) + return WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER; + + if (priv->preferences->forceCompositingMode()) + return WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS; + + return WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND; +} + +/** + * webkit_settings_set_hardware_acceleration_policy: + * @settings: a #WebKitSettings + * @policy: a #WebKitHardwareAccelerationPolicy + * + * Set the #WebKitSettings:hardware-acceleration-policy property. + * + * Since: 2.16 + */ +void webkit_settings_set_hardware_acceleration_policy(WebKitSettings* settings, WebKitHardwareAccelerationPolicy policy) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + bool changed = false; + switch (policy) { + case WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS: + if (!HardwareAccelerationManager::singleton().canUseHardwareAcceleration()) + return; + if (!priv->preferences->acceleratedCompositingEnabled()) { + priv->preferences->setAcceleratedCompositingEnabled(true); + changed = true; + } + if (!priv->preferences->forceCompositingMode()) { + priv->preferences->setForceCompositingMode(true); + changed = true; + } + break; + case WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER: + if (HardwareAccelerationManager::singleton().forceHardwareAcceleration()) + return; + if (priv->preferences->acceleratedCompositingEnabled()) { + priv->preferences->setAcceleratedCompositingEnabled(false); + changed = true; + } + + if (priv->preferences->forceCompositingMode()) { + priv->preferences->setForceCompositingMode(false); + changed = true; + } + break; + case WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND: + if (!priv->preferences->acceleratedCompositingEnabled() && HardwareAccelerationManager::singleton().canUseHardwareAcceleration()) { + priv->preferences->setAcceleratedCompositingEnabled(true); + changed = true; + } + + if (priv->preferences->forceCompositingMode() && !HardwareAccelerationManager::singleton().forceHardwareAcceleration()) { + priv->preferences->setForceCompositingMode(false); + changed = true; + } + break; + } + + if (changed) + g_object_notify(G_OBJECT(settings), "hardware-acceleration-policy"); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h index 66e687f3d..7f6357787 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h @@ -47,6 +47,22 @@ G_BEGIN_DECLS #define WEBKIT_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_SETTINGS)) #define WEBKIT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_SETTINGS, WebKitSettingsClass)) +/** + * WebKitHardwareAccelerationPolicy: + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND: Hardware acceleration is enabled/disabled as request by web contents. + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS: Hardware acceleration is always enabled, even for websites not requesting it. + * @WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER: Hardware acceleration is always disabled, even for websites requesting it. + * + * Enum values used for determining the hardware acceleration policy. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_HARDWARE_ACCELERATION_POLICY_ON_DEMAND, + WEBKIT_HARDWARE_ACCELERATION_POLICY_ALWAYS, + WEBKIT_HARDWARE_ACCELERATION_POLICY_NEVER +} WebKitHardwareAccelerationPolicy; + typedef struct _WebKitSettings WebKitSettings; typedef struct _WebKitSettingsClass WebKitSettingsClass; typedef struct _WebKitSettingsPrivate WebKitSettingsPrivate; @@ -236,10 +252,10 @@ WEBKIT_API void webkit_settings_set_default_charset (WebKitSettings *settings, const gchar *default_charset); -WEBKIT_API gboolean +WEBKIT_DEPRECATED gboolean webkit_settings_get_enable_private_browsing (WebKitSettings *settings); -WEBKIT_API void +WEBKIT_DEPRECATED void webkit_settings_set_enable_private_browsing (WebKitSettings *settings, gboolean enabled); @@ -414,6 +430,27 @@ WEBKIT_API void webkit_settings_set_enable_mediasource (WebKitSettings *settings, gboolean enabled); +WEBKIT_API gboolean +webkit_settings_get_allow_file_access_from_file_urls (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_allow_file_access_from_file_urls (WebKitSettings *settings, + gboolean allowed); + +WEBKIT_API gboolean +webkit_settings_get_allow_universal_access_from_file_urls (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_allow_universal_access_from_file_urls (WebKitSettings *settings, + gboolean allowed); + +WEBKIT_API WebKitHardwareAccelerationPolicy +webkit_settings_get_hardware_acceleration_policy (WebKitSettings *settings); + +WEBKIT_API void +webkit_settings_set_hardware_acceleration_policy (WebKitSettings *settings, + WebKitHardwareAccelerationPolicy policy); + G_END_DECLS #endif /* WebKitSettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp deleted file mode 100644 index 69b4b091b..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebKitTextChecker.h" - -#if ENABLE(SPELLCHECK) - -#include "WebKitPrivate.h" - -using namespace WebKit; - -static inline WebKitTextChecker* toTextChecker(const void* clientInfo) -{ - return static_cast<WebKitTextChecker*>(const_cast<void*>(clientInfo)); -} - -static bool continuousSpellCheckingEnabledCallback(const void* clientInfo) -{ - return toTextChecker(clientInfo)->isSpellCheckingEnabled(); -} - -static void setContinuousSpellCheckingEnabledCallback(bool enabled, const void* clientInfo) -{ - toTextChecker(clientInfo)->setSpellCheckingEnabled(enabled); -} - -static void checkSpellingOfStringCallback(uint64_t tag, WKStringRef text, int32_t* misspellingLocation, int32_t* misspellingLength, const void* clientInfo) -{ - toTextChecker(clientInfo)->checkSpellingOfString(toImpl(text)->string(), *misspellingLocation, *misspellingLength); -} - -static WKArrayRef guessesForWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - Vector<String> guesses = toTextChecker(clientInfo)->getGuessesForWord(toImpl(word)->string()); - if (guesses.isEmpty()) - return 0; - - WKMutableArrayRef wkSuggestions = WKMutableArrayCreate(); - for (Vector<String>::const_iterator iter = guesses.begin(); iter != guesses.end(); ++iter) { - WKRetainPtr<WKStringRef> wkSuggestion(AdoptWK, WKStringCreateWithUTF8CString(iter->utf8().data())); - WKArrayAppendItem(wkSuggestions, wkSuggestion.get()); - } - - return wkSuggestions; -} - -static void learnWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - toTextChecker(clientInfo)->learnWord(toImpl(word)->string()); -} - -static void ignoreWordCallback(uint64_t tag, WKStringRef word, const void* clientInfo) -{ - toTextChecker(clientInfo)->ignoreWord(toImpl(word)->string()); -} - -WebKitTextChecker::~WebKitTextChecker() -{ -} - -WebKitTextChecker::WebKitTextChecker() - : m_textChecker(WebCore::TextCheckerEnchant::create()) - , m_spellCheckingEnabled(false) -{ - WKTextCheckerClientV0 wkTextCheckerClient = { - { - 0, // version - this, // clientInfo - }, - 0, // continuousSpellCheckingAllowed - continuousSpellCheckingEnabledCallback, - setContinuousSpellCheckingEnabledCallback, - 0, // grammarCheckingEnabled - 0, // setGrammarCheckingEnabled - 0, // uniqueSpellDocumentTag - 0, // closeSpellDocumentWithTag - checkSpellingOfStringCallback, - 0, // checkGrammarOfString - 0, // spellingUIIsShowing - 0, // toggleSpellingUIIsShowing - 0, // updateSpellingUIWithMisspelledWord - 0, // updateSpellingUIWithGrammarString - guessesForWordCallback, - learnWordCallback, - ignoreWordCallback, - }; - WKTextCheckerSetClient(&wkTextCheckerClient.base); -} - -void WebKitTextChecker::checkSpellingOfString(const String& string, int& misspellingLocation, int& misspellingLength) -{ - m_textChecker->checkSpellingOfString(string, misspellingLocation, misspellingLength); -} - -Vector<String> WebKitTextChecker::getGuessesForWord(const String& word) -{ - return m_textChecker->getGuessesForWord(word); -} - -void WebKitTextChecker::learnWord(const String& word) -{ - m_textChecker->learnWord(word); -} - -void WebKitTextChecker::ignoreWord(const String& word) -{ - m_textChecker->ignoreWord(word); -} - -void WebKitTextChecker::setSpellCheckingEnabled(bool enabled) -{ - if (m_spellCheckingEnabled == enabled) - return; - m_spellCheckingEnabled = enabled; - - // We need to notify the Web process that this has changed. - WKTextCheckerContinuousSpellCheckingEnabledStateChanged(enabled); -} - -const char* const* WebKitTextChecker::getSpellCheckingLanguages() -{ - Vector<String> spellCheckingLanguages = m_textChecker->loadedSpellCheckingLanguages(); - if (spellCheckingLanguages.isEmpty()) - return 0; - - m_spellCheckingLanguages = adoptGRef(g_ptr_array_new_with_free_func(g_free)); - for (size_t i = 0; i < spellCheckingLanguages.size(); ++i) - g_ptr_array_add(m_spellCheckingLanguages.get(), g_strdup(spellCheckingLanguages[i].utf8().data())); - g_ptr_array_add(m_spellCheckingLanguages.get(), 0); - - return reinterpret_cast<char**>(m_spellCheckingLanguages->pdata); -} - -void WebKitTextChecker::setSpellCheckingLanguages(const char* const* languages) -{ - Vector<String> spellCheckingLanguages; - for (size_t i = 0; languages[i]; ++i) - spellCheckingLanguages.append(String::fromUTF8(languages[i])); - m_textChecker->updateSpellCheckingLanguages(spellCheckingLanguages); -} -#endif // ENABLE(SPELLCHECK) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h b/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h deleted file mode 100644 index 45424c584..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitTextChecker.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebKitTextChecker_h -#define WebKitTextChecker_h - -#if ENABLE(SPELLCHECK) - -#include <WebCore/TextCheckerEnchant.h> -#include <wtf/FastMalloc.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/Vector.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/text/CString.h> - -class WebKitTextChecker { - WTF_MAKE_FAST_ALLOCATED; - -public: - static PassOwnPtr<WebKitTextChecker> create() { return adoptPtr(new WebKitTextChecker()); } - virtual ~WebKitTextChecker(); - - // For implementing TextCheckerClient. - bool isSpellCheckingEnabled() { return m_spellCheckingEnabled; } - void setSpellCheckingEnabled(bool enabled); - void checkSpellingOfString(const String& string, int& misspellingLocation, int& misspellingLength); - Vector<String> getGuessesForWord(const String& word); - void learnWord(const String& word); - void ignoreWord(const String& word); - - // To be called from WebKitWebContext only. - const char* const* getSpellCheckingLanguages(); - void setSpellCheckingLanguages(const char* const* spellCheckingLanguages); - -private: - WebKitTextChecker(); - - OwnPtr<WebCore::TextCheckerEnchant> m_textChecker; - GRefPtr<GPtrArray> m_spellCheckingLanguages; - bool m_spellCheckingEnabled; -}; - -#endif // ENABLE(SPELLCHECK) - -#endif // WebKitTextChecker_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp index 483b82786..9bca06f52 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUIClient.cpp @@ -20,199 +20,197 @@ #include "config.h" #include "WebKitUIClient.h" +#include "APIUIClient.h" #include "WebKitFileChooserRequestPrivate.h" #include "WebKitGeolocationPermissionRequestPrivate.h" +#include "WebKitNavigationActionPrivate.h" +#include "WebKitNotificationPermissionRequestPrivate.h" #include "WebKitPrivate.h" +#include "WebKitURIRequestPrivate.h" +#include "WebKitUserMediaPermissionRequestPrivate.h" #include "WebKitWebViewBasePrivate.h" #include "WebKitWebViewPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include "WebPageProxy.h" #include <WebCore/GtkUtilities.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> using namespace WebKit; -static WKPageRef createNewPage(WKPageRef page, WKURLRequestRef, WKDictionaryRef wkWindowFeatures, WKEventModifiers, WKEventMouseButton, const void* clientInfo) -{ - return static_cast<WKPageRef>(toAPI(webkitWebViewCreateNewPage(WEBKIT_WEB_VIEW(clientInfo), toImpl(wkWindowFeatures)))); -} +class UIClient : public API::UIClient { +public: + explicit UIClient(WebKitWebView* webView) + : m_webView(webView) + { + } -static void showPage(WKPageRef page, const void* clientInfo) -{ - webkitWebViewReadyToShowPage(WEBKIT_WEB_VIEW(clientInfo)); -} +private: + PassRefPtr<WebPageProxy> createNewPage(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest& resourceRequest, const WebCore::WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData) override + { + GRefPtr<WebKitURIRequest> request = adoptGRef(webkitURIRequestCreateForResourceRequest(resourceRequest)); + WebKitNavigationAction navigationAction(request.get(), navigationActionData); + return webkitWebViewCreateNewPage(m_webView, windowFeatures, &navigationAction); + } -static void closePage(WKPageRef page, const void* clientInfo) -{ - webkitWebViewClosePage(WEBKIT_WEB_VIEW(clientInfo)); -} + void showPage(WebPageProxy*) override + { + webkitWebViewReadyToShowPage(m_webView); + } -static void runJavaScriptAlert(WKPageRef page, WKStringRef message, WKFrameRef, const void* clientInfo) -{ - webkitWebViewRunJavaScriptAlert(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8()); -} + void close(WebPageProxy*) override + { + webkitWebViewClosePage(m_webView); + } -static bool runJavaScriptConfirm(WKPageRef page, WKStringRef message, WKFrameRef, const void* clientInfo) -{ - return webkitWebViewRunJavaScriptConfirm(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8()); -} + void runJavaScriptAlert(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void ()>&& completionHandler) override + { + webkitWebViewRunJavaScriptAlert(m_webView, message.utf8()); + completionHandler(); + } -static WKStringRef runJavaScriptPrompt(WKPageRef page, WKStringRef message, WKStringRef defaultValue, WKFrameRef, const void* clientInfo) -{ - CString result = webkitWebViewRunJavaScriptPrompt(WEBKIT_WEB_VIEW(clientInfo), toImpl(message)->string().utf8(), - toImpl(defaultValue)->string().utf8()); - return WKStringCreateWithUTF8CString(result.data()); -} + void runJavaScriptConfirm(WebPageProxy*, const String& message, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (bool)>&& completionHandler) override + { + completionHandler(webkitWebViewRunJavaScriptConfirm(m_webView, message.utf8())); + } -static bool toolbarsAreVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_toolbar_visible(windowProperties); -} + void runJavaScriptPrompt(WebPageProxy*, const String& message, const String& defaultValue, WebFrameProxy*, const WebCore::SecurityOriginData&, Function<void (const String&)>&& completionHandler) override + { + CString result = webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8()); + if (result.isNull()) { + completionHandler(String()); + return; + } -static void setToolbarsAreVisible(WKPageRef page, bool toolbarsVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetToolbarVisible(windowProperties, toolbarsVisible); -} + completionHandler(String::fromUTF8(result.data())); + } -static bool menuBarIsVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_menubar_visible(windowProperties); -} + bool canRunBeforeUnloadConfirmPanel() const override { return true; } -static void setMenuBarIsVisible(WKPageRef page, bool menuBarVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetMenubarVisible(windowProperties, menuBarVisible); -} + void runBeforeUnloadConfirmPanel(WebPageProxy*, const String& message, WebFrameProxy*, Function<void (bool)>&& completionHandler) override + { + completionHandler(webkitWebViewRunJavaScriptBeforeUnloadConfirm(m_webView, message.utf8())); + } -static bool statusBarIsVisible(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_statusbar_visible(windowProperties); -} + void mouseDidMoveOverElement(WebPageProxy*, const WebHitTestResultData& data, WebEvent::Modifiers modifiers, API::Object*) override + { + webkitWebViewMouseTargetChanged(m_webView, data, toGdkModifiers(modifiers)); + } -static void setStatusBarIsVisible(WKPageRef page, bool statusBarVisible, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetStatusbarVisible(windowProperties, statusBarVisible); -} + bool toolbarsAreVisible(WebPageProxy*) override + { + return webkit_window_properties_get_toolbar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static bool isResizable(WKPageRef page, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - return webkit_window_properties_get_resizable(windowProperties); -} + void setToolbarsAreVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible); + } -static void setIsResizable(WKPageRef page, bool resizable, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - webkitWindowPropertiesSetResizable(windowProperties, resizable); -} + bool menuBarIsVisible(WebPageProxy*) override + { + return webkit_window_properties_get_menubar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static WKRect getWindowFrame(WKPageRef page, const void* clientInfo) -{ - GdkRectangle geometry = { 0, 0, 0, 0 }; - GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(clientInfo)); - if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) { - gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y); - gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height); + void setMenuBarIsVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetToolbarVisible(webkit_web_view_get_window_properties(m_webView), visible); } - return WKRectMake(geometry.x, geometry.y, geometry.width, geometry.height); -} -static void setWindowFrame(WKPageRef page, WKRect frame, const void* clientInfo) -{ - WebKitWindowProperties* windowProperties = webkit_web_view_get_window_properties(WEBKIT_WEB_VIEW(clientInfo)); - GdkRectangle geometry = { static_cast<int>(frame.origin.x), static_cast<int>(frame.origin.y), - static_cast<int>(frame.size.width), static_cast<int>(frame.size.height) }; - webkitWindowPropertiesSetGeometry(windowProperties, &geometry); -} + bool statusBarIsVisible(WebPageProxy*) override + { + return webkit_window_properties_get_statusbar_visible(webkit_web_view_get_window_properties(m_webView)); + } -static void mouseDidMoveOverElement(WKPageRef page, WKHitTestResultRef hitTestResult, WKEventModifiers modifiers, WKTypeRef userData, const void* clientInfo) -{ - webkitWebViewMouseTargetChanged(WEBKIT_WEB_VIEW(clientInfo), toImpl(hitTestResult), wkEventModifiersToGdkModifiers(modifiers)); -} + void setStatusBarIsVisible(WebPageProxy*, bool visible) override + { + webkitWindowPropertiesSetStatusbarVisible(webkit_web_view_get_window_properties(m_webView), visible); + } -static void printFrame(WKPageRef page, WKFrameRef frame, const void*) -{ - webkitWebViewPrintFrame(WEBKIT_WEB_VIEW(toImpl(page)->viewWidget()), toImpl(frame)); -} + bool isResizable(WebPageProxy*) override + { + return webkit_window_properties_get_resizable(webkit_web_view_get_window_properties(m_webView)); + } -static void runOpenPanel(WKPageRef page, WKFrameRef frame, WKOpenPanelParametersRef parameters, WKOpenPanelResultListenerRef listener, const void *clientInfo) -{ - GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(toImpl(parameters), toImpl(listener))); - webkitWebViewRunFileChooserRequest(WEBKIT_WEB_VIEW(clientInfo), request.get()); -} + void setIsResizable(WebPageProxy*, bool resizable) override + { + webkitWindowPropertiesSetResizable(webkit_web_view_get_window_properties(m_webView), resizable); + } -static void decidePolicyForGeolocationPermissionRequest(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKGeolocationPermissionRequestRef request, const void* clientInfo) -{ - GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(toImpl(request))); - webkitWebViewMakePermissionRequest(WEBKIT_WEB_VIEW(clientInfo), WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get())); -} + void setWindowFrame(WebPageProxy*, const WebCore::FloatRect& frame) override + { + GdkRectangle geometry = WebCore::IntRect(frame); + webkitWindowPropertiesSetGeometry(webkit_web_view_get_window_properties(m_webView), &geometry); + } -static void runModal(WKPageRef page, const void* clientInfo) -{ - webkitWebViewRunAsModal(WEBKIT_WEB_VIEW(clientInfo)); -} + WebCore::FloatRect windowFrame(WebPageProxy*) override + { + GdkRectangle geometry = { 0, 0, 0, 0 }; + GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView)); + if (WebCore::widgetIsOnscreenToplevelWindow(window) && gtk_widget_get_visible(window)) { + gtk_window_get_position(GTK_WINDOW(window), &geometry.x, &geometry.y); + gtk_window_get_size(GTK_WINDOW(window), &geometry.width, &geometry.height); + } + return WebCore::FloatRect(geometry); + } + + void exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, const String&, const String&, unsigned long long /*currentQuota*/, unsigned long long /*currentOriginUsage*/, unsigned long long /*currentDatabaseUsage*/, unsigned long long /*expectedUsage*/, Function<void (unsigned long long)>&& completionHandler) override + { + static const unsigned long long defaultQuota = 5 * 1024 * 1204; // 5 MB + // FIXME: Provide API for this. + completionHandler(defaultQuota); + } + + bool runOpenPanel(WebPageProxy*, WebFrameProxy*, const WebCore::SecurityOriginData&, API::OpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) override + { + GRefPtr<WebKitFileChooserRequest> request = adoptGRef(webkitFileChooserRequestCreate(parameters, listener)); + webkitWebViewRunFileChooserRequest(m_webView, request.get()); + return true; + } + + bool decidePolicyForGeolocationPermissionRequest(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin*, GeolocationPermissionRequestProxy* permissionRequest) override + { + GRefPtr<WebKitGeolocationPermissionRequest> geolocationPermissionRequest = adoptGRef(webkitGeolocationPermissionRequestCreate(permissionRequest)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(geolocationPermissionRequest.get())); + return true; + } + + bool decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin, UserMediaPermissionRequestProxy& permissionRequest) override + { + GRefPtr<WebKitUserMediaPermissionRequest> userMediaPermissionRequest = adoptGRef(webkitUserMediaPermissionRequestCreate(permissionRequest, userMediaDocumentOrigin, topLevelDocumentOrigin)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(userMediaPermissionRequest.get())); + return true; + } + + bool decidePolicyForNotificationPermissionRequest(WebPageProxy*, API::SecurityOrigin*, NotificationPermissionRequest* permissionRequest) override + { + GRefPtr<WebKitNotificationPermissionRequest> notificationPermissionRequest = adoptGRef(webkitNotificationPermissionRequestCreate(permissionRequest)); + webkitWebViewMakePermissionRequest(m_webView, WEBKIT_PERMISSION_REQUEST(notificationPermissionRequest.get())); + return true; + } + + void printFrame(WebPageProxy*, WebFrameProxy* frame) override + { + webkitWebViewPrintFrame(m_webView, frame); + } + + bool canRunModal() const override { return true; } + + void runModal(WebPageProxy*) override + { + webkitWebViewRunAsModal(m_webView); + } + + void isPlayingAudioDidChange(WebPageProxy&) override + { + webkitWebViewIsPlayingAudioChanged(m_webView); + } + + WebKitWebView* m_webView; +}; void attachUIClientToView(WebKitWebView* webView) { - WKPageUIClientV2 wkUIClient = { - { - 2, // version - webView, // clientInfo - }, - 0, // createNewPage_deprecatedForUseWithV0 - showPage, - closePage, - 0, // takeFocus - 0, // focus - 0, // unfocus - runJavaScriptAlert, - runJavaScriptConfirm, - runJavaScriptPrompt, - 0, // setStatusText - 0, // mouseDidMoveOverElement_deprecatedForUseWithV0 - 0, // missingPluginButtonClicked - 0, // didNotHandleKeyEvent - 0, // didNotHandleWheelEvent - toolbarsAreVisible, - setToolbarsAreVisible, - menuBarIsVisible, - setMenuBarIsVisible, - statusBarIsVisible, - setStatusBarIsVisible, - isResizable, - setIsResizable, - getWindowFrame, - setWindowFrame, - 0, // runBeforeUnloadConfirmPanel - 0, // didDraw - 0, // pageDidScroll - 0, // exceededDatabaseQuota - runOpenPanel, - decidePolicyForGeolocationPermissionRequest, - 0, // headerHeight - 0, // footerHeight - 0, // drawHeader - 0, // drawFooter - printFrame, - runModal, - 0, // didCompleteRubberBandForMainFrame - 0, // saveDataToFileInDownloadsFolder - 0, // shouldInterruptJavaScript - createNewPage, - mouseDidMoveOverElement, - 0, // decidePolicyForNotificationPermissionRequest - 0, // unavailablePluginButtonClicked - 0, // showColorPicker - 0, // hideColorPicker - 0, // pluginLoadPolicy - }; - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - WKPageSetPageUIClient(wkPage, &wkUIClient.base); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); + page->setUIClient(std::make_unique<UIClient>(webView)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp index 2c59cd868..e2ff04d19 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.cpp @@ -48,6 +48,7 @@ using namespace WebCore; struct _WebKitURIRequestPrivate { WebCore::ResourceRequest resourceRequest; CString uri; + const char* httpMethod; GUniquePtr<SoupMessageHeaders> httpHeaders; }; @@ -171,6 +172,32 @@ SoupMessageHeaders* webkit_uri_request_get_http_headers(WebKitURIRequest* reques return request->priv->httpHeaders.get(); } +/** + * webkit_uri_request_get_http_method: + * @request: a #WebKitURIRequest + * + * Get the HTTP method of the #WebKitURIRequest. + * + * Returns: the HTTP method of the #WebKitURIRequest or %NULL if @request is not + * an HTTP request. + * + * Since: 2.12 + */ +const gchar* webkit_uri_request_get_http_method(WebKitURIRequest* request) +{ + g_return_val_if_fail(WEBKIT_IS_URI_REQUEST(request), nullptr); + + if (!request->priv->resourceRequest.url().protocolIsInHTTPFamily()) + return nullptr; + + if (request->priv->resourceRequest.httpMethod().isEmpty()) + return nullptr; + + if (!request->priv->httpMethod) + request->priv->httpMethod = g_intern_string(request->priv->resourceRequest.httpMethod().utf8().data()); + return request->priv->httpMethod; +} + WebKitURIRequest* webkitURIRequestCreateForResourceRequest(const ResourceRequest& resourceRequest) { WebKitURIRequest* uriRequest = WEBKIT_URI_REQUEST(g_object_new(WEBKIT_TYPE_URI_REQUEST, NULL)); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h index cac3b332b..10cf63489 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIRequest.h @@ -70,6 +70,9 @@ WEBKIT_API void webkit_uri_request_set_uri (WebKitURIRequest *request, const gchar *uri); +WEBKIT_API const gchar * +webkit_uri_request_get_http_method (WebKitURIRequest *request); + WEBKIT_API SoupMessageHeaders * webkit_uri_request_get_http_headers (WebKitURIRequest *request); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp index 20ab248a5..b85fc4300 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.cpp @@ -22,6 +22,7 @@ #include "WebKitPrivate.h" #include "WebKitURIResponsePrivate.h" +#include <WebCore/GUniquePtrSoup.h> #include <glib/gi18n-lib.h> #include <wtf/text/CString.h> @@ -46,7 +47,8 @@ enum { PROP_STATUS_CODE, PROP_CONTENT_LENGTH, PROP_MIME_TYPE, - PROP_SUGGESTED_FILENAME + PROP_SUGGESTED_FILENAME, + PROP_HTTP_HEADERS }; struct _WebKitURIResponsePrivate { @@ -54,6 +56,7 @@ struct _WebKitURIResponsePrivate { CString uri; CString mimeType; CString suggestedFilename; + GUniquePtr<SoupMessageHeaders> httpHeaders; }; WEBKIT_DEFINE_TYPE(WebKitURIResponse, webkit_uri_response, G_TYPE_OBJECT) @@ -78,6 +81,9 @@ static void webkitURIResponseGetProperty(GObject* object, guint propId, GValue* case PROP_SUGGESTED_FILENAME: g_value_set_string(value, webkit_uri_response_get_suggested_filename(response)); break; + case PROP_HTTP_HEADERS: + g_value_set_boxed(value, webkit_uri_response_get_http_headers(response)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -151,6 +157,23 @@ static void webkit_uri_response_class_init(WebKitURIResponseClass* responseClass _("The suggested filename for the URI response"), 0, WEBKIT_PARAM_READABLE)); + + /** + * WebKitURIResponse:http-headers: + * + * The HTTP headers of the response, or %NULL if the response is not an HTTP response. + * + * Since: 2.6 + */ + g_object_class_install_property( + objectClass, + PROP_HTTP_HEADERS, + g_param_spec_boxed( + "http-headers", + _("HTTP Headers"), + _("The The HTTP headers of the response"), + SOUP_TYPE_MESSAGE_HEADERS, + WEBKIT_PARAM_READABLE)); } /** @@ -237,6 +260,31 @@ const gchar* webkit_uri_response_get_suggested_filename(WebKitURIResponse* respo return response->priv->suggestedFilename.data(); } +/** + * webkit_uri_response_get_http_headers: + * @response: a #WebKitURIResponse + * + * Get the HTTP headers of a #WebKitURIResponse as a #SoupMessageHeaders. + * + * Returns: (transfer none): a #SoupMessageHeaders with the HTTP headers of @response + * or %NULL if @response is not an HTTP response. + * Since: 2.6 + */ +SoupMessageHeaders* webkit_uri_response_get_http_headers(WebKitURIResponse* response) +{ + g_return_val_if_fail(WEBKIT_IS_URI_RESPONSE(response), nullptr); + + if (response->priv->httpHeaders) + return response->priv->httpHeaders.get(); + + if (!response->priv->resourceResponse.url().protocolIsInHTTPFamily()) + return nullptr; + + response->priv->httpHeaders.reset(soup_message_headers_new(SOUP_MESSAGE_HEADERS_RESPONSE)); + response->priv->resourceResponse.updateSoupMessageHeaders(response->priv->httpHeaders.get()); + return response->priv->httpHeaders.get(); +} + WebKitURIResponse* webkitURIResponseCreateForResourceResponse(const WebCore::ResourceResponse& resourceResponse) { WebKitURIResponse* uriResponse = WEBKIT_URI_RESPONSE(g_object_new(WEBKIT_TYPE_URI_RESPONSE, NULL)); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h index d43eca13f..67316165f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURIResponse.h @@ -25,6 +25,7 @@ #define WebKitURIResponse_h #include <gio/gio.h> +#include <libsoup/soup.h> #include <webkit2/WebKitDefines.h> G_BEGIN_DECLS @@ -74,6 +75,9 @@ webkit_uri_response_get_mime_type (WebKitURIResponse *response); WEBKIT_API const gchar * webkit_uri_response_get_suggested_filename (WebKitURIResponse *response); +WEBKIT_API SoupMessageHeaders * +webkit_uri_response_get_http_headers (WebKitURIResponse *response); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp index 6d8c68418..59bdb930d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequest.cpp @@ -21,6 +21,7 @@ #include "WebKitURISchemeRequest.h" #include "APIData.h" +#include "WebKitPrivate.h" #include "WebKitURISchemeRequestPrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebView.h" @@ -28,10 +29,11 @@ #include <WebCore/GUniquePtrSoup.h> #include <WebCore/ResourceError.h> #include <libsoup/soup.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; +using namespace WebCore; /** * SECTION: WebKitURISchemeRequest @@ -53,7 +55,7 @@ static const unsigned int gReadBufferSize = 8192; struct _WebKitURISchemeRequestPrivate { WebKitWebContext* webContext; - RefPtr<WebSoupCustomProtocolRequestManager> webRequestManager; + CustomProtocolManagerProxy* manager; RefPtr<WebPageProxy> initiatingPage; uint64_t requestID; CString uri; @@ -69,25 +71,35 @@ struct _WebKitURISchemeRequestPrivate { WEBKIT_DEFINE_TYPE(WebKitURISchemeRequest, webkit_uri_scheme_request, G_TYPE_OBJECT) -static void webkit_uri_scheme_request_class_init(WebKitURISchemeRequestClass* requestClass) +static void webkit_uri_scheme_request_class_init(WebKitURISchemeRequestClass*) { } -WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext* webContext, API::URLRequest* urlRequest) +WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext* webContext, const ResourceRequest& resourceRequest, CustomProtocolManagerProxy& manager) { - WebKitURISchemeRequest* request = WEBKIT_URI_SCHEME_REQUEST(g_object_new(WEBKIT_TYPE_URI_SCHEME_REQUEST, NULL)); + WebKitURISchemeRequest* request = WEBKIT_URI_SCHEME_REQUEST(g_object_new(WEBKIT_TYPE_URI_SCHEME_REQUEST, nullptr)); request->priv->webContext = webContext; - request->priv->webRequestManager = webkitWebContextGetRequestManager(webContext); - request->priv->uri = urlRequest->resourceRequest().url().string().utf8(); - request->priv->initiatingPage = WebProcessProxy::webPage(urlRequest->resourceRequest().initiatingPageID()); + request->priv->manager = &manager; + request->priv->uri = resourceRequest.url().string().utf8(); + request->priv->initiatingPage = WebProcessProxy::webPage(resourceRequest.initiatingPageID()); request->priv->requestID = requestID; return request; } void webkitURISchemeRequestCancel(WebKitURISchemeRequest* request) { - if (request->priv->cancellable.get()) - g_cancellable_cancel(request->priv->cancellable.get()); + g_cancellable_cancel(request->priv->cancellable.get()); +} + +CustomProtocolManagerProxy* webkitURISchemeRequestGetManager(WebKitURISchemeRequest* request) +{ + return request->priv->manager; +} + +void webkitURISchemeRequestInvalidate(WebKitURISchemeRequest* request) +{ + request->priv->manager = nullptr; + webkitURISchemeRequestCancel(request); } /** @@ -158,29 +170,39 @@ WebKitWebView* webkit_uri_scheme_request_get_web_view(WebKitURISchemeRequest* re static void webkitURISchemeRequestReadCallback(GInputStream* inputStream, GAsyncResult* result, WebKitURISchemeRequest* schemeRequest) { GRefPtr<WebKitURISchemeRequest> request = adoptGRef(schemeRequest); + WebKitURISchemeRequestPrivate* priv = request->priv; GUniqueOutPtr<GError> error; gssize bytesRead = g_input_stream_read_finish(inputStream, result, &error.outPtr()); + if (!priv->manager) { + webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); + return; + } + if (bytesRead == -1) { webkit_uri_scheme_request_finish_error(request.get(), error.get()); return; } - WebKitURISchemeRequestPrivate* priv = request->priv; - RefPtr<API::Data> webData = API::Data::create(reinterpret_cast<const unsigned char*>(priv->readBuffer), bytesRead); + // Need to check the stream before proceeding as it can be cancelled if finish_error + // was previously call, which won't be detected by g_input_stream_read_finish(). + if (!request->priv->stream) + return; + + auto webData = IPC::DataReference(reinterpret_cast<const uint8_t*>(priv->readBuffer), bytesRead); if (!priv->bytesRead) { // First chunk read. In case of empty reply an empty API::Data is sent to the networking process. - WebCore::ResourceResponse response(WebCore::URL(WebCore::URL(), String::fromUTF8(priv->uri)), String::fromUTF8(priv->mimeType.data()), - priv->streamLength, emptyString(), emptyString()); - priv->webRequestManager->didReceiveResponse(priv->requestID, response); - priv->webRequestManager->didLoadData(priv->requestID, webData.get()); + ResourceResponse response(URL(URL(), String::fromUTF8(priv->uri)), String::fromUTF8(priv->mimeType.data()), + priv->streamLength, emptyString()); + priv->manager->didReceiveResponse(priv->requestID, response, 0); + priv->manager->didLoadData(priv->requestID, webData); } else if (bytesRead || (!bytesRead && !priv->streamLength)) { // Subsequent chunk read. We only send an empty API::Data to the networking process when stream length is unknown. - priv->webRequestManager->didLoadData(priv->requestID, webData.get()); + priv->manager->didLoadData(priv->requestID, webData); } if (!bytesRead) { - priv->webRequestManager->didFinishLoading(request->priv->requestID); - webkitWebContextDidFinishLoadingCustomProtocol(request->priv->webContext, request->priv->requestID); + priv->manager->didFinishLoading(priv->requestID); + webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); return; } @@ -229,8 +251,11 @@ void webkit_uri_scheme_request_finish_error(WebKitURISchemeRequest* request, GEr g_return_if_fail(error); WebKitURISchemeRequestPrivate* priv = request->priv; + if (!webkitWebContextIsLoadingCustomProtocol(priv->webContext, priv->requestID)) + return; - WebCore::ResourceError resourceError(g_quark_to_string(error->domain), error->code, priv->uri.data(), String::fromUTF8(error->message)); - priv->webRequestManager->didFailWithError(priv->requestID, resourceError); + priv->stream = nullptr; + ResourceError resourceError(g_quark_to_string(error->domain), toWebCoreError(error->code), URL(priv->soupURI.get()), String::fromUTF8(error->message)); + priv->manager->didFailWithError(priv->requestID, resourceError); webkitWebContextDidFinishLoadingCustomProtocol(priv->webContext, priv->requestID); } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h index c72fa185e..47bb8c272 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitURISchemeRequestPrivate.h @@ -20,11 +20,15 @@ #ifndef WebKitURISchemeRequestPrivate_h #define WebKitURISchemeRequestPrivate_h +#include "CustomProtocolManagerProxy.h" #include "WebKitPrivate.h" #include "WebKitURISchemeRequest.h" #include "WebKitWebContext.h" +#include <WebCore/ResourceRequest.h> -WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext*, API::URLRequest*); +WebKitURISchemeRequest* webkitURISchemeRequestCreate(uint64_t requestID, WebKitWebContext*, const WebCore::ResourceRequest&, WebKit::CustomProtocolManagerProxy&); void webkitURISchemeRequestCancel(WebKitURISchemeRequest*); +WebKit::CustomProtocolManagerProxy* webkitURISchemeRequestGetManager(WebKitURISchemeRequest*); +void webkitURISchemeRequestInvalidate(WebKitURISchemeRequest*); #endif // WebKitURISchemeRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp new file mode 100644 index 000000000..6fac63c6f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitUserContent.h" + +#include "WebKitPrivate.h" +#include "WebKitUserContentPrivate.h" +#include <wtf/text/CString.h> + +using namespace WebCore; + +/** + * SECTION:WebKitUserContent + * @short_description: Defines user content types which affect web pages. + * @title: User content + * + * See also: #WebKitUserContentManager + * + * Since: 2.6 + */ + +static inline UserContentInjectedFrames toUserContentInjectedFrames(WebKitUserContentInjectedFrames injectedFrames) +{ + switch (injectedFrames) { + case WEBKIT_USER_CONTENT_INJECT_TOP_FRAME: + return InjectInTopFrameOnly; + case WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES: + return InjectInAllFrames; + default: + ASSERT_NOT_REACHED(); + return InjectInAllFrames; + } +} + +static inline UserStyleLevel toUserStyleLevel(WebKitUserStyleLevel styleLevel) +{ + switch (styleLevel) { + case WEBKIT_USER_STYLE_LEVEL_USER: + return UserStyleUserLevel; + case WEBKIT_USER_STYLE_LEVEL_AUTHOR: + return UserStyleAuthorLevel; + default: + ASSERT_NOT_REACHED(); + return UserStyleAuthorLevel; + } +} + +static inline UserScriptInjectionTime toUserScriptInjectionTime(WebKitUserScriptInjectionTime injectionTime) +{ + switch (injectionTime) { + case WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START: + return InjectAtDocumentStart; + case WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END: + return InjectAtDocumentEnd; + default: + ASSERT_NOT_REACHED(); + return InjectAtDocumentStart; + } +} + +static inline Vector<String> toStringVector(const char* const* strv) +{ + if (!strv) + return Vector<String>(); + + Vector<String> result; + for (auto str = strv; *str; ++str) + result.append(String::fromUTF8(*str)); + return result; +} + +struct _WebKitUserStyleSheet { + _WebKitUserStyleSheet(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) + : userStyleSheet(adoptRef(new API::UserStyleSheet(UserStyleSheet { + String::fromUTF8(source), URL { }, + toStringVector(whitelist), toStringVector(blacklist), + toUserContentInjectedFrames(injectedFrames), + toUserStyleLevel(level) }, API::UserContentWorld::normalWorld()))) + , referenceCount(1) + { + } + + RefPtr<API::UserStyleSheet> userStyleSheet; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitUserStyleSheet, webkit_user_style_sheet, webkit_user_style_sheet_ref, webkit_user_style_sheet_unref) + +/** + * webkit_user_style_sheet_ref: + * @user_style_sheet: a #WebKitUserStyleSheet + * + * Atomically increments the reference count of @user_style_sheet by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitUserStyleSheet + * + * Since: 2.6 + */ +WebKitUserStyleSheet* webkit_user_style_sheet_ref(WebKitUserStyleSheet* userStyleSheet) +{ + g_atomic_int_inc(&userStyleSheet->referenceCount); + return userStyleSheet; +} + +/** + * webkit_user_style_sheet_unref: + * @user_style_sheet: a #WebKitUserStyleSheet + * + * Atomically decrements the reference count of @user_style_sheet by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitUserStyleSheet is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.6 + */ +void webkit_user_style_sheet_unref(WebKitUserStyleSheet* userStyleSheet) +{ + if (g_atomic_int_dec_and_test(&userStyleSheet->referenceCount)) { + userStyleSheet->~WebKitUserStyleSheet(); + fastFree(userStyleSheet); + } +} + +/** + * webkit_user_style_sheet_new: + * @source: Source code of the user style sheet. + * @injected_frames: A #WebKitUserContentInjectedFrames value + * @level: A #WebKitUserStyleLevel + * @whitelist: (array zero-terminated=1) (allow-none): A whitelist of URI patterns or %NULL + * @blacklist: (array zero-terminated=1) (allow-none): A blacklist of URI patterns or %NULL + * + * Creates a new user style sheet. Style sheets can be applied to some URIs + * only by passing non-null values for @whitelist or @blacklist. Passing a + * %NULL whitelist implies that all URIs are on the whitelist. The style + * sheet is applied if an URI matches the whitelist and not the blacklist. + * URI patterns must be of the form `[protocol]://[host]/[path]`, where the + * *host* and *path* components can contain the wildcard character (`*`) to + * represent zero or more other characters. + * + * Returns: A new #WebKitUserStyleSheet + * + * Since: 2.6 + */ +WebKitUserStyleSheet* webkit_user_style_sheet_new(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserStyleLevel level, const char* const* whitelist, const char* const* blacklist) +{ + g_return_val_if_fail(source, nullptr); + WebKitUserStyleSheet* userStyleSheet = static_cast<WebKitUserStyleSheet*>(fastMalloc(sizeof(WebKitUserStyleSheet))); + new (userStyleSheet) WebKitUserStyleSheet(source, injectedFrames, level, whitelist, blacklist); + return userStyleSheet; +} + +API::UserStyleSheet& webkitUserStyleSheetGetUserStyleSheet(WebKitUserStyleSheet* userStyleSheet) +{ + return *userStyleSheet->userStyleSheet; +} + +struct _WebKitUserScript { + _WebKitUserScript(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserScriptInjectionTime injectionTime, const gchar* const* whitelist, const gchar* const* blacklist) + : userScript(adoptRef(new API::UserScript(UserScript { + String::fromUTF8(source), URL { }, + toStringVector(whitelist), toStringVector(blacklist), + toUserScriptInjectionTime(injectionTime), + toUserContentInjectedFrames(injectedFrames) }, API::UserContentWorld::normalWorld()))) + , referenceCount(1) + { + } + + RefPtr<API::UserScript> userScript; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitUserScript, webkit_user_script, webkit_user_script_ref, webkit_user_script_unref) + +/** + * webkit_user_script_ref: + * @user_script: a #WebKitUserScript + * + * Atomically increments the reference count of @user_script by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitUserScript + * + * Since: 2.6 + */ +WebKitUserScript* webkit_user_script_ref(WebKitUserScript* userScript) +{ + g_atomic_int_inc(&userScript->referenceCount); + return userScript; +} + +/** + * webkit_user_script_unref: + * @user_script: a #WebKitUserScript + * + * Atomically decrements the reference count of @user_script by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitUserScript is released. This function is MT-safe and may be called + * from any thread. + * + * Since: 2.6 + */ +void webkit_user_script_unref(WebKitUserScript* userScript) +{ + if (g_atomic_int_dec_and_test(&userScript->referenceCount)) { + userScript->~WebKitUserScript(); + fastFree(userScript); + } +} + +/** + * webkit_user_script_new: + * @source: Source code of the user script. + * @injected_frames: A #WebKitUserContentInjectedFrames value + * @injection_time: A #WebKitUserScriptInjectionTime value + * @whitelist: (array zero-terminated=1) (allow-none): A whitelist of URI patterns or %NULL + * @blacklist: (array zero-terminated=1) (allow-none): A blacklist of URI patterns or %NULL + * + * Creates a new user script. Scripts can be applied to some URIs + * only by passing non-null values for @whitelist or @blacklist. Passing a + * %NULL whitelist implies that all URIs are on the whitelist. The script + * is applied if an URI matches the whitelist and not the blacklist. + * URI patterns must be of the form `[protocol]://[host]/[path]`, where the + * *host* and *path* components can contain the wildcard character (`*`) to + * represent zero or more other characters. + * + * Returns: A new #WebKitUserScript + * + * Since: 2.6 + */ +WebKitUserScript* webkit_user_script_new(const gchar* source, WebKitUserContentInjectedFrames injectedFrames, WebKitUserScriptInjectionTime injectionTime, const gchar* const* whitelist, const gchar* const* blacklist) +{ + g_return_val_if_fail(source, nullptr); + WebKitUserScript* userScript = static_cast<WebKitUserScript*>(fastMalloc(sizeof(WebKitUserScript))); + new (userScript) WebKitUserScript(source, injectedFrames, injectionTime, whitelist, blacklist); + return userScript; +} + +API::UserScript& webkitUserScriptGetUserScript(WebKitUserScript* userScript) +{ + return *userScript->userScript; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h new file mode 100644 index 000000000..c3f1ed569 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContent.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserContent_h +#define WebKitUserContent_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +/** + * WebKitUserContentInjectedFrames: + * @WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES: Insert the user style + * sheet in all the frames loaded by the web view, including + * nested frames. This is the default. + * @WEBKIT_USER_CONTENT_INJECT_TOP_FRAME: Insert the user style + * sheet *only* in the top-level frame loaded by the web view, + * and *not* in the nested frames. + * + * Specifies in which frames user style sheets are to be inserted in. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, + WEBKIT_USER_CONTENT_INJECT_TOP_FRAME, +} WebKitUserContentInjectedFrames; + +/** + * WebKitUserStyleLevel: + * @WEBKIT_USER_STYLE_LEVEL_USER: The style sheet is an user style sheet, + * its contents always override other style sheets. This is the default. + * @WEBKIT_USER_STYLE_LEVEL_AUTHOR: The style sheet will be treated as if + * it was provided by the loaded documents. That means other user style + * sheets may still override it. + * + * Specifies how to treat an user style sheet. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_STYLE_LEVEL_USER, + WEBKIT_USER_STYLE_LEVEL_AUTHOR, +} WebKitUserStyleLevel; + +#define WEBKIT_TYPE_USER_STYLE_SHEET (webkit_user_style_sheet_get_type()) + +typedef struct _WebKitUserStyleSheet WebKitUserStyleSheet; + +WEBKIT_API GType +webkit_user_style_sheet_get_type (void); + +WEBKIT_API WebKitUserStyleSheet * +webkit_user_style_sheet_ref (WebKitUserStyleSheet *user_style_sheet); + +WEBKIT_API void +webkit_user_style_sheet_unref (WebKitUserStyleSheet *user_style_sheet); + +WEBKIT_API WebKitUserStyleSheet * +webkit_user_style_sheet_new (const gchar *source, + WebKitUserContentInjectedFrames injected_frames, + WebKitUserStyleLevel level, + const gchar* const *whitelist, + const gchar* const *blacklist); + +/** + * WebKitUserScriptInjectionTime: + * @WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START: Insert the code of the user + * script at the beginning of loaded documents. This is the default. + * @WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END: Insert the code of the user + * script at the end of the loaded documents. + * + * Specifies at which place of documents an user script will be inserted. + * + * Since: 2.6 + */ +typedef enum { + WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, + WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, +} WebKitUserScriptInjectionTime; + +#define WEBKIT_TYPE_USER_SCRIPT (webkit_user_script_get_type()) + +typedef struct _WebKitUserScript WebKitUserScript; + +WEBKIT_API GType +webkit_user_script_get_type (void); + +WEBKIT_API WebKitUserScript * +webkit_user_script_ref (WebKitUserScript *user_script); + +WEBKIT_API void +webkit_user_script_unref (WebKitUserScript *user_script); + +WEBKIT_API WebKitUserScript * +webkit_user_script_new (const gchar *source, + WebKitUserContentInjectedFrames injected_frames, + WebKitUserScriptInjectionTime injection_time, + const gchar* const *whitelist, + const gchar* const *blacklist); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp new file mode 100644 index 000000000..5c7d7af38 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitUserContentManager.h" + +#include "APISerializedScriptValue.h" +#include "WebKitJavascriptResultPrivate.h" +#include "WebKitPrivate.h" +#include "WebKitUserContentManagerPrivate.h" +#include "WebKitUserContentPrivate.h" +#include "WebKitWebContextPrivate.h" +#include "WebScriptMessageHandler.h" +#include <wtf/glib/GRefPtr.h> + +using namespace WebCore; +using namespace WebKit; + +struct _WebKitUserContentManagerPrivate { + _WebKitUserContentManagerPrivate() + : userContentController(adoptRef(new WebUserContentControllerProxy)) + { + } + + RefPtr<WebUserContentControllerProxy> userContentController; +}; + +/** + * SECTION:WebKitUserContentManager + * @short_description: Manages user-defined content which affects web pages. + * @title: WebKitUserContentManager + * + * Using a #WebKitUserContentManager user CSS style sheets can be set to + * be injected in the web pages loaded by a #WebKitWebView, by + * webkit_user_content_manager_add_style_sheet(). + * + * To use a #WebKitUserContentManager, it must be created using + * webkit_user_content_manager_new(), and then passed to + * webkit_web_view_new_with_user_content_manager(). User style + * sheets can be created with webkit_user_style_sheet_new(). + * + * User style sheets can be added and removed at any time, but + * they will affect the web pages loaded afterwards. + * + * Since: 2.6 + */ + +WEBKIT_DEFINE_TYPE(WebKitUserContentManager, webkit_user_content_manager, G_TYPE_OBJECT) + +enum { + SCRIPT_MESSAGE_RECEIVED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +static void webkit_user_content_manager_class_init(WebKitUserContentManagerClass* klass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(klass); + + /** + * WebKitUserContentManager::script-message-received: + * @manager: the #WebKitUserContentManager + * @js_result: the #WebKitJavascriptResult holding the value received from the JavaScript world. + * + * This signal is emitted when JavaScript in a web view calls + * <code>window.webkit.messageHandlers.<name>.postMessage()</code>, after registering + * <code><name></code> using + * webkit_user_content_manager_register_script_message_handler() + * + * Since: 2.8 + */ + signals[SCRIPT_MESSAGE_RECEIVED] = + g_signal_new( + "script-message-received", + G_TYPE_FROM_CLASS(gObjectClass), + static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED), + 0, nullptr, nullptr, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + WEBKIT_TYPE_JAVASCRIPT_RESULT); +} + +/** + * webkit_user_content_manager_new: + * + * Creates a new user content manager. + * + * Returns: A #WebKitUserContentManager + * + * Since: 2.6 + */ +WebKitUserContentManager* webkit_user_content_manager_new() +{ + return WEBKIT_USER_CONTENT_MANAGER(g_object_new(WEBKIT_TYPE_USER_CONTENT_MANAGER, nullptr)); +} + +/** + * webkit_user_content_manager_add_style_sheet: + * @manager: A #WebKitUserContentManager + * @stylesheet: A #WebKitUserStyleSheet + * + * Adds a #WebKitUserStyleSheet to the given #WebKitUserContentManager. + * The same #WebKitUserStyleSheet can be reused with multiple + * #WebKitUserContentManager instances. + * + * Since: 2.6 + */ +void webkit_user_content_manager_add_style_sheet(WebKitUserContentManager* manager, WebKitUserStyleSheet* styleSheet) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(styleSheet); + manager->priv->userContentController->addUserStyleSheet(webkitUserStyleSheetGetUserStyleSheet(styleSheet)); +} + +/** + * webkit_user_content_manager_remove_all_style_sheets: + * @manager: A #WebKitUserContentManager + * + * Removes all user style sheets from the given #WebKitUserContentManager. + * + * Since: 2.6 + */ +void webkit_user_content_manager_remove_all_style_sheets(WebKitUserContentManager* manager) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + manager->priv->userContentController->removeAllUserStyleSheets(); +} + +/** + * webkit_user_content_manager_add_script: + * @manager: A #WebKitUserContentManager + * @script: A #WebKitUserScript + * + * Adds a #WebKitUserScript to the given #WebKitUserContentManager. + * The same #WebKitUserScript can be reused with multiple + * #WebKitUserContentManager instances. + * + * Since: 2.6 + */ +void webkit_user_content_manager_add_script(WebKitUserContentManager* manager, WebKitUserScript* script) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(script); + manager->priv->userContentController->addUserScript(webkitUserScriptGetUserScript(script)); +} + +/** + * webkit_user_content_manager_remove_all_scripts: + * @manager: A #WebKitUserContentManager + * + * Removes all user scripts from the given #WebKitUserContentManager + * + * Since: 2.6 + */ +void webkit_user_content_manager_remove_all_scripts(WebKitUserContentManager* manager) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + manager->priv->userContentController->removeAllUserScripts(); +} + +class ScriptMessageClientGtk final : public WebScriptMessageHandler::Client { +public: + ScriptMessageClientGtk(WebKitUserContentManager* manager, const char* handlerName) + : m_handlerName(g_quark_from_string(handlerName)) + , m_manager(manager) + { + } + + void didPostMessage(WebPageProxy& page, const FrameInfoData&, WebCore::SerializedScriptValue& serializedScriptValue) override + { + WebKitJavascriptResult* jsResult = webkitJavascriptResultCreate(WEBKIT_WEB_VIEW(page.viewWidget()), serializedScriptValue); + g_signal_emit(m_manager, signals[SCRIPT_MESSAGE_RECEIVED], m_handlerName, jsResult); + webkit_javascript_result_unref(jsResult); + } + + virtual ~ScriptMessageClientGtk() { } + +private: + GQuark m_handlerName; + WebKitUserContentManager* m_manager; +}; + +/** + * webkit_user_content_manager_register_script_message_handler: + * @manager: A #WebKitUserContentManager + * @name: Name of the script message channel + * + * Registers a new user script message handler. After it is registered, + * scripts can use `window.webkit.messageHandlers.<name>.postMessage(value)` + * to send messages. Those messages are received by connecting handlers + * to the #WebKitUserContentManager::script-message-received signal. The + * handler name is used as the detail of the signal. To avoid race + * conditions between registering the handler name, and starting to + * receive the signals, it is recommended to connect to the signal + * *before* registering the handler name: + * + * <informalexample><programlisting> + * WebKitWebView *view = webkit_web_view_new (); + * WebKitUserContentManager *manager = webkit_web_view_get_user_content_manager (); + * g_signal_connect (manager, "script-message-received::foobar", + * G_CALLBACK (handle_script_message), NULL); + * webkit_user_content_manager_register_script_message_handler (manager, "foobar"); + * </programlisting></informalexample> + * + * Registering a script message handler will fail if the requested + * name has been already registered before. + * + * Returns: %TRUE if message handler was registered successfully, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_user_content_manager_register_script_message_handler(WebKitUserContentManager* manager, const char* name) +{ + g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager), FALSE); + g_return_val_if_fail(name, FALSE); + + Ref<WebScriptMessageHandler> handler = + WebScriptMessageHandler::create(std::make_unique<ScriptMessageClientGtk>(manager, name), String::fromUTF8(name), API::UserContentWorld::normalWorld()); + return manager->priv->userContentController->addUserScriptMessageHandler(handler.get()); +} + +/** + * webkit_user_content_manager_unregister_script_message_handler: + * @manager: A #WebKitUserContentManager + * @name: Name of the script message channel + * + * Unregisters a previously registered message handler. + * + * Note that this does *not* disconnect handlers for the + * #WebKitUserContentManager::script-message-received signal, + * they will be kept connected, but the signal will not be emitted + * unless the handler name is registered again. + * + * See also webkit_user_content_manager_register_script_message_handler() + * + * Since: 2.8 + */ +void webkit_user_content_manager_unregister_script_message_handler(WebKitUserContentManager* manager, const char* name) +{ + g_return_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(manager)); + g_return_if_fail(name); + manager->priv->userContentController->removeUserMessageHandlerForName(String::fromUTF8(name), API::UserContentWorld::normalWorld()); +} + +WebUserContentControllerProxy* webkitUserContentManagerGetUserContentControllerProxy(WebKitUserContentManager* manager) +{ + return manager->priv->userContentController.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h new file mode 100644 index 000000000..86d24a113 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManager.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserContentManager_h +#define WebKitUserContentManager_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitUserContent.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_USER_CONTENT_MANAGER (webkit_user_content_manager_get_type()) +#define WEBKIT_USER_CONTENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManager)) +#define WEBKIT_IS_USER_CONTENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER)) +#define WEBKIT_USER_CONTENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManagerClass)) +#define WEBKIT_IS_USER_CONTENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_USER_CONTENT_MANAGER)) +#define WEBKIT_USER_CONTENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_USER_CONTENT_MANAGER, WebKitUserContentManagerClass)) + +typedef struct _WebKitUserContentManager WebKitUserContentManager; +typedef struct _WebKitUserContentManagerClass WebKitUserContentManagerClass; +typedef struct _WebKitUserContentManagerPrivate WebKitUserContentManagerPrivate; + + +struct _WebKitUserContentManager { + GObject parent; + + /*< private >*/ + WebKitUserContentManagerPrivate *priv; +}; + +struct _WebKitUserContentManagerClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + + +WEBKIT_API GType +webkit_user_content_manager_get_type (void); + +WEBKIT_API WebKitUserContentManager * +webkit_user_content_manager_new (void); + +WEBKIT_API void +webkit_user_content_manager_add_style_sheet (WebKitUserContentManager *manager, + WebKitUserStyleSheet *stylesheet); +WEBKIT_API void +webkit_user_content_manager_remove_all_style_sheets (WebKitUserContentManager *manager); + +WEBKIT_API gboolean +webkit_user_content_manager_register_script_message_handler (WebKitUserContentManager *manager, + const gchar *name); +WEBKIT_API void +webkit_user_content_manager_unregister_script_message_handler (WebKitUserContentManager *manager, + const gchar *name); + +WEBKIT_API void +webkit_user_content_manager_add_script (WebKitUserContentManager *manager, + WebKitUserScript *script); + +WEBKIT_API void +webkit_user_content_manager_remove_all_scripts (WebKitUserContentManager *manager); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h new file mode 100644 index 000000000..f791a5357 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentManagerPrivate.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitUserContentManagerPrivate_h +#define WebKitUserContentManagerPrivate_h + +#include "WebKitUserContentManager.h" +#include "WebUserContentControllerProxy.h" + +WebKit::WebUserContentControllerProxy* webkitUserContentManagerGetUserContentControllerProxy(WebKitUserContentManager*); + +#endif // WebKitUserContentManagerPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h new file mode 100644 index 000000000..444e2caaa --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserContentPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitUserContentPrivate_h +#define WebKitUserContentPrivate_h + +#include "APIUserScript.h" +#include "APIUserStyleSheet.h" +#include "WebKitUserContent.h" +#include <WebCore/UserScript.h> +#include <WebCore/UserStyleSheet.h> + +API::UserScript& webkitUserScriptGetUserScript(WebKitUserScript*); +API::UserStyleSheet& webkitUserStyleSheetGetUserStyleSheet(WebKitUserStyleSheet*); + +#endif // WebKitUserContentPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp new file mode 100644 index 000000000..1220a9e6d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "WebKitUserMediaPermissionRequest.h" + +#include "UserMediaPermissionRequestProxy.h" +#include "WebKitPermissionRequest.h" +#include "WebKitUserMediaPermissionRequestPrivate.h" +#include <glib/gi18n-lib.h> + +using namespace WebKit; + +/** + * SECTION: WebKitUserMediaPermissionRequest + * @Short_description: A permission request for accessing user's audio/video devices. + * @Title: WebKitUserMediaPermissionRequest + * @See_also: #WebKitPermissionRequest, #WebKitWebView + * + * WebKitUserMediaPermissionRequest represents a request for + * permission to decide whether WebKit should be allowed to access the user's + * audio and video source devices when requested throught the getUserMedia API. + * + * When a WebKitUserMediaPermissionRequest is not handled by the user, + * it is denied by default. + * + * Since: 2.8 + */ + +enum { + PROP_0, + PROP_IS_FOR_AUDIO_DEVICE, + PROP_IS_FOR_VIDEO_DEVICE +}; + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface*); + +struct _WebKitUserMediaPermissionRequestPrivate { + RefPtr<UserMediaPermissionRequestProxy> request; + bool madeDecision; +}; + +WEBKIT_DEFINE_TYPE_WITH_CODE( + WebKitUserMediaPermissionRequest, webkit_user_media_permission_request, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_PERMISSION_REQUEST, webkit_permission_request_interface_init)) + +static void webkitUserMediaPermissionRequestAllow(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)); + + WebKitUserMediaPermissionRequestPrivate* priv = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->madeDecision = true; + + auto videoDeviceUIDs = priv->request->videoDeviceUIDs(); + auto audioDeviceUIDs = priv->request->audioDeviceUIDs(); + + auto videoDevice = !videoDeviceUIDs.isEmpty() ? videoDeviceUIDs[0] : emptyString(); + auto audioDevice = !audioDeviceUIDs.isEmpty() ? audioDeviceUIDs[0] : emptyString(); + + priv->request->allow(audioDevice, videoDevice); +} + +static void webkitUserMediaPermissionRequestDeny(WebKitPermissionRequest* request) +{ + ASSERT(WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)); + + WebKitUserMediaPermissionRequestPrivate* priv = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request)->priv; + + // Only one decision at a time. + if (priv->madeDecision) + return; + + priv->madeDecision = true; + priv->request->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied); +} + +static void webkit_permission_request_interface_init(WebKitPermissionRequestIface* iface) +{ + iface->allow = webkitUserMediaPermissionRequestAllow; + iface->deny = webkitUserMediaPermissionRequestDeny; +} + +static void webkitUserMediaPermissionRequestDispose(GObject* object) +{ + // Default behaviour when no decision has been made is denying the request. + webkitUserMediaPermissionRequestDeny(WEBKIT_PERMISSION_REQUEST(object)); + G_OBJECT_CLASS(webkit_user_media_permission_request_parent_class)->dispose(object); +} + +/** + * webkit_user_media_permission_is_for_audio_device: + * @request: a #WebKitUserMediaPermissionRequest + * + * Returns: %TRUE if access to an audio device was requested. + * + * Since: 2.8 + */ +gboolean webkit_user_media_permission_is_for_audio_device(WebKitUserMediaPermissionRequest* request) +{ + g_return_val_if_fail(request->priv->request, FALSE); + return request->priv->request->requiresAudio(); +} + +/** + * webkit_user_media_permission_is_for_video_device: + * @request: a #WebKitUserMediaPermissionRequest + * + * Returns: %TRUE if access to a video device was requested. + * + * Since: 2.8 + */ +gboolean webkit_user_media_permission_is_for_video_device(WebKitUserMediaPermissionRequest* request) +{ + g_return_val_if_fail(request->priv->request, FALSE); + return request->priv->request->requiresVideo(); +} + +static void webkitUserMediaPermissionRequestGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitUserMediaPermissionRequest* request = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(object); + + switch (propId) { + case PROP_IS_FOR_AUDIO_DEVICE: + g_value_set_boolean(value, webkit_user_media_permission_is_for_audio_device(request)); + break; + case PROP_IS_FOR_VIDEO_DEVICE: + g_value_set_boolean(value, webkit_user_media_permission_is_for_video_device(request)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_user_media_permission_request_class_init(WebKitUserMediaPermissionRequestClass* klass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(klass); + objectClass->dispose = webkitUserMediaPermissionRequestDispose; + objectClass->get_property = webkitUserMediaPermissionRequestGetProperty; + + /** + * WebKitUserPermissionRequest:is-for-audio-device: + * + * Whether the media device to which the permission was requested has a microphone or not. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, PROP_IS_FOR_AUDIO_DEVICE, + g_param_spec_boolean("is-for-audio-device", _("Is for audio device"), + _("Whether the media device to which the permission was requested has a microphone or not."), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitUserPermissionRequest:is-for-video-device: + * + * Whether the media device to which the permission was requested has a video capture capability or not. + * + * Since: 2.8 + */ + g_object_class_install_property(objectClass, PROP_IS_FOR_VIDEO_DEVICE, + g_param_spec_boolean("is-for-video-device", _("Is for video device"), + _("Whether the media device to which the permission was requested has a video capture capability or not."), + FALSE, + WEBKIT_PARAM_READABLE)); +} + +WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(UserMediaPermissionRequestProxy& request, API::SecurityOrigin& userMediaDocumentOrigin, API::SecurityOrigin& topLevelDocumentOrigin) +{ + WebKitUserMediaPermissionRequest* usermediaPermissionRequest = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(g_object_new(WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, nullptr)); + + // FIXME: store SecurityOrigins + UNUSED_PARAM(userMediaDocumentOrigin); + UNUSED_PARAM(topLevelDocumentOrigin); + + usermediaPermissionRequest->priv->request = &request; + return usermediaPermissionRequest; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h new file mode 100644 index 000000000..ad382b1ba --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequest.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitUserMediaPermissionRequest_h +#define WebKitUserMediaPermissionRequest_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST (webkit_user_media_permission_request_get_type()) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequest)) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequestClass)) +#define WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST)) +#define WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST)) +#define WEBKIT_USER_MEDIA_PERMISSION_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST, WebKitUserMediaPermissionRequestClass)) + +typedef struct _WebKitUserMediaPermissionRequest WebKitUserMediaPermissionRequest; +typedef struct _WebKitUserMediaPermissionRequestClass WebKitUserMediaPermissionRequestClass; +typedef struct _WebKitUserMediaPermissionRequestPrivate WebKitUserMediaPermissionRequestPrivate; + +struct _WebKitUserMediaPermissionRequest { + GObject parent; + + /*< private >*/ + WebKitUserMediaPermissionRequestPrivate *priv; +}; + +struct _WebKitUserMediaPermissionRequestClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_user_media_permission_request_get_type (void); + +WEBKIT_API gboolean +webkit_user_media_permission_is_for_audio_device (WebKitUserMediaPermissionRequest *request); + +WEBKIT_API gboolean +webkit_user_media_permission_is_for_video_device (WebKitUserMediaPermissionRequest *request); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h new file mode 100644 index 000000000..328a1616e --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitUserMediaPermissionRequestPrivate.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef WebKitUserMediaPermissionRequestPrivate_h +#define WebKitUserMediaPermissionRequestPrivate_h + +#include "WebKitPrivate.h" +#include "WebKitUserMediaPermissionRequest.h" + +class SecurityOrigin; + +WebKitUserMediaPermissionRequest* webkitUserMediaPermissionRequestCreate(WebKit::UserMediaPermissionRequestProxy&, API::SecurityOrigin&, API::SecurityOrigin&); + +#endif // WebKitUserMediaPermissionRequestPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in index b1c5af45d..1364bf602 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitVersion.h.in @@ -35,7 +35,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MAJOR_VERSION (@WEBKIT_MAJOR_VERSION@) +#define WEBKIT_MAJOR_VERSION (@PROJECT_VERSION_MAJOR@) /** * WEBKIT_MINOR_VERSION: @@ -44,7 +44,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MINOR_VERSION (@WEBKIT_MINOR_VERSION@) +#define WEBKIT_MINOR_VERSION (@PROJECT_VERSION_MINOR@) /** * WEBKIT_MICRO_VERSION: @@ -53,7 +53,7 @@ G_BEGIN_DECLS * application compile time, rather than from the library linked * against at application run time. */ -#define WEBKIT_MICRO_VERSION (@WEBKIT_MICRO_VERSION@) +#define WEBKIT_MICRO_VERSION (@PROJECT_VERSION_MICRO@) /** * WEBKIT_CHECK_VERSION: diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp index 1528324ba..e80255f4a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp @@ -20,39 +20,48 @@ #include "config.h" #include "WebKitWebContext.h" +#include "APICustomProtocolManagerClient.h" +#include "APIDownloadClient.h" +#include "APIPageConfiguration.h" +#include "APIProcessPoolConfiguration.h" #include "APIString.h" -#include "WebBatteryManagerProxy.h" +#include "TextChecker.h" +#include "TextCheckerState.h" #include "WebCertificateInfo.h" -#include "WebCookieManagerProxy.h" #include "WebGeolocationManagerProxy.h" -#include "WebKitBatteryProvider.h" -#include "WebKitCertificateInfoPrivate.h" -#include "WebKitCookieManagerPrivate.h" +#include "WebKitCustomProtocolManagerClient.h" #include "WebKitDownloadClient.h" #include "WebKitDownloadPrivate.h" #include "WebKitFaviconDatabasePrivate.h" #include "WebKitGeolocationProvider.h" #include "WebKitInjectedBundleClient.h" +#include "WebKitNetworkProxySettingsPrivate.h" +#include "WebKitNotificationProvider.h" #include "WebKitPluginPrivate.h" #include "WebKitPrivate.h" -#include "WebKitRequestManagerClient.h" #include "WebKitSecurityManagerPrivate.h" -#include "WebKitTextChecker.h" +#include "WebKitSecurityOriginPrivate.h" +#include "WebKitSettingsPrivate.h" #include "WebKitURISchemeRequestPrivate.h" +#include "WebKitUserContentManagerPrivate.h" #include "WebKitWebContextPrivate.h" #include "WebKitWebViewBasePrivate.h" -#include "WebKitWebViewGroupPrivate.h" -#include "WebResourceCacheManagerProxy.h" +#include "WebKitWebViewPrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebNotificationManagerProxy.h" +#include "WebsiteDataType.h" #include <WebCore/FileSystem.h> #include <WebCore/IconDatabase.h> #include <WebCore/Language.h> +#include <glib/gi18n-lib.h> #include <libintl.h> +#include <memory> #include <wtf/HashMap.h> -#include <wtf/OwnPtr.h> +#include <wtf/NeverDestroyed.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -68,11 +77,9 @@ using namespace WebKit; * You can define the #WebKitCacheModel and #WebKitProcessModel with * webkit_web_context_set_cache_model() and * webkit_web_context_set_process_model(), depending on the needs of - * your application. You can access the #WebKitCookieManager or the - * #WebKitSecurityManager to specify the behaviour of your application - * regarding cookies and security, using - * webkit_web_context_get_cookie_manager() and - * webkit_web_context_get_security_manager() for that. + * your application. You can access the #WebKitSecurityManager to specify + * the behaviour of your application regarding security using + * webkit_web_context_get_security_manager(). * * It is also possible to change your preferred language or enable * spell checking, using webkit_web_context_set_preferred_languages(), @@ -82,23 +89,32 @@ using namespace WebKit; * You can use webkit_web_context_register_uri_scheme() to register * custom URI schemes, and manage several other settings. * + * TLS certificate validation failure is now treated as a transport + * error by default. To handle TLS failures differently, you can + * connect to #WebKitWebView::load-failed-with-tls-errors. + * Alternatively, you can use webkit_web_context_set_tls_errors_policy() + * to set the policy %WEBKIT_TLS_ERRORS_POLICY_IGNORE; however, this is + * not appropriate for Internet applications. + * */ enum { + PROP_0, + + PROP_LOCAL_STORAGE_DIRECTORY, + PROP_WEBSITE_DATA_MANAGER +}; + +enum { DOWNLOAD_STARTED, INITIALIZE_WEB_EXTENSIONS, + INITIALIZE_NOTIFICATION_PERMISSIONS, LAST_SIGNAL }; class WebKitURISchemeHandler: public RefCounted<WebKitURISchemeHandler> { public: - WebKitURISchemeHandler() - : m_callback(0) - , m_userData(0) - , m_destroyNotify(0) - { - } WebKitURISchemeHandler(WebKitURISchemeRequestCallback callback, void* userData, GDestroyNotify destroyNotify) : m_callback(callback) , m_userData(userData) @@ -125,50 +141,221 @@ public: } private: - WebKitURISchemeRequestCallback m_callback; - void* m_userData; - GDestroyNotify m_destroyNotify; + WebKitURISchemeRequestCallback m_callback { nullptr }; + void* m_userData { nullptr }; + GDestroyNotify m_destroyNotify { nullptr }; }; typedef HashMap<String, RefPtr<WebKitURISchemeHandler> > URISchemeHandlerMap; typedef HashMap<uint64_t, GRefPtr<WebKitURISchemeRequest> > URISchemeRequestMap; struct _WebKitWebContextPrivate { - RefPtr<WebContext> context; + RefPtr<WebProcessPool> processPool; + bool clientsDetached; - GRefPtr<WebKitCookieManager> cookieManager; GRefPtr<WebKitFaviconDatabase> faviconDatabase; GRefPtr<WebKitSecurityManager> securityManager; - RefPtr<WebSoupCustomProtocolRequestManager> requestManager; URISchemeHandlerMap uriSchemeHandlers; URISchemeRequestMap uriSchemeRequests; #if ENABLE(GEOLOCATION) RefPtr<WebKitGeolocationProvider> geolocationProvider; #endif -#if ENABLE(BATTERY_STATUS) - RefPtr<WebKitBatteryProvider> batteryProvider; -#endif -#if ENABLE(SPELLCHECK) - OwnPtr<WebKitTextChecker> textChecker; +#if ENABLE(NOTIFICATIONS) + RefPtr<WebKitNotificationProvider> notificationProvider; #endif + GRefPtr<WebKitWebsiteDataManager> websiteDataManager; + CString faviconDatabaseDirectory; WebKitTLSErrorsPolicy tlsErrorsPolicy; + WebKitProcessModel processModel; + unsigned processCountLimit; HashMap<uint64_t, WebKitWebView*> webViews; - GRefPtr<WebKitWebViewGroup> defaultWebViewGroup; + unsigned ephemeralPageCount; CString webExtensionsDirectory; GRefPtr<GVariant> webExtensionsInitializationUserData; + + CString localStorageDirectory; }; static guint signals[LAST_SIGNAL] = { 0, }; WEBKIT_DEFINE_TYPE(WebKitWebContext, webkit_web_context, G_TYPE_OBJECT) +static const char* injectedBundleDirectory() +{ +#if ENABLE(DEVELOPER_MODE) + const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH"); + if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR)) + return bundleDirectory; +#endif + + static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING + G_DIR_SEPARATOR_S "injected-bundle" G_DIR_SEPARATOR_S; + return injectedBundlePath; +} + +static void webkitWebContextGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec) +{ + WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); + + switch (propID) { + case PROP_LOCAL_STORAGE_DIRECTORY: + g_value_set_string(value, context->priv->localStorageDirectory.data()); + break; + case PROP_WEBSITE_DATA_MANAGER: + g_value_set_object(value, webkit_web_context_get_website_data_manager(context)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebContextSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitWebContext* context = WEBKIT_WEB_CONTEXT(object); + + switch (propID) { + case PROP_LOCAL_STORAGE_DIRECTORY: + context->priv->localStorageDirectory = g_value_get_string(value); + break; + case PROP_WEBSITE_DATA_MANAGER: { + gpointer manager = g_value_get_object(value); + context->priv->websiteDataManager = manager ? WEBKIT_WEBSITE_DATA_MANAGER(manager) : nullptr; + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static inline WebsiteDataStore::Configuration websiteDataStoreConfigurationForWebProcessPoolConfiguration(const API::ProcessPoolConfiguration& processPoolconfigurarion) +{ + WebsiteDataStore::Configuration configuration; + configuration.applicationCacheDirectory = processPoolconfigurarion.applicationCacheDirectory(); + configuration.networkCacheDirectory = processPoolconfigurarion.diskCacheDirectory(); + configuration.webSQLDatabaseDirectory = processPoolconfigurarion.webSQLDatabaseDirectory(); + configuration.localStorageDirectory = processPoolconfigurarion.localStorageDirectory(); + configuration.mediaKeysStorageDirectory = processPoolconfigurarion.mediaKeysStorageDirectory(); + return configuration; +} + +static void webkitWebContextConstructed(GObject* object) +{ + G_OBJECT_CLASS(webkit_web_context_parent_class)->constructed(object); + + GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory(), "libwebkit2gtkinjectedbundle.so", nullptr)); + + API::ProcessPoolConfiguration configuration; + configuration.setInjectedBundlePath(WebCore::stringFromFileSystemRepresentation(bundleFilename.get())); + configuration.setMaximumProcessCount(1); + configuration.setDiskCacheSpeculativeValidationEnabled(true); + + WebKitWebContext* webContext = WEBKIT_WEB_CONTEXT(object); + WebKitWebContextPrivate* priv = webContext->priv; + if (priv->websiteDataManager && !webkit_website_data_manager_is_ephemeral(priv->websiteDataManager.get())) { + configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_local_storage_directory(priv->websiteDataManager.get()))); + configuration.setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_disk_cache_directory(priv->websiteDataManager.get())), networkCacheSubdirectory)); + configuration.setApplicationCacheDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_offline_application_cache_directory(priv->websiteDataManager.get()))); + configuration.setIndexedDBDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_indexeddb_directory(priv->websiteDataManager.get()))); + configuration.setWebSQLDatabaseDirectory(WebCore::stringFromFileSystemRepresentation(webkit_website_data_manager_get_websql_directory(priv->websiteDataManager.get()))); + } else if (!priv->localStorageDirectory.isNull()) + configuration.setLocalStorageDirectory(WebCore::stringFromFileSystemRepresentation(priv->localStorageDirectory.data())); + + priv->processPool = WebProcessPool::create(configuration); + + if (!priv->websiteDataManager) + priv->websiteDataManager = adoptGRef(webkitWebsiteDataManagerCreate(websiteDataStoreConfigurationForWebProcessPoolConfiguration(configuration))); + + webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), *priv->processPool); + + priv->tlsErrorsPolicy = WEBKIT_TLS_ERRORS_POLICY_FAIL; + priv->processPool->setIgnoreTLSErrors(false); + +#if ENABLE(MEMORY_SAMPLER) + if (getenv("WEBKIT_SAMPLE_MEMORY")) + priv->processPool->startMemorySampler(0); +#endif + + attachInjectedBundleClientToContext(webContext); + attachDownloadClientToContext(webContext); + attachCustomProtocolManagerClientToContext(webContext); + +#if ENABLE(GEOLOCATION) + priv->geolocationProvider = WebKitGeolocationProvider::create(priv->processPool->supplement<WebGeolocationManagerProxy>()); +#endif +#if ENABLE(NOTIFICATIONS) + priv->notificationProvider = WebKitNotificationProvider::create(priv->processPool->supplement<WebNotificationManagerProxy>(), webContext); +#endif +} + +static void webkitWebContextDispose(GObject* object) +{ + WebKitWebContextPrivate* priv = WEBKIT_WEB_CONTEXT(object)->priv; + if (!priv->clientsDetached) { + priv->clientsDetached = true; + priv->processPool->initializeInjectedBundleClient(nullptr); + priv->processPool->setDownloadClient(nullptr); + priv->processPool->setCustomProtocolManagerClient(nullptr); + } + + if (priv->websiteDataManager) { + webkitWebsiteDataManagerRemoveProcessPool(priv->websiteDataManager.get(), *priv->processPool); + priv->websiteDataManager = nullptr; + } + + G_OBJECT_CLASS(webkit_web_context_parent_class)->dispose(object); +} + static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass) { GObjectClass* gObjectClass = G_OBJECT_CLASS(webContextClass); + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + gObjectClass->get_property = webkitWebContextGetProperty; + gObjectClass->set_property = webkitWebContextSetProperty; + gObjectClass->constructed = webkitWebContextConstructed; + gObjectClass->dispose = webkitWebContextDispose; + + /** + * WebKitWebContext:local-storage-directory: + * + * The directory where local storage data will be saved. + * + * Since: 2.8 + * + * Deprecated: 2.10. Use #WebKitWebsiteDataManager:local-storage-directory instead. + */ + g_object_class_install_property( + gObjectClass, + PROP_LOCAL_STORAGE_DIRECTORY, + g_param_spec_string( + "local-storage-directory", + _("Local Storage Directory"), + _("The directory where local storage data will be saved"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebContext:website-data-manager: + * + * The #WebKitWebsiteDataManager associated with this context. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_WEBSITE_DATA_MANAGER, + g_param_spec_object( + "website-data-manager", + _("Website Data Manager"), + _("The WebKitWebsiteDataManager associated with this context"), + WEBKIT_TYPE_WEBSITE_DATA_MANAGER, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + /** * WebKitWebContext::download-started: * @context: the #WebKitWebContext @@ -178,12 +365,13 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass */ signals[DOWNLOAD_STARTED] = g_signal_new("download-started", - G_TYPE_FROM_CLASS(gObjectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - WEBKIT_TYPE_DOWNLOAD); + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebContextClass, download_started), + nullptr, nullptr, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + WEBKIT_TYPE_DOWNLOAD); /** * WebKitWebContext::initialize-web-extensions: @@ -200,68 +388,138 @@ static void webkit_web_context_class_init(WebKitWebContextClass* webContextClass g_signal_new("initialize-web-extensions", G_TYPE_FROM_CLASS(gObjectClass), G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, + G_STRUCT_OFFSET(WebKitWebContextClass, initialize_web_extensions), + nullptr, nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitWebContext::initialize-notification-permissions: + * @context: the #WebKitWebContext + * + * This signal is emitted when a #WebKitWebContext needs to set + * initial notification permissions for a web process. It is emitted + * when a new web process is about to be launched, and signals the + * most appropriate moment to use + * webkit_web_context_initialize_notification_permissions(). If no + * notification permissions have changed since the last time this + * signal was emitted, then there is no need to call + * webkit_web_context_initialize_notification_permissions() again. + * + * Since: 2.16 + */ + signals[INITIALIZE_NOTIFICATION_PERMISSIONS] = + g_signal_new("initialize-notification-permissions", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebContextClass, initialize_notification_permissions), + nullptr, nullptr, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } -static CString injectedBundleDirectory() +static gpointer createDefaultWebContext(gpointer) { - const char* bundleDirectory = g_getenv("WEBKIT_INJECTED_BUNDLE_PATH"); - if (bundleDirectory && g_file_test(bundleDirectory, G_FILE_TEST_IS_DIR)) - return bundleDirectory; + static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr))); + return webContext.get(); +} - static const char* injectedBundlePath = LIBDIR G_DIR_SEPARATOR_S "webkit2gtk-" WEBKITGTK_API_VERSION_STRING - G_DIR_SEPARATOR_S "injected-bundle" G_DIR_SEPARATOR_S; - return injectedBundlePath; +/** + * webkit_web_context_get_default: + * + * Gets the default web context + * + * Returns: (transfer none): a #WebKitWebContext + */ +WebKitWebContext* webkit_web_context_get_default(void) +{ + static GOnce onceInit = G_ONCE_INIT; + return WEBKIT_WEB_CONTEXT(g_once(&onceInit, createDefaultWebContext, 0)); } -static CString injectedBundleFilename() +/** + * webkit_web_context_new: + * + * Create a new #WebKitWebContext + * + * Returns: (transfer full): a newly created #WebKitWebContext + * + * Since: 2.8 + */ +WebKitWebContext* webkit_web_context_new(void) { - GUniquePtr<char> bundleFilename(g_build_filename(injectedBundleDirectory().data(), "libwebkit2gtkinjectedbundle.so", NULL)); - return bundleFilename.get(); + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, nullptr)); } -static gpointer createDefaultWebContext(gpointer) +/** + * webkit_web_context_new_ephemeral: + * + * Create a new ephemeral #WebKitWebContext. An ephemeral #WebKitWebContext is a context + * created with an ephemeral #WebKitWebsiteDataManager. This is just a convenient method + * to create ephemeral contexts without having to create your own #WebKitWebsiteDataManager. + * All #WebKitWebView<!-- -->s associated with this context will also be ephemeral. Websites will + * not store any data in the client storage. + * This is normally used to implement private instances. + * + * Returns: (transfer full): a new ephemeral #WebKitWebContext. + * + * Since: 2.16 + */ +WebKitWebContext* webkit_web_context_new_ephemeral() { - bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); - bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + GRefPtr<WebKitWebsiteDataManager> manager = adoptGRef(webkit_website_data_manager_new_ephemeral()); + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager.get(), nullptr)); +} - static GRefPtr<WebKitWebContext> webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, NULL))); - WebKitWebContextPrivate* priv = webContext->priv; +/** + * webkit_web_context_new_with_website_data_manager: + * @manager: a #WebKitWebsiteDataManager + * + * Create a new #WebKitWebContext with a #WebKitWebsiteDataManager. + * + * Returns: (transfer full): a newly created #WebKitWebContext + * + * Since: 2.10 + */ +WebKitWebContext* webkit_web_context_new_with_website_data_manager(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); - priv->context = WebContext::create(WebCore::filenameToString(injectedBundleFilename().data())); - priv->requestManager = webContext->priv->context->supplement<WebSoupCustomProtocolRequestManager>(); - priv->context->setCacheModel(CacheModelPrimaryWebBrowser); - priv->tlsErrorsPolicy = WEBKIT_TLS_ERRORS_POLICY_IGNORE; + return WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, nullptr)); +} - attachInjectedBundleClientToContext(webContext.get()); - attachDownloadClientToContext(webContext.get()); - attachRequestManagerClientToContext(webContext.get()); +/** + * webkit_web_context_get_website_data_manager: + * @context: the #WebKitWebContext + * + * Get the #WebKitWebsiteDataManager of @context. + * + * Returns: (transfer none): a #WebKitWebsiteDataManager + * + * Since: 2.10 + */ +WebKitWebsiteDataManager* webkit_web_context_get_website_data_manager(WebKitWebContext* context) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); -#if ENABLE(GEOLOCATION) - priv->geolocationProvider = WebKitGeolocationProvider::create(priv->context->supplement<WebGeolocationManagerProxy>()); -#endif -#if ENABLE(BATTERY_STATUS) - priv->batteryProvider = WebKitBatteryProvider::create(priv->context->supplement<WebBatteryManagerProxy>()); -#endif -#if ENABLE(SPELLCHECK) - priv->textChecker = WebKitTextChecker::create(); -#endif - return webContext.get(); + return context->priv->websiteDataManager.get(); } /** - * webkit_web_context_get_default: + * webkit_web_context_is_ephemeral: + * @context: the #WebKitWebContext * - * Gets the default web context + * Get whether a #WebKitWebContext is ephemeral. * - * Returns: (transfer none): a #WebKitWebContext + * Returns: %TRUE if @context is ephemeral or %FALSE otherwise. + * + * Since: 2.16 */ -WebKitWebContext* webkit_web_context_get_default(void) +gboolean webkit_web_context_is_ephemeral(WebKitWebContext* context) { - static GOnce onceInit = G_ONCE_INIT; - return WEBKIT_WEB_CONTEXT(g_once(&onceInit, createDefaultWebContext, 0)); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); + + return webkit_website_data_manager_is_ephemeral(context->priv->websiteDataManager.get()); } /** @@ -308,8 +566,8 @@ void webkit_web_context_set_cache_model(WebKitWebContext* context, WebKitCacheMo g_assert_not_reached(); } - if (cacheModel != context->priv->context->cacheModel()) - context->priv->context->setCacheModel(cacheModel); + if (cacheModel != context->priv->processPool->cacheModel()) + context->priv->processPool->setCacheModel(cacheModel); } /** @@ -326,7 +584,7 @@ WebKitCacheModel webkit_web_context_get_cache_model(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_CACHE_MODEL_WEB_BROWSER); - switch (context->priv->context->cacheModel()) { + switch (context->priv->processPool->cacheModel()) { case CacheModelDocumentViewer: return WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER; case CacheModelPrimaryWebBrowser: @@ -351,14 +609,59 @@ void webkit_web_context_clear_cache(WebKitWebContext* context) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - context->priv->context->supplement<WebResourceCacheManagerProxy>()->clearCacheForAllOrigins(AllResourceCaches); + OptionSet<WebsiteDataType> websiteDataTypes; + websiteDataTypes |= WebsiteDataType::MemoryCache; + websiteDataTypes |= WebsiteDataType::DiskCache; + auto& websiteDataStore = webkitWebsiteDataManagerGetDataStore(context->priv->websiteDataManager.get()).websiteDataStore(); + websiteDataStore.removeData(websiteDataTypes, std::chrono::system_clock::time_point::min(), [] { }); +} + +/** + * webkit_web_context_set_network_proxy_settings: + * @context: a #WebKitWebContext + * @proxy_mode: a #WebKitNetworkProxyMode + * @proxy_settings: (allow-none): a #WebKitNetworkProxySettings, or %NULL + * + * Set the network proxy settings to be used by connections started in @context. + * By default %WEBKIT_NETWORK_PROXY_MODE_DEFAULT is used, which means that the + * system settings will be used (g_proxy_resolver_get_default()). + * If you want to override the system default settings, you can either use + * %WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to make sure no proxies are used at all, + * or %WEBKIT_NETWORK_PROXY_MODE_CUSTOM to provide your own proxy settings. + * When @proxy_mode is %WEBKIT_NETWORK_PROXY_MODE_CUSTOM @proxy_settings must be + * a valid #WebKitNetworkProxySettings; otherwise, @proxy_settings must be %NULL. + * + * Since: 2.16 + */ +void webkit_web_context_set_network_proxy_settings(WebKitWebContext* context, WebKitNetworkProxyMode proxyMode, WebKitNetworkProxySettings* proxySettings) +{ + g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); + g_return_if_fail((proxyMode != WEBKIT_NETWORK_PROXY_MODE_CUSTOM && !proxySettings) || (proxyMode == WEBKIT_NETWORK_PROXY_MODE_CUSTOM && proxySettings)); + + WebKitWebContextPrivate* priv = context->priv; + switch (proxyMode) { + case WEBKIT_NETWORK_PROXY_MODE_DEFAULT: + priv->processPool->setNetworkProxySettings({ }); + break; + case WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: + priv->processPool->setNetworkProxySettings(WebCore::SoupNetworkProxySettings(WebCore::SoupNetworkProxySettings::Mode::NoProxy)); + break; + case WEBKIT_NETWORK_PROXY_MODE_CUSTOM: + const auto& settings = webkitNetworkProxySettingsGetNetworkProxySettings(proxySettings); + if (settings.isEmpty()) { + g_warning("Invalid attempt to set custom network proxy settings with an empty WebKitNetworkProxySettings. Use " + "WEBKIT_NETWORK_PROXY_MODE_NO_PROXY to not use any proxy or WEBKIT_NETWORK_PROXY_MODE_DEFAULT to use the default system settings"); + } else + priv->processPool->setNetworkProxySettings(settings); + break; + } } typedef HashMap<DownloadProxy*, GRefPtr<WebKitDownload> > DownloadsMap; static DownloadsMap& downloadsMap() { - DEFINE_STATIC_LOCAL(DownloadsMap, downloads, ()); + static NeverDestroyed<DownloadsMap> downloads; return downloads; } @@ -377,29 +680,26 @@ static DownloadsMap& downloadsMap() */ WebKitDownload* webkit_web_context_download_uri(WebKitWebContext* context, const gchar* uri) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); - g_return_val_if_fail(uri, 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); + g_return_val_if_fail(uri, nullptr); - return webkitWebContextStartDownload(context, uri, 0); + GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(context, uri, nullptr); + return download.leakRef(); } /** * webkit_web_context_get_cookie_manager: * @context: a #WebKitWebContext * - * Get the #WebKitCookieManager of @context. + * Get the #WebKitCookieManager of the @context's #WebKitWebsiteDataManager. * * Returns: (transfer none): the #WebKitCookieManager of @context. */ WebKitCookieManager* webkit_web_context_get_cookie_manager(WebKitWebContext* context) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); - WebKitWebContextPrivate* priv = context->priv; - if (!priv->cookieManager) - priv->cookieManager = adoptGRef(webkitCookieManagerCreate(priv->context->supplement<WebCookieManagerProxy>())); - - return priv->cookieManager.get(); + return webkit_website_data_manager_get_cookie_manager(context->priv->websiteDataManager.get()); } static void ensureFaviconDatabase(WebKitWebContext* context) @@ -408,7 +708,32 @@ static void ensureFaviconDatabase(WebKitWebContext* context) if (priv->faviconDatabase) return; - priv->faviconDatabase = adoptGRef(webkitFaviconDatabaseCreate(priv->context->iconDatabase())); + priv->faviconDatabase = adoptGRef(webkitFaviconDatabaseCreate(priv->processPool->iconDatabase())); +} + +static void webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) +{ + if (webkit_web_context_is_ephemeral(context)) + return; + if (!webkit_web_view_is_ephemeral(webView)) + return; + + if (!context->priv->ephemeralPageCount) + context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); + context->priv->ephemeralPageCount++; +} + +static void webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(WebKitWebContext* context, WebKitWebView* webView) +{ + if (webkit_web_context_is_ephemeral(context)) + return; + if (!webkit_web_view_is_ephemeral(webView)) + return; + + ASSERT(context->priv->ephemeralPageCount); + context->priv->ephemeralPageCount--; + if (!context->priv->ephemeralPageCount) + context->priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(false); } /** @@ -431,16 +756,16 @@ void webkit_web_context_set_favicon_database_directory(WebKitWebContext* context g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); WebKitWebContextPrivate* priv = context->priv; - WebIconDatabase* iconDatabase = priv->context->iconDatabase(); + WebIconDatabase* iconDatabase = priv->processPool->iconDatabase(); if (iconDatabase->isOpen()) return; ensureFaviconDatabase(context); // Use default if 0 is passed as parameter. - String directoryPath = WebCore::filenameToString(path); + String directoryPath = WebCore::stringFromFileSystemRepresentation(path); priv->faviconDatabaseDirectory = directoryPath.isEmpty() - ? priv->context->iconDatabasePath().utf8() + ? priv->processPool->iconDatabasePath().utf8() : directoryPath.utf8(); // Build the full path to the icon database file on disk. @@ -448,7 +773,10 @@ void webkit_web_context_set_favicon_database_directory(WebKitWebContext* context WebCore::IconDatabase::defaultDatabaseFilename().utf8().data(), nullptr)); // Setting the path will cause the icon database to be opened. - priv->context->setIconDatabasePath(WebCore::filenameToString(faviconDatabasePath.get())); + priv->processPool->setIconDatabasePath(WebCore::stringFromFileSystemRepresentation(faviconDatabasePath.get())); + + if (webkit_web_context_is_ephemeral(context)) + priv->processPool->iconDatabase()->setPrivateBrowsingEnabled(true); } /** @@ -528,7 +856,9 @@ void webkit_web_context_set_additional_plugins_directory(WebKitWebContext* conte g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); - context->priv->context->setAdditionalPluginsDirectory(WebCore::filenameToString(directory)); +#if ENABLE(NETSCAPE_PLUGIN_API) + context->priv->processPool->setAdditionalPluginsDirectory(WebCore::stringFromFileSystemRepresentation(directory)); +#endif } static void destroyPluginList(GList* plugins) @@ -536,12 +866,14 @@ static void destroyPluginList(GList* plugins) g_list_free_full(plugins, g_object_unref); } -static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer taskData, GCancellable*) +static void webkitWebContextGetPluginThread(GTask* task, gpointer object, gpointer /* taskData */, GCancellable*) { - Vector<PluginModuleInfo> plugins = WEBKIT_WEB_CONTEXT(object)->priv->context->pluginInfoStore().plugins(); GList* returnValue = 0; +#if ENABLE(NETSCAPE_PLUGIN_API) + Vector<PluginModuleInfo> plugins = WEBKIT_WEB_CONTEXT(object)->priv->processPool->pluginInfoStore().plugins(); for (size_t i = 0; i < plugins.size(); ++i) returnValue = g_list_prepend(returnValue, webkitPluginCreate(plugins[i])); +#endif g_task_return_pointer(task, returnValue, reinterpret_cast<GDestroyNotify>(destroyPluginList)); } @@ -642,8 +974,9 @@ void webkit_web_context_register_uri_scheme(WebKitWebContext* context, const cha g_return_if_fail(callback); RefPtr<WebKitURISchemeHandler> handler = adoptRef(new WebKitURISchemeHandler(callback, userData, destroyNotify)); - context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), handler.get()); - context->priv->requestManager->registerSchemeForCustomProtocol(String::fromUTF8(scheme)); + auto addResult = context->priv->uriSchemeHandlers.set(String::fromUTF8(scheme), handler.get()); + if (addResult.isNewEntry) + context->priv->processPool->registerSchemeForCustomProtocol(String::fromUTF8(scheme)); } /** @@ -659,7 +992,7 @@ gboolean webkit_web_context_get_spell_checking_enabled(WebKitWebContext* context g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), FALSE); #if ENABLE(SPELLCHECK) - return context->priv->textChecker->isSpellCheckingEnabled(); + return TextChecker::state().isContinuousSpellCheckingEnabled; #else return false; #endif @@ -677,7 +1010,7 @@ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gb g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); #if ENABLE(SPELLCHECK) - context->priv->textChecker->setSpellCheckingEnabled(enabled); + TextChecker::setContinuousSpellCheckingEnabled(enabled); #endif } @@ -696,10 +1029,20 @@ void webkit_web_context_set_spell_checking_enabled(WebKitWebContext* context, gb */ const gchar* const* webkit_web_context_get_spell_checking_languages(WebKitWebContext* context) { - g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr); #if ENABLE(SPELLCHECK) - return context->priv->textChecker->getSpellCheckingLanguages(); + Vector<String> spellCheckingLanguages = TextChecker::loadedSpellCheckingLanguages(); + if (spellCheckingLanguages.isEmpty()) + return nullptr; + + static GRefPtr<GPtrArray> languagesToReturn; + languagesToReturn = adoptGRef(g_ptr_array_new_with_free_func(g_free)); + for (const auto& language : spellCheckingLanguages) + g_ptr_array_add(languagesToReturn.get(), g_strdup(language.utf8().data())); + g_ptr_array_add(languagesToReturn.get(), nullptr); + + return reinterpret_cast<char**>(languagesToReturn->pdata); #else return 0; #endif @@ -728,7 +1071,10 @@ void webkit_web_context_set_spell_checking_languages(WebKitWebContext* context, g_return_if_fail(languages); #if ENABLE(SPELLCHECK) - context->priv->textChecker->setSpellCheckingLanguages(languages); + Vector<String> spellCheckingLanguages; + for (size_t i = 0; languages[i]; ++i) + spellCheckingLanguages.append(String::fromUTF8(languages[i])); + TextChecker::setSpellCheckingLanguages(spellCheckingLanguages); #endif } @@ -750,11 +1096,14 @@ void webkit_web_context_set_preferred_languages(WebKitWebContext* context, const return; Vector<String> languages; - for (size_t i = 0; languageList[i]; ++i) - languages.append(String::fromUTF8(languageList[i]).lower().replace("_", "-")); - + for (size_t i = 0; languageList[i]; ++i) { + // Do not propagate the C locale to WebCore. + if (!g_ascii_strcasecmp(languageList[i], "C") || !g_ascii_strcasecmp(languageList[i], "POSIX")) + languages.append(ASCIILiteral("en-us")); + else + languages.append(String::fromUTF8(languageList[i]).convertToASCIILowercase().replace("_", "-")); + } WebCore::overrideUserPreferredLanguages(languages); - WebCore::languageDidChange(); } /** @@ -773,8 +1122,8 @@ void webkit_web_context_set_tls_errors_policy(WebKitWebContext* context, WebKitT context->priv->tlsErrorsPolicy = policy; bool ignoreTLSErrors = policy == WEBKIT_TLS_ERRORS_POLICY_IGNORE; - if (context->priv->context->ignoreTLSErrors() != ignoreTLSErrors) - context->priv->context->setIgnoreTLSErrors(ignoreTLSErrors); + if (context->priv->processPool->ignoreTLSErrors() != ignoreTLSErrors) + context->priv->processPool->setIgnoreTLSErrors(ignoreTLSErrors); } /** @@ -842,13 +1191,19 @@ void webkit_web_context_set_web_extensions_initialization_user_data(WebKitWebCon * Set the directory where disk cache files will be stored * This method must be called before loading anything in this context, otherwise * it will not have any effect. + * + * Note that this method overrides the directory set in the #WebKitWebsiteDataManager, + * but it doesn't change the value returned by webkit_website_data_manager_get_disk_cache_directory() + * since the #WebKitWebsiteDataManager is immutable. + * + * Deprecated: 2.10. Use webkit_web_context_new_with_website_data_manager() instead. */ void webkit_web_context_set_disk_cache_directory(WebKitWebContext* context, const char* directory) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(directory); - context->priv->context->setDiskCacheDirectory(WebCore::filenameToString(directory)); + context->priv->processPool->configuration().setDiskCacheDirectory(WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(directory), networkCacheSubdirectory)); } /** @@ -864,29 +1219,29 @@ void webkit_web_context_prefetch_dns(WebKitWebContext* context, const char* host g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); g_return_if_fail(hostname); - ImmutableDictionary::MapType message; + API::Dictionary::MapType message; message.set(String::fromUTF8("Hostname"), API::String::create(String::fromUTF8(hostname))); - context->priv->context->postMessageToInjectedBundle(String::fromUTF8("PrefetchDNS"), ImmutableDictionary::create(std::move(message)).get()); + context->priv->processPool->postMessageToInjectedBundle(String::fromUTF8("PrefetchDNS"), API::Dictionary::create(WTFMove(message)).ptr()); } /** * webkit_web_context_allow_tls_certificate_for_host: * @context: a #WebKitWebContext - * @info: a #WebKitCertificateInfo + * @certificate: a #GTlsCertificate * @host: the host for which a certificate is to be allowed * * Ignore further TLS errors on the @host for the certificate present in @info. * - * Since: 2.4 + * Since: 2.6 */ -void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context, WebKitCertificateInfo* info, const gchar* host) +void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context, GTlsCertificate* certificate, const gchar* host) { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - g_return_if_fail(info); + g_return_if_fail(G_IS_TLS_CERTIFICATE(certificate)); g_return_if_fail(host); - RefPtr<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(webkitCertificateInfoGetCertificateInfo(info)); - context->priv->context->allowSpecificHTTPSCertificateForHost(webCertificateInfo.get(), String::fromUTF8(host)); + RefPtr<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(WebCore::CertificateInfo(certificate, static_cast<GTlsCertificateFlags>(0))); + context->priv->processPool->allowSpecificHTTPSCertificateForHost(webCertificateInfo.get(), String::fromUTF8(host)); } /** @@ -910,7 +1265,7 @@ void webkit_web_context_allow_tls_certificate_for_host(WebKitWebContext* context * the rest of the WebViews in the application will still function * normally. * - * This method **must be called before any other functions**, + * This method **must be called before any web process has been created**, * as early as possible in your application. Calling it later will make * your application crash. * @@ -920,24 +1275,18 @@ void webkit_web_context_set_process_model(WebKitWebContext* context, WebKitProce { g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); - ProcessModel newProcessModel; + if (processModel == context->priv->processModel) + return; - switch (processModel) { + context->priv->processModel = processModel; + switch (context->priv->processModel) { case WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS: - newProcessModel = ProcessModelSharedSecondaryProcess; + context->priv->processPool->setMaximumNumberOfProcesses(1); break; case WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES: - newProcessModel = ProcessModelMultipleSecondaryProcesses; + context->priv->processPool->setMaximumNumberOfProcesses(context->priv->processCountLimit); break; - default: - g_assert_not_reached(); } - - if (newProcessModel == context->priv->context->processModel()) - return; - - context->priv->context->setUsesNetworkProcess(newProcessModel == ProcessModelMultipleSecondaryProcesses); - context->priv->context->setProcessModel(newProcessModel); } /** @@ -955,14 +1304,98 @@ WebKitProcessModel webkit_web_context_get_process_model(WebKitWebContext* contex { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS); - switch (context->priv->context->processModel()) { - case ProcessModelSharedSecondaryProcess: - return WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS; - case ProcessModelMultipleSecondaryProcesses: - return WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES; - default: - g_assert_not_reached(); - } + return context->priv->processModel; +} + +/** + * webkit_web_context_set_web_process_count_limit: + * @context: the #WebKitWebContext + * @limit: the maximum number of web processes + * + * Sets the maximum number of web processes that can be created at the same time for the @context. + * The default value is 0 and means no limit. + * + * This method **must be called before any web process has been created**, + * as early as possible in your application. Calling it later will make + * your application crash. + * + * Since: 2.10 + */ +void webkit_web_context_set_web_process_count_limit(WebKitWebContext* context, guint limit) +{ + g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context)); + + if (context->priv->processCountLimit == limit) + return; + + context->priv->processCountLimit = limit; + if (context->priv->processModel != WEBKIT_PROCESS_MODEL_SHARED_SECONDARY_PROCESS) + context->priv->processPool->setMaximumNumberOfProcesses(limit); +} + +/** + * webkit_web_context_get_web_process_count_limit: + * @context: the #WebKitWebContext + * + * Gets the maximum number of web processes that can be created at the same time for the @context. + * + * Returns: the maximum limit of web processes, or 0 if there isn't a limit. + * + * Since: 2.10 + */ +guint webkit_web_context_get_web_process_count_limit(WebKitWebContext* context) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); + + return context->priv->processCountLimit; +} + +static void addOriginToMap(WebKitSecurityOrigin* origin, HashMap<String, RefPtr<API::Object>>* map, bool allowed) +{ + String string = webkitSecurityOriginGetSecurityOrigin(origin).toString(); + if (string != "null") + map->set(string, API::Boolean::create(allowed)); +} + +/** + * webkit_web_context_initialize_notification_permissions: + * @context: the #WebKitWebContext + * @allowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins + * @disallowed_origins: (element-type WebKitSecurityOrigin): a #GList of security origins + * + * Sets initial desktop notification permissions for the @context. + * @allowed_origins and @disallowed_origins must each be #GList of + * #WebKitSecurityOrigin objects representing origins that will, + * respectively, either always or never have permission to show desktop + * notifications. No #WebKitNotificationPermissionRequest will ever be + * generated for any of the security origins represented in + * @allowed_origins or @disallowed_origins. This function is necessary + * because some webpages proactively check whether they have permission + * to display notifications without ever creating a permission request. + * + * This function only affects web processes that have not already been + * created. The best time to call it is when handling + * #WebKitWebContext::initialize-notification-permissions so as to + * ensure that new web processes receive the most recent set of + * permissions. + * + * Since: 2.16 + */ +void webkit_web_context_initialize_notification_permissions(WebKitWebContext* context, GList* allowedOrigins, GList* disallowedOrigins) +{ + HashMap<String, RefPtr<API::Object>> map; + g_list_foreach(allowedOrigins, [](gpointer data, gpointer userData) { + addOriginToMap(static_cast<WebKitSecurityOrigin*>(data), static_cast<HashMap<String, RefPtr<API::Object>>*>(userData), true); + }, &map); + g_list_foreach(disallowedOrigins, [](gpointer data, gpointer userData) { + addOriginToMap(static_cast<WebKitSecurityOrigin*>(data), static_cast<HashMap<String, RefPtr<API::Object>>*>(userData), false); + }, &map); + context->priv->notificationProvider->setNotificationPermissions(WTFMove(map)); +} + +void webkitWebContextInitializeNotificationPermissions(WebKitWebContext* context) +{ + g_signal_emit(context, signals[INITIALIZE_NOTIFICATION_PERMISSIONS], 0); } WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy) @@ -979,10 +1412,7 @@ WebKitDownload* webkitWebContextGetOrCreateDownload(DownloadProxy* downloadProxy WebKitDownload* webkitWebContextStartDownload(WebKitWebContext* context, const char* uri, WebPageProxy* initiatingPage) { WebCore::ResourceRequest request(String::fromUTF8(uri)); - DownloadProxy* downloadProxy = context->priv->context->download(initiatingPage, request); - WebKitDownload* download = webkitDownloadCreateForRequest(downloadProxy, request); - downloadsMap().set(downloadProxy, download); - return download; + return webkitWebContextGetOrCreateDownload(context->priv->processPool->download(initiatingPage, request)); } void webkitWebContextRemoveDownload(DownloadProxy* downloadProxy) @@ -1003,21 +1433,16 @@ GVariant* webkitWebContextInitializeWebExtensions(WebKitWebContext* context) context->priv->webExtensionsInitializationUserData.get()); } -WebContext* webkitWebContextGetContext(WebKitWebContext* context) +WebProcessPool& webkitWebContextGetProcessPool(WebKitWebContext* context) { g_assert(WEBKIT_IS_WEB_CONTEXT(context)); - return context->priv->context.get(); -} - -WebSoupCustomProtocolRequestManager* webkitWebContextGetRequestManager(WebKitWebContext* context) -{ - return context->priv->requestManager.get(); + return *context->priv->processPool; } -void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID, API::URLRequest* urlRequest) +void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID, const WebCore::ResourceRequest& resourceRequest, CustomProtocolManagerProxy& manager) { - GRefPtr<WebKitURISchemeRequest> request = adoptGRef(webkitURISchemeRequestCreate(customProtocolID, context, urlRequest)); + GRefPtr<WebKitURISchemeRequest> request = adoptGRef(webkitURISchemeRequestCreate(customProtocolID, context, resourceRequest, manager)); String scheme(String::fromUTF8(webkit_uri_scheme_request_get_scheme(request.get()))); RefPtr<WebKitURISchemeHandler> handler = context->priv->uriSchemeHandlers.get(scheme); ASSERT(handler.get()); @@ -1036,27 +1461,54 @@ void webkitWebContextStopLoadingCustomProtocol(WebKitWebContext* context, uint64 webkitURISchemeRequestCancel(request.get()); } +void webkitWebContextInvalidateCustomProtocolRequests(WebKitWebContext* context, CustomProtocolManagerProxy& manager) +{ + Vector<GRefPtr<WebKitURISchemeRequest>> requests; + copyValuesToVector(context->priv->uriSchemeRequests, requests); + for (auto& request : requests) { + if (webkitURISchemeRequestGetManager(request.get()) == &manager) + webkitURISchemeRequestInvalidate(request.get()); + } +} + void webkitWebContextDidFinishLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) { context->priv->uriSchemeRequests.remove(customProtocolID); } -void webkitWebContextCreatePageForWebView(WebKitWebContext* context, WebKitWebView* webView, WebKitWebViewGroup* webViewGroup, WebKitWebView* relatedView) +bool webkitWebContextIsLoadingCustomProtocol(WebKitWebContext* context, uint64_t customProtocolID) +{ + return context->priv->uriSchemeRequests.get(customProtocolID); +} + +void webkitWebContextCreatePageForWebView(WebKitWebContext* context, WebKitWebView* webView, WebKitUserContentManager* userContentManager, WebKitWebView* relatedView) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView); - WebPageGroup* pageGroup = webViewGroup ? webkitWebViewGroupGetPageGroup(webViewGroup) : 0; - WebPageProxy* relatedPage = relatedView ? webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(relatedView)) : nullptr; - webkitWebViewBaseCreateWebPage(webViewBase, context->priv->context.get(), pageGroup, relatedPage); + + // FIXME: icon database private mode is global, not per page, so while there are + // pages in private mode we need to enable the private mode in the icon database. + webkitWebContextEnableIconDatabasePrivateBrowsingIfNeeded(context, webView); + + auto pageConfiguration = API::PageConfiguration::create(); + pageConfiguration->setProcessPool(context->priv->processPool.get()); + pageConfiguration->setPreferences(webkitSettingsGetPreferences(webkit_web_view_get_settings(webView))); + pageConfiguration->setRelatedPage(relatedView ? webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(relatedView)) : nullptr); + pageConfiguration->setUserContentController(userContentManager ? webkitUserContentManagerGetUserContentControllerProxy(userContentManager) : nullptr); + + WebKitWebsiteDataManager* manager = webkitWebViewGetWebsiteDataManager(webView); + if (!manager) + manager = context->priv->websiteDataManager.get(); + pageConfiguration->setWebsiteDataStore(&webkitWebsiteDataManagerGetDataStore(manager)); + pageConfiguration->setSessionID(pageConfiguration->websiteDataStore()->websiteDataStore().sessionID()); + webkitWebViewBaseCreateWebPage(webViewBase, WTFMove(pageConfiguration)); WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); context->priv->webViews.set(page->pageID(), webView); - - if (!pageGroup && !context->priv->defaultWebViewGroup) - context->priv->defaultWebViewGroup = adoptGRef(webkitWebViewGroupCreate(&page->pageGroup())); } void webkitWebContextWebViewDestroyed(WebKitWebContext* context, WebKitWebView* webView) { + webkitWebContextDisableIconDatabasePrivateBrowsingIfNeeded(context, webView); WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)); context->priv->webViews.remove(page->pageID()); } @@ -1065,8 +1517,3 @@ WebKitWebView* webkitWebContextGetWebViewForPage(WebKitWebContext* context, WebP { return page ? context->priv->webViews.get(page->pageID()) : 0; } - -WebKitWebViewGroup* webkitWebContextGetDefaultWebViewGroup(WebKitWebContext* context) -{ - return context->priv->defaultWebViewGroup.get(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h index 3ce281b9b..5ae166655 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.h @@ -25,13 +25,14 @@ #define WebKitWebContext_h #include <glib-object.h> -#include <webkit2/WebKitCertificateInfo.h> #include <webkit2/WebKitCookieManager.h> #include <webkit2/WebKitDefines.h> #include <webkit2/WebKitDownload.h> #include <webkit2/WebKitFaviconDatabase.h> +#include <webkit2/WebKitNetworkProxySettings.h> #include <webkit2/WebKitSecurityManager.h> #include <webkit2/WebKitURISchemeRequest.h> +#include <webkit2/WebKitWebsiteDataManager.h> G_BEGIN_DECLS @@ -104,6 +105,22 @@ typedef enum { } WebKitTLSErrorsPolicy; /** + * WebKitNetworkProxyMode: + * @WEBKIT_NETWORK_PROXY_MODE_DEFAULT: Use the default proxy of the system. + * @WEBKIT_NETWORK_PROXY_MODE_NO_PROXY: Do not use any proxy. + * @WEBKIT_NETWORK_PROXY_MODE_CUSTOM: Use custom proxy settings. + * + * Enum values used to set the network proxy mode. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_NETWORK_PROXY_MODE_DEFAULT, + WEBKIT_NETWORK_PROXY_MODE_NO_PROXY, + WEBKIT_NETWORK_PROXY_MODE_CUSTOM +} WebKitNetworkProxyMode; + +/** * WebKitURISchemeRequestCallback: * @request: the #WebKitURISchemeRequest * @user_data: user data passed to the callback @@ -128,14 +145,16 @@ struct _WebKitWebContext { struct _WebKitWebContextClass { GObjectClass parent; + void (* download_started) (WebKitWebContext *context, + WebKitDownload *download); + void (* initialize_web_extensions) (WebKitWebContext *context); + void (* initialize_notification_permissions) (WebKitWebContext *context); + void (*_webkit_reserved0) (void); void (*_webkit_reserved1) (void); void (*_webkit_reserved2) (void); void (*_webkit_reserved3) (void); void (*_webkit_reserved4) (void); - void (*_webkit_reserved5) (void); - void (*_webkit_reserved6) (void); - void (*_webkit_reserved7) (void); }; WEBKIT_API GType @@ -144,6 +163,21 @@ webkit_web_context_get_type (void); WEBKIT_API WebKitWebContext * webkit_web_context_get_default (void); +WEBKIT_API WebKitWebContext * +webkit_web_context_new (void); + +WEBKIT_API WebKitWebContext * +webkit_web_context_new_ephemeral (void); + +WEBKIT_API WebKitWebContext * +webkit_web_context_new_with_website_data_manager (WebKitWebsiteDataManager *manager); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_web_context_get_website_data_manager (WebKitWebContext *context); + +WEBKIT_API gboolean +webkit_web_context_is_ephemeral (WebKitWebContext *context); + WEBKIT_API void webkit_web_context_set_cache_model (WebKitWebContext *context, WebKitCacheModel cache_model); @@ -151,8 +185,20 @@ WEBKIT_API WebKitCacheModel webkit_web_context_get_cache_model (WebKitWebContext *context); WEBKIT_API void +webkit_web_context_set_web_process_count_limit (WebKitWebContext *context, + guint limit); + +WEBKIT_API guint +webkit_web_context_get_web_process_count_limit (WebKitWebContext *context); + +WEBKIT_API void webkit_web_context_clear_cache (WebKitWebContext *context); +WEBKIT_API void +webkit_web_context_set_network_proxy_settings (WebKitWebContext *context, + WebKitNetworkProxyMode proxy_mode, + WebKitNetworkProxySettings *proxy_settings); + WEBKIT_API WebKitDownload * webkit_web_context_download_uri (WebKitWebContext *context, const gchar *uri); @@ -230,13 +276,13 @@ WEBKIT_API void webkit_web_context_prefetch_dns (WebKitWebContext *context, const gchar *hostname); -WEBKIT_API void +WEBKIT_DEPRECATED_FOR(webkit_web_context_new_with_website_data_manager) void webkit_web_context_set_disk_cache_directory (WebKitWebContext *context, const gchar *directory); WEBKIT_API void webkit_web_context_allow_tls_certificate_for_host (WebKitWebContext *context, - WebKitCertificateInfo *info, + GTlsCertificate *certificate, const gchar *host); WEBKIT_API void @@ -246,6 +292,12 @@ webkit_web_context_set_process_model (WebKitWebContext WEBKIT_API WebKitProcessModel webkit_web_context_get_process_model (WebKitWebContext *context); +WEBKIT_API void +webkit_web_context_initialize_notification_permissions + (WebKitWebContext *context, + GList *allowed_origins, + GList *disallowed_origins); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h index 06474a1ef..c2b29ac74 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebContextPrivate.h @@ -26,26 +26,28 @@ #ifndef WebKitWebContextPrivate_h #define WebKitWebContextPrivate_h +#include "CustomProtocolManagerProxy.h" #include "DownloadProxy.h" -#include "WebContext.h" #include "WebKitPrivate.h" +#include "WebKitUserContentManager.h" #include "WebKitWebContext.h" -#include "WebKitWebViewGroup.h" -#include "WebSoupCustomProtocolRequestManager.h" +#include "WebProcessPool.h" +#include <WebCore/ResourceRequest.h> -WebKit::WebContext* webkitWebContextGetContext(WebKitWebContext*); +WebKit::WebProcessPool& webkitWebContextGetProcessPool(WebKitWebContext*); WebKitDownload* webkitWebContextGetOrCreateDownload(WebKit::DownloadProxy*); WebKitDownload* webkitWebContextStartDownload(WebKitWebContext*, const char* uri, WebKit::WebPageProxy*); void webkitWebContextRemoveDownload(WebKit::DownloadProxy*); void webkitWebContextDownloadStarted(WebKitWebContext*, WebKitDownload*); -WebKit::WebSoupCustomProtocolRequestManager* webkitWebContextGetRequestManager(WebKitWebContext*); -void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID, API::URLRequest*); +void webkitWebContextStartLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID, const WebCore::ResourceRequest&, WebKit::CustomProtocolManagerProxy&); void webkitWebContextStopLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); +void webkitWebContextInvalidateCustomProtocolRequests(WebKitWebContext*, WebKit::CustomProtocolManagerProxy&); void webkitWebContextDidFinishLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); -void webkitWebContextCreatePageForWebView(WebKitWebContext*, WebKitWebView*, WebKitWebViewGroup*, WebKitWebView*); +bool webkitWebContextIsLoadingCustomProtocol(WebKitWebContext*, uint64_t customProtocolID); +void webkitWebContextCreatePageForWebView(WebKitWebContext*, WebKitWebView*, WebKitUserContentManager*, WebKitWebView*); void webkitWebContextWebViewDestroyed(WebKitWebContext*, WebKitWebView*); WebKitWebView* webkitWebContextGetWebViewForPage(WebKitWebContext*, WebKit::WebPageProxy*); -WebKitWebViewGroup* webkitWebContextGetDefaultWebViewGroup(WebKitWebContext*); GVariant* webkitWebContextInitializeWebExtensions(WebKitWebContext*); +void webkitWebContextInitializeNotificationPermissions(WebKitWebContext*); #endif // WebKitWebContextPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp index 083d27c84..522e5b635 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.cpp @@ -24,7 +24,7 @@ #include "WebKitMarshal.h" #include "WebKitWebInspectorPrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -72,7 +72,8 @@ enum { PROP_0, PROP_INSPECTED_URI, - PROP_ATTACHED_HEIGHT + PROP_ATTACHED_HEIGHT, + PROP_CAN_ATTACH }; struct _WebKitWebInspectorPrivate { @@ -84,6 +85,7 @@ struct _WebKitWebInspectorPrivate { RefPtr<WebInspectorProxy> webInspector; CString inspectedURI; unsigned attachedHeight; + bool canAttach; }; WEBKIT_DEFINE_TYPE(WebKitWebInspector, webkit_web_inspector, G_TYPE_OBJECT) @@ -101,6 +103,9 @@ static void webkitWebInspectorGetProperty(GObject* object, guint propId, GValue* case PROP_ATTACHED_HEIGHT: g_value_set_uint(value, webkit_web_inspector_get_attached_height(inspector)); break; + case PROP_CAN_ATTACH: + g_value_set_boolean(value, webkit_web_inspector_get_can_attach(inspector)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); } @@ -137,6 +142,24 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* findClass) WEBKIT_PARAM_READABLE)); /** + * WebKitWebInspector:can-attach: + * + * Whether the @inspector can be attached to the same window that contains + * the inspected view. + * + * Since: 2.8 + */ + g_object_class_install_property( + gObjectClass, + PROP_CAN_ATTACH, + g_param_spec_boolean( + "can-attach", + _("Can Attach"), + _("Whether the inspector can be attached to the same window that contains the inspected view"), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** * WebKitWebInspector::open-window: * @inspector: the #WebKitWebInspector on which the signal is emitted * @@ -217,7 +240,7 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* findClass) * if you want to attach the inspector view yourself (for example, to add * the inspector view to a browser tab). * - * To prevent the inspector vew from being attached you can connect to this + * To prevent the inspector view from being attached you can connect to this * signal and simply return %TRUE. * * Returns: %TRUE to stop other handlers from being invoked for the event. @@ -295,7 +318,7 @@ static bool attach(WKInspectorRef, const void* clientInfo) return returnValue; } -static bool detach(WKInspectorRef inspector, const void* clientInfo) +static bool detach(WKInspectorRef, const void* clientInfo) { gboolean returnValue; g_signal_emit(WEBKIT_WEB_INSPECTOR(clientInfo), signals[DETACH], 0, &returnValue); @@ -311,6 +334,15 @@ static void didChangeAttachedHeight(WKInspectorRef, unsigned height, const void* g_object_notify(G_OBJECT(inspector), "attached-height"); } +static void didChangeAttachAvailability(WKInspectorRef, bool available, const void* clientInfo) +{ + WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(clientInfo); + if (inspector->priv->canAttach == available) + return; + inspector->priv->canAttach = available; + g_object_notify(G_OBJECT(clientInfo), "can-attach"); +} + WebKitWebInspector* webkitWebInspectorCreate(WebInspectorProxy* webInspector) { WebKitWebInspector* inspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)); @@ -328,7 +360,8 @@ WebKitWebInspector* webkitWebInspectorCreate(WebInspectorProxy* webInspector) attach, detach, didChangeAttachedHeight, - nullptr // didChangeAttachedWidth + nullptr, // didChangeAttachedWidth + didChangeAttachAvailability }; WKInspectorSetInspectorClientGtk(toAPI(webInspector), &wkInspectorClientGtk.base); @@ -371,6 +404,25 @@ const char* webkit_web_inspector_get_inspected_uri(WebKitWebInspector* inspector } /** + * webkit_web_inspector_get_can_attach: + * @inspector: a #WebKitWebInspector + * + * Whether the @inspector can be attached to the same window that contains + * the inspected view. + * + * Returns: %TRUE if there is enough room for the inspector view inside the + * window that contains the inspected view, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_inspector_get_can_attach(WebKitWebInspector* inspector) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_INSPECTOR(inspector), FALSE); + + return inspector->priv->canAttach; +} + +/** * webkit_web_inspector_is_attached: * @inspector: a #WebKitWebInspector * diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h index 67f0f4957..686f949ac 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebInspector.h @@ -83,6 +83,9 @@ webkit_web_inspector_close (WebKitWebInspector *inspector); WEBKIT_API guint webkit_web_inspector_get_attached_height (WebKitWebInspector *inspector); +WEBKIT_API gboolean +webkit_web_inspector_get_can_attach (WebKitWebInspector* inspector); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp index b4e11e90c..7dbd804ad 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResource.cpp @@ -26,7 +26,7 @@ #include "WebKitURIRequest.h" #include "WebKitWebResourcePrivate.h" #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> using namespace WebKit; @@ -53,6 +53,7 @@ enum { RECEIVED_DATA, FINISHED, FAILED, + FAILED_WITH_TLS_ERRORS, LAST_SIGNAL }; @@ -190,13 +191,34 @@ static void webkit_web_resource_class_init(WebKitWebResourceClass* resourceClass * load operation. */ signals[FAILED] = - g_signal_new("failed", - G_TYPE_FROM_CLASS(objectClass), - G_SIGNAL_RUN_LAST, - 0, 0, 0, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); + g_signal_new( + "failed", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); + + /** + * WebKitWebResource::failed-with-tls-errors: + * @resource: the #WebKitWebResource + * @certificate: a #GTlsCertificate + * @errors: a #GTlsCertificateFlags with the verification status of @certificate + * + * This signal is emitted when a TLS error occurs during the resource load operation. + * + * Since: 2.8 + */ + signals[FAILED_WITH_TLS_ERRORS] = + g_signal_new("failed-with-tls-errors", + G_TYPE_FROM_CLASS(objectClass), + G_SIGNAL_RUN_LAST, + 0, nullptr, nullptr, + g_cclosure_marshal_generic, + G_TYPE_NONE, 2, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); } static void webkitWebResourceUpdateURI(WebKitWebResource* resource, const CString& requestURI) @@ -246,6 +268,12 @@ void webkitWebResourceFailed(WebKitWebResource* resource, GError* error) g_signal_emit(resource, signals[FINISHED], 0, NULL); } +void webkitWebResourceFailedWithTLSErrors(WebKitWebResource* resource, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate) +{ + g_signal_emit(resource, signals[FAILED_WITH_TLS_ERRORS], 0, certificate, tlsErrors); + g_signal_emit(resource, signals[FINISHED], 0, nullptr); +} + WebFrameProxy* webkitWebResourceGetFrame(WebKitWebResource* resource) { return resource->priv->frame.get(); @@ -314,12 +342,11 @@ struct ResourceGetDataAsyncData { }; WEBKIT_DEFINE_ASYNC_DATA_STRUCT(ResourceGetDataAsyncData) -static void resourceDataCallback(WKDataRef wkData, WKErrorRef, void* context) +static void resourceDataCallback(API::Data* wkData, GTask* task) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_task_get_task_data(task.get())); - data->webData = toImpl(wkData); - g_task_return_boolean(task.get(), TRUE); + ResourceGetDataAsyncData* data = static_cast<ResourceGetDataAsyncData*>(g_task_get_task_data(task)); + data->webData = wkData; + g_task_return_boolean(task, TRUE); } /** @@ -341,10 +368,14 @@ void webkit_web_resource_get_data(WebKitWebResource* resource, GCancellable* can GTask* task = g_task_new(resource, cancellable, callback, userData); g_task_set_task_data(task, createResourceGetDataAsyncData(), reinterpret_cast<GDestroyNotify>(destroyResourceGetDataAsyncData)); if (resource->priv->isMainResource) - resource->priv->frame->getMainResourceData(DataCallback::create(task, resourceDataCallback)); + resource->priv->frame->getMainResourceData([task](API::Data* data, CallbackBase::Error) { + resourceDataCallback(data, adoptGRef(task).get()); + }); else { String url = String::fromUTF8(resource->priv->uri.data()); - resource->priv->frame->getResourceData(API::URL::create(url).get(), DataCallback::create(task, resourceDataCallback)); + resource->priv->frame->getResourceData(API::URL::create(url).ptr(), [task](API::Data* data, CallbackBase::Error) { + resourceDataCallback(data, adoptGRef(task).get()); + }); } } diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h index 82e2d8f5a..de9e36b5f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebResourcePrivate.h @@ -29,6 +29,7 @@ void webkitWebResourceSetResponse(WebKitWebResource*, WebKitURIResponse*); void webkitWebResourceNotifyProgress(WebKitWebResource*, guint64 bytesReceived); void webkitWebResourceFinished(WebKitWebResource*); void webkitWebResourceFailed(WebKitWebResource*, GError*); +void webkitWebResourceFailedWithTLSErrors(WebKitWebResource*, GTlsCertificateFlags, GTlsCertificate*); WebKit::WebFrameProxy* webkitWebResourceGetFrame(WebKitWebResource*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index 0abb35e12..eeb439bb2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2011 Igalia S.L. * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2014 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,6 +23,7 @@ #include "WebKitWebView.h" #include "APIData.h" +#include "APISerializedScriptValue.h" #include "ImageOptions.h" #include "WebCertificateInfo.h" #include "WebContextMenuItem.h" @@ -29,25 +31,28 @@ #include "WebKitAuthenticationDialog.h" #include "WebKitAuthenticationRequestPrivate.h" #include "WebKitBackForwardListPrivate.h" -#include "WebKitCertificateInfoPrivate.h" #include "WebKitContextMenuClient.h" #include "WebKitContextMenuItemPrivate.h" #include "WebKitContextMenuPrivate.h" #include "WebKitDownloadPrivate.h" +#include "WebKitEditorStatePrivate.h" #include "WebKitEnumTypes.h" #include "WebKitError.h" #include "WebKitFaviconDatabasePrivate.h" #include "WebKitFormClient.h" #include "WebKitFullscreenClient.h" #include "WebKitHitTestResultPrivate.h" +#include "WebKitInstallMissingMediaPluginsPermissionRequestPrivate.h" #include "WebKitJavascriptResultPrivate.h" #include "WebKitLoaderClient.h" #include "WebKitMarshal.h" +#include "WebKitNotificationPrivate.h" #include "WebKitPolicyClient.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" #include "WebKitResponsePolicyDecision.h" #include "WebKitScriptDialogPrivate.h" +#include "WebKitSettingsPrivate.h" #include "WebKitUIClient.h" #include "WebKitURIRequestPrivate.h" #include "WebKitURIResponsePrivate.h" @@ -55,20 +60,24 @@ #include "WebKitWebInspectorPrivate.h" #include "WebKitWebResourcePrivate.h" #include "WebKitWebViewBasePrivate.h" -#include "WebKitWebViewGroupPrivate.h" #include "WebKitWebViewPrivate.h" +#include "WebKitWebViewSessionStatePrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include <JavaScriptCore/APICast.h> #include <WebCore/CertificateInfo.h> -#include <WebCore/DragIcon.h> #include <WebCore/GUniquePtrGtk.h> #include <WebCore/GUniquePtrSoup.h> #include <WebCore/GtkUtilities.h> #include <WebCore/RefPtrCairo.h> #include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> +#if USE(LIBNOTIFY) +#include <libnotify/notify.h> +#endif + using namespace WebKit; using namespace WebCore; @@ -124,6 +133,10 @@ enum { AUTHENTICATE, + SHOW_NOTIFICATION, + + RUN_COLOR_CHOOSER, + LAST_SIGNAL }; @@ -132,19 +145,24 @@ enum { PROP_WEB_CONTEXT, PROP_RELATED_VIEW, - PROP_GROUP, + PROP_SETTINGS, + PROP_USER_CONTENT_MANAGER, PROP_TITLE, PROP_ESTIMATED_LOAD_PROGRESS, PROP_FAVICON, PROP_URI, PROP_ZOOM_LEVEL, PROP_IS_LOADING, - PROP_VIEW_MODE + PROP_IS_PLAYING_AUDIO, + PROP_IS_EPHEMERAL, + PROP_EDITABLE }; typedef HashMap<uint64_t, GRefPtr<WebKitWebResource> > LoadingResourcesMap; typedef HashMap<uint64_t, GRefPtr<GTask> > SnapshotResultsMap; +class PageLoadStateObserver; + struct _WebKitWebViewPrivate { ~_WebKitWebViewPrivate() { @@ -156,24 +174,21 @@ struct _WebKitWebViewPrivate { g_main_loop_quit(modalLoop.get()); } - WebKitWebContext* context; WebKitWebView* relatedView; CString title; CString customTextEncoding; - double estimatedLoadProgress; CString activeURI; bool isLoading; - WebKitViewMode viewMode; + bool isEphemeral; - bool waitingForMainResource; - unsigned long mainResourceResponseHandlerID; - WebKitLoadEvent lastDelayedEvent; + std::unique_ptr<PageLoadStateObserver> loadObserver; GRefPtr<WebKitBackForwardList> backForwardList; GRefPtr<WebKitSettings> settings; - unsigned long settingsChangedHandlerID; - GRefPtr<WebKitWebViewGroup> group; + GRefPtr<WebKitUserContentManager> userContentManager; + GRefPtr<WebKitWebContext> context; GRefPtr<WebKitWindowProperties> windowProperties; + GRefPtr<WebKitEditorState> editorState; GRefPtr<GMainLoop> modalLoop; @@ -195,6 +210,8 @@ struct _WebKitWebViewPrivate { SnapshotResultsMap snapshotResultsMap; GRefPtr<WebKitAuthenticationRequest> authenticationRequest; + + GRefPtr<WebKitWebsiteDataManager> websiteDataManager; }; static guint signals[LAST_SIGNAL] = { 0, }; @@ -206,6 +223,87 @@ static inline WebPageProxy* getPage(WebKitWebView* webView) return webkitWebViewBaseGetPage(reinterpret_cast<WebKitWebViewBase*>(webView)); } +static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading) +{ + if (webView->priv->isLoading == isLoading) + return; + + webView->priv->isLoading = isLoading; + g_object_notify(G_OBJECT(webView), "is-loading"); +} + +void webkitWebViewIsPlayingAudioChanged(WebKitWebView* webView) +{ + g_object_notify(G_OBJECT(webView), "is-playing-audio"); +} + +class PageLoadStateObserver final : public PageLoadState::Observer { +public: + PageLoadStateObserver(WebKitWebView* webView) + : m_webView(webView) + { + } + +private: + void willChangeIsLoading() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeIsLoading() override + { + webkitWebViewSetIsLoading(m_webView, getPage(m_webView)->pageLoadState().isLoading()); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeTitle() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeTitle() override + { + m_webView->priv->title = getPage(m_webView)->pageLoadState().title().utf8(); + g_object_notify(G_OBJECT(m_webView), "title"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeActiveURL() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeActiveURL() override + { + m_webView->priv->activeURI = getPage(m_webView)->pageLoadState().activeURL().utf8(); + g_object_notify(G_OBJECT(m_webView), "uri"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeHasOnlySecureContent() override { } + void didChangeHasOnlySecureContent() override { } + + void willChangeEstimatedProgress() override + { + g_object_freeze_notify(G_OBJECT(m_webView)); + } + void didChangeEstimatedProgress() override + { + g_object_notify(G_OBJECT(m_webView), "estimated-load-progress"); + g_object_thaw_notify(G_OBJECT(m_webView)); + } + + void willChangeCanGoBack() override { } + void didChangeCanGoBack() override { } + void willChangeCanGoForward() override { } + void didChangeCanGoForward() override { } + void willChangeNetworkRequestsInProgress() override { } + void didChangeNetworkRequestsInProgress() override { } + void willChangeCertificateInfo() override { } + void didChangeCertificateInfo() override { } + void willChangeWebProcessIsResponsive() override { } + void didChangeWebProcessIsResponsive() override { } + + WebKitWebView* m_webView; +}; + static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, const char* failingURI, GError* error) { if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED) @@ -219,19 +317,22 @@ static gboolean webkitWebViewLoadFail(WebKitWebView* webView, WebKitLoadEvent, c return TRUE; } -static GtkWidget* webkitWebViewCreate(WebKitWebView*) +static GtkWidget* webkitWebViewCreate(WebKitWebView*, WebKitNavigationAction*) { - return 0; + return nullptr; } -static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, GtkMessageType type, GtkButtonsType buttons, int defaultResponse, const char* message) +static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, GtkMessageType type, GtkButtonsType buttons, int defaultResponse, const char* primaryText, const char* secondaryText = nullptr) { GtkWidget* parent = gtk_widget_get_toplevel(GTK_WIDGET(webView)); - GtkWidget* dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(parent) ? GTK_WINDOW(parent) : 0, - GTK_DIALOG_DESTROY_WITH_PARENT, type, buttons, "%s", message); - GUniquePtr<char> title(g_strdup_printf("JavaScript - %s", webkit_web_view_get_uri(webView))); + GtkWidget* dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(parent) ? GTK_WINDOW(parent) : nullptr, + GTK_DIALOG_DESTROY_WITH_PARENT, type, buttons, "%s", primaryText); + if (secondaryText) + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", secondaryText); + GUniquePtr<char> title(g_strdup_printf("JavaScript - %s", getPage(webView)->pageLoadState().url().utf8().data())); gtk_window_set_title(GTK_WINDOW(dialog), title.get()); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse); + if (buttons != GTK_BUTTONS_NONE) + gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse); return dialog; } @@ -249,7 +350,7 @@ static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDi dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; break; - case WEBKIT_SCRIPT_DIALOG_PROMPT: + case WEBKIT_SCRIPT_DIALOG_PROMPT: { dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); GtkWidget* entry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entry), scriptDialog->defaultText.data()); @@ -260,13 +361,21 @@ static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDi scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry)); break; } + case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, GTK_RESPONSE_OK, + _("Are you sure you want to leave this page?"), scriptDialog->message.data()); + gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("Stay on Page"), GTK_RESPONSE_CLOSE, _("Leave Page"), GTK_RESPONSE_OK, nullptr); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; + break; + } gtk_widget_destroy(dialog); return TRUE; } -static gboolean webkitWebViewDecidePolicy(WebKitWebView* webView, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType) +static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType decisionType) { if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE) { webkit_policy_decision_use(decision); @@ -353,7 +462,7 @@ static void webkitWebViewRequestFavicon(WebKitWebView* webView) WebKitWebViewPrivate* priv = webView->priv; priv->faviconCancellable = adoptGRef(g_cancellable_new()); - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); webkit_favicon_database_get_favicon(database, priv->activeURI.data(), priv->faviconCancellable.get(), gotFaviconCallback, webView); } @@ -366,7 +475,7 @@ static void webkitWebViewUpdateFaviconURI(WebKitWebView* webView, const char* fa webkitWebViewRequestFavicon(webView); } -static void faviconChangedCallback(WebKitFaviconDatabase* database, const char* pageURI, const char* faviconURI, WebKitWebView* webView) +static void faviconChangedCallback(WebKitFaviconDatabase*, const char* pageURI, const char* faviconURI, WebKitWebView* webView) { if (webView->priv->activeURI != pageURI) return; @@ -376,16 +485,18 @@ static void faviconChangedCallback(WebKitFaviconDatabase* database, const char* static void webkitWebViewUpdateSettings(WebKitWebView* webView) { - // We keep a ref of the current settings to disconnect the signals when settings change in the group. - webView->priv->settings = webkit_web_view_get_settings(webView); + // The "settings" property is set on construction, and in that + // case webkit_web_view_set_settings() will be called *before* the + // WebPageProxy has been created so we should do an early return. + WebPageProxy* page = getPage(webView); + if (!page) + return; WebKitSettings* settings = webView->priv->settings.get(); - WebPageProxy* page = getPage(webView); + page->setPreferences(*webkitSettingsGetPreferences(settings)); page->setCanRunModal(webkit_settings_get_allow_modal_dialogs(settings)); page->setCustomUserAgent(String::fromUTF8(webkit_settings_get_user_agent(settings))); - webkitWebViewBaseUpdatePreferences(WEBKIT_WEB_VIEW_BASE(webView)); - g_signal_connect(settings, "notify::allow-modal-dialogs", G_CALLBACK(allowModalDialogsChanged), webView); g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView); g_signal_connect(settings, "notify::user-agent", G_CALLBACK(userAgentChanged), webView); @@ -399,35 +510,13 @@ static void webkitWebViewDisconnectSettingsSignalHandlers(WebKitWebView* webView g_signal_handlers_disconnect_by_func(settings, reinterpret_cast<gpointer>(userAgentChanged), webView); } -static void webkitWebViewSettingsChanged(WebKitWebViewGroup* group, GParamSpec*, WebKitWebView* webView) -{ - webkitWebViewDisconnectSettingsSignalHandlers(webView); - webkitWebViewUpdateSettings(webView); -} - -static void webkitWebViewDisconnectSettingsChangedSignalHandler(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->settingsChangedHandlerID) - g_signal_handler_disconnect(webkit_web_view_get_group(webView), priv->settingsChangedHandlerID); - priv->settingsChangedHandlerID = 0; -} - -static void webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->mainResourceResponseHandlerID) - g_signal_handler_disconnect(priv->mainResource.get(), priv->mainResourceResponseHandlerID); - priv->mainResourceResponseHandlerID = 0; -} - static void webkitWebViewWatchForChangesInFavicon(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; if (priv->faviconChangedHandlerID) return; - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); priv->faviconChangedHandlerID = g_signal_connect(database, "favicon-changed", G_CALLBACK(faviconChangedCallback), webView); } @@ -435,7 +524,7 @@ static void webkitWebViewDisconnectFaviconDatabaseSignalHandlers(WebKitWebView* { WebKitWebViewPrivate* priv = webView->priv; if (priv->faviconChangedHandlerID) - g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context), priv->faviconChangedHandlerID); + g_signal_handler_disconnect(webkit_web_context_get_favicon_database(priv->context.get()), priv->faviconChangedHandlerID); priv->faviconChangedHandlerID = 0; } @@ -496,14 +585,87 @@ static void webkitWebViewHandleDownloadRequest(WebKitWebViewBase* webViewBase, D webkitDownloadSetWebView(download.get(), WEBKIT_WEB_VIEW(webViewBase)); } +#if USE(LIBNOTIFY) +static const char* gNotifyNotificationID = "wk-notify-notification"; + +static void notifyNotificationClosed(NotifyNotification*, WebKitNotification* webNotification) +{ + g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr); + webkit_notification_close(webNotification); +} + +static void notifyNotificationClicked(NotifyNotification*, char*, WebKitNotification* webNotification) +{ + webkit_notification_clicked(webNotification); +} + +static void webNotificationClosed(WebKitNotification* webNotification) +{ + NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID)); + if (!notification) + return; + + notify_notification_close(notification, nullptr); + g_object_set_data(G_OBJECT(webNotification), gNotifyNotificationID, nullptr); +} +#endif // USE(LIBNOTIFY) + +static gboolean webkitWebViewShowNotification(WebKitWebView*, WebKitNotification* webNotification) +{ +#if USE(LIBNOTIFY) + if (!notify_is_initted()) + notify_init(g_get_prgname()); + + NotifyNotification* notification = NOTIFY_NOTIFICATION(g_object_get_data(G_OBJECT(webNotification), gNotifyNotificationID)); + if (!notification) { + notification = notify_notification_new(webkit_notification_get_title(webNotification), + webkit_notification_get_body(webNotification), nullptr); + + notify_notification_add_action(notification, "default", _("Acknowledge"), NOTIFY_ACTION_CALLBACK(notifyNotificationClicked), webNotification, nullptr); + + g_signal_connect_object(notification, "closed", G_CALLBACK(notifyNotificationClosed), webNotification, static_cast<GConnectFlags>(0)); + g_signal_connect(webNotification, "closed", G_CALLBACK(webNotificationClosed), nullptr); + g_object_set_data_full(G_OBJECT(webNotification), gNotifyNotificationID, notification, static_cast<GDestroyNotify>(g_object_unref)); + } else { + notify_notification_update(notification, webkit_notification_get_title(webNotification), + webkit_notification_get_body(webNotification), nullptr); + } + + notify_notification_show(notification, nullptr); + return TRUE; +#else + UNUSED_PARAM(webNotification); + return FALSE; +#endif +} + static void webkitWebViewConstructed(GObject* object) { - if (G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed) - G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object); + G_OBJECT_CLASS(webkit_web_view_parent_class)->constructed(object); WebKitWebView* webView = WEBKIT_WEB_VIEW(object); WebKitWebViewPrivate* priv = webView->priv; - webkitWebContextCreatePageForWebView(priv->context, webView, priv->group.get(), priv->relatedView); + if (priv->relatedView) { + priv->context = webkit_web_view_get_context(priv->relatedView); + priv->isEphemeral = webkit_web_view_is_ephemeral(priv->relatedView); + } else if (!priv->context) + priv->context = webkit_web_context_get_default(); + else if (!priv->isEphemeral) + priv->isEphemeral = webkit_web_context_is_ephemeral(priv->context.get()); + + if (!priv->settings) + priv->settings = adoptGRef(webkit_settings_new()); + + if (priv->isEphemeral && !webkit_web_context_is_ephemeral(priv->context.get())) { + priv->websiteDataManager = adoptGRef(webkit_website_data_manager_new_ephemeral()); + webkitWebsiteDataManagerAddProcessPool(priv->websiteDataManager.get(), webkitWebContextGetProcessPool(priv->context.get())); + } + + webkitWebContextCreatePageForWebView(priv->context.get(), webView, priv->userContentManager.get(), priv->relatedView); + + priv->loadObserver = std::make_unique<PageLoadStateObserver>(webView); + getPage(webView)->pageLoadState().addObserver(*priv->loadObserver); + // The related view is only valid during the construction. priv->relatedView = nullptr; @@ -516,12 +678,12 @@ static void webkitWebViewConstructed(GObject* object) attachContextMenuClientToView(webView); attachFormClientToView(webView); + // This needs to be after attachUIClientToView() because WebPageProxy::setUIClient() calls setCanRunModal() with true. + // See https://bugs.webkit.org/show_bug.cgi?id=135412. + webkitWebViewUpdateSettings(webView); + priv->backForwardList = adoptGRef(webkitBackForwardListCreate(&getPage(webView)->backForwardList())); priv->windowProperties = adoptGRef(webkitWindowPropertiesCreate()); - - webkitWebViewUpdateSettings(webView); - priv->settingsChangedHandlerID = - g_signal_connect(webkit_web_view_get_group(webView), "notify::settings", G_CALLBACK(webkitWebViewSettingsChanged), webView); } static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -531,7 +693,7 @@ static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue switch (propId) { case PROP_WEB_CONTEXT: { gpointer webContext = g_value_get_object(value); - webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : webkit_web_context_get_default(); + webView->priv->context = webContext ? WEBKIT_WEB_CONTEXT(webContext) : nullptr; break; } case PROP_RELATED_VIEW: { @@ -539,16 +701,24 @@ static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue webView->priv->relatedView = relatedView ? WEBKIT_WEB_VIEW(relatedView) : nullptr; break; } - case PROP_GROUP: { - gpointer group = g_value_get_object(value); - webView->priv->group = group ? WEBKIT_WEB_VIEW_GROUP(group) : 0; + case PROP_SETTINGS: { + if (gpointer settings = g_value_get_object(value)) + webkit_web_view_set_settings(webView, WEBKIT_SETTINGS(settings)); + break; + } + case PROP_USER_CONTENT_MANAGER: { + gpointer userContentManager = g_value_get_object(value); + webView->priv->userContentManager = userContentManager ? WEBKIT_USER_CONTENT_MANAGER(userContentManager) : nullptr; break; } case PROP_ZOOM_LEVEL: webkit_web_view_set_zoom_level(webView, g_value_get_double(value)); break; - case PROP_VIEW_MODE: - webkit_web_view_set_view_mode(webView, static_cast<WebKitViewMode>(g_value_get_enum(value))); + case PROP_IS_EPHEMERAL: + webView->priv->isEphemeral = g_value_get_boolean(value); + break; + case PROP_EDITABLE: + webkit_web_view_set_editable(webView, g_value_get_boolean(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); @@ -561,10 +731,13 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu switch (propId) { case PROP_WEB_CONTEXT: - g_value_set_object(value, webView->priv->context); + g_value_set_object(value, webView->priv->context.get()); break; - case PROP_GROUP: - g_value_set_object(value, webkit_web_view_get_group(webView)); + case PROP_SETTINGS: + g_value_set_object(value, webkit_web_view_get_settings(webView)); + break; + case PROP_USER_CONTENT_MANAGER: + g_value_set_object(value, webkit_web_view_get_user_content_manager(webView)); break; case PROP_TITLE: g_value_set_string(value, webView->priv->title.data()); @@ -584,8 +757,14 @@ static void webkitWebViewGetProperty(GObject* object, guint propId, GValue* valu case PROP_IS_LOADING: g_value_set_boolean(value, webkit_web_view_is_loading(webView)); break; - case PROP_VIEW_MODE: - g_value_set_enum(value, webkit_web_view_get_view_mode(webView)); + case PROP_IS_PLAYING_AUDIO: + g_value_set_boolean(value, webkit_web_view_is_playing_audio(webView)); + break; + case PROP_IS_EPHEMERAL: + g_value_set_boolean(value, webkit_web_view_is_ephemeral(webView)); + break; + case PROP_EDITABLE: + g_value_set_boolean(value, webkit_web_view_is_editable(webView)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); @@ -596,12 +775,23 @@ static void webkitWebViewDispose(GObject* object) { WebKitWebView* webView = WEBKIT_WEB_VIEW(object); webkitWebViewCancelFaviconRequest(webView); - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - webkitWebViewDisconnectSettingsChangedSignalHandler(webView); webkitWebViewDisconnectSettingsSignalHandlers(webView); webkitWebViewDisconnectFaviconDatabaseSignalHandlers(webView); - webkitWebContextWebViewDestroyed(webView->priv->context, webView); + if (webView->priv->loadObserver) { + getPage(webView)->pageLoadState().removeObserver(*webView->priv->loadObserver); + webView->priv->loadObserver.reset(); + + // We notify the context here to ensure it's called only once. Ideally we should + // call this in finalize, not dispose, but finalize is used internally and we don't + // have access to the instance pointer from the private struct destructor. + webkitWebContextWebViewDestroyed(webView->priv->context.get(), webView); + } + + if (webView->priv->websiteDataManager) { + webkitWebsiteDataManagerRemoveProcessPool(webView->priv->websiteDataManager.get(), webkitWebContextGetProcessPool(webView->priv->context.get())); + webView->priv->websiteDataManager = nullptr; + } G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object); } @@ -631,6 +821,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webViewClass->permission_request = webkitWebViewPermissionRequest; webViewClass->run_file_chooser = webkitWebViewRunFileChooser; webViewClass->authenticate = webkitWebViewAuthenticate; + webViewClass->show_notification = webkitWebViewShowNotification; /** * WebKitWebView:web-context: @@ -664,18 +855,37 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY))); /** - * WebKitWebView:group: + * WebKitWebView:settings: + * + * The #WebKitSettings of the view. * - * The #WebKitWebViewGroup of the view. + * Since: 2.6 */ g_object_class_install_property( gObjectClass, - PROP_GROUP, + PROP_SETTINGS, g_param_spec_object( - "group", - _("WebView Group"), - _("The WebKitWebViewGroup of the view"), - WEBKIT_TYPE_WEB_VIEW_GROUP, + "settings", + _("WebView settings"), + _("The WebKitSettings of the view"), + WEBKIT_TYPE_SETTINGS, + static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT))); + + /** + * WebKitWebView:user-content-manager: + * + * The #WebKitUserContentManager of the view. + * + * Since: 2.6 + */ + g_object_class_install_property( + gObjectClass, + PROP_USER_CONTENT_MANAGER, + g_param_spec_object( + "user-content-manager", + _("WebView user content manager"), + _("The WebKitUserContentManager of the view"), + WEBKIT_TYPE_USER_CONTENT_MANAGER, static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); /** @@ -742,13 +952,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * The zoom level of the #WebKitWebView content. * See webkit_web_view_set_zoom_level() for more details. */ - g_object_class_install_property(gObjectClass, - PROP_ZOOM_LEVEL, - g_param_spec_double("zoom-level", - "Zoom level", - _("The zoom level of the view content"), - 0, G_MAXDOUBLE, 1, - WEBKIT_PARAM_READWRITE)); + g_object_class_install_property( + gObjectClass, + PROP_ZOOM_LEVEL, + g_param_spec_double( + "zoom-level", + _("Zoom level"), + _("The zoom level of the view content"), + 0, G_MAXDOUBLE, 1, + WEBKIT_PARAM_READWRITE)); /** * WebKitWebView:is-loading: @@ -760,28 +972,76 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * When the load operation finishes the property is set to %FALSE before * #WebKitWebView::load-changed is emitted with %WEBKIT_LOAD_FINISHED. */ - g_object_class_install_property(gObjectClass, - PROP_IS_LOADING, - g_param_spec_boolean("is-loading", - "Is Loading", - _("Whether the view is loading a page"), - FALSE, - WEBKIT_PARAM_READABLE)); + g_object_class_install_property( + gObjectClass, + PROP_IS_LOADING, + g_param_spec_boolean( + "is-loading", + _("Is Loading"), + _("Whether the view is loading a page"), + FALSE, + WEBKIT_PARAM_READABLE)); /** - * WebKitWebView:view-mode: + * WebKitWebView:is-playing-audio: + * + * Whether the #WebKitWebView is currently playing audio from a page. + * This property becomes %TRUE as soon as web content starts playing any + * kind of audio. When a page is no longer playing any kind of sound, + * the property is set back to %FALSE. * - * The #WebKitViewMode that is used to display the contents of a #WebKitWebView. - * See also webkit_web_view_set_view_mode(). + * Since: 2.8 */ - g_object_class_install_property(gObjectClass, - PROP_VIEW_MODE, - g_param_spec_enum("view-mode", - "View Mode", - _("The view mode to display the web view contents"), - WEBKIT_TYPE_VIEW_MODE, - WEBKIT_VIEW_MODE_WEB, - WEBKIT_PARAM_READWRITE)); + g_object_class_install_property( + gObjectClass, + PROP_IS_PLAYING_AUDIO, + g_param_spec_boolean( + "is-playing-audio", + "Is Playing Audio", + _("Whether the view is playing audio"), + FALSE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:is-ephemeral: + * + * Whether the #WebKitWebView is ephemeral. An ephemeral web view never writes + * website data to the client storage, no matter what #WebKitWebsiteDataManager + * its context is using. This is normally used to implement private browsing mode. + * This is a %G_PARAM_CONSTRUCT_ONLY property, so you have to create a ephemeral + * #WebKitWebView and it can't be changed. Note that all #WebKitWebView<!-- -->s + * created with an ephemeral #WebKitWebContext will be ephemeral automatically. + * See also webkit_web_context_new_ephemeral(). + * + * Since: 2.16 + */ + g_object_class_install_property( + gObjectClass, + PROP_IS_EPHEMERAL, + g_param_spec_boolean( + "is-ephemeral", + "Is Ephemeral", + _("Whether the web view is ephemeral"), + FALSE, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebView:editable: + * + * Whether the pages loaded inside #WebKitWebView are editable. For more + * information see webkit_web_view_set_editable(). + * + * Since: 2.8 + */ + g_object_class_install_property( + gObjectClass, + PROP_EDITABLE, + g_param_spec_boolean( + "editable", + _("Editable"), + _("Whether the content can be modified by the user."), + FALSE, + WEBKIT_PARAM_READWRITE)); /** * WebKitWebView::load-changed: @@ -865,30 +1125,31 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * %FALSE to propagate the event further. */ signals[LOAD_FAILED] = - g_signal_new("load-failed", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, load_failed), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__ENUM_STRING_POINTER, - G_TYPE_BOOLEAN, 3, - WEBKIT_TYPE_LOAD_EVENT, - G_TYPE_STRING, - G_TYPE_POINTER); + g_signal_new( + "load-failed", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, load_failed), + g_signal_accumulator_true_handled, 0, + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, 3, + WEBKIT_TYPE_LOAD_EVENT, + G_TYPE_STRING, + G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::load-failed-with-tls-errors: * @web_view: the #WebKitWebView on which the signal is emitted - * @info: a #WebKitCertificateInfo - * @host: the host on which the error occurred + * @failing_uri: the URI that failed to load + * @certificate: a #GTlsCertificate + * @errors: a #GTlsCertificateFlags with the verification status of @certificate * - * Emitted when a TLS error occurs during a load operation. The @info - * object contains information about the error such as the #GTlsCertificate - * and the #GTlsCertificateFlags. To allow an exception for this certificate - * and this host use webkit_web_context_allow_tls_certificate_for_host(). + * Emitted when a TLS error occurs during a load operation. + * To allow an exception for this @certificate + * and the host of @failing_uri use webkit_web_context_allow_tls_certificate_for_host(). * - * To handle this signal asynchronously you should copy the #WebKitCertificateInfo - * with webkit_certificate_info_copy() and return %TRUE. + * To handle this signal asynchronously you should call g_object_ref() on @certificate + * and return %TRUE. * * If %FALSE is returned, #WebKitWebView::load-failed will be emitted. The load * will finish regardless of the returned value. @@ -896,7 +1157,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. * - * Since: 2.4 + * Since: 2.6 */ signals[LOAD_FAILED_WITH_TLS_ERRORS] = g_signal_new("load-failed-with-tls-errors", @@ -904,22 +1165,27 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(WebKitWebViewClass, load_failed_with_tls_errors), g_signal_accumulator_true_handled, 0 /* accumulator data */, - webkit_marshal_BOOLEAN__BOXED_STRING, - G_TYPE_BOOLEAN, 2, /* number of parameters */ - WEBKIT_TYPE_CERTIFICATE_INFO | G_SIGNAL_TYPE_STATIC_SCOPE, - G_TYPE_STRING); + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, 3, + G_TYPE_STRING, + G_TYPE_TLS_CERTIFICATE, + G_TYPE_TLS_CERTIFICATE_FLAGS); /** * WebKitWebView::create: * @web_view: the #WebKitWebView on which the signal is emitted + * @navigation_action: a #WebKitNavigationAction * * Emitted when the creation of a new #WebKitWebView is requested. * If this signal is handled the signal handler should return the * newly created #WebKitWebView. * + * The #WebKitNavigationAction parameter contains information about the + * navigation action that triggered this signal. + * * When using %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES * process model, the new #WebKitWebView should be related to - * @web_view to share the same web process, see webkit_web_view_new_with_related_view + * @web_view to share the same web process, see webkit_web_view_new_with_related_view() * for more details. * * The new #WebKitWebView should not be displayed to the user @@ -928,14 +1194,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * Returns: (transfer full): a newly allocated #WebKitWebView widget * or %NULL to propagate the event further. */ - signals[CREATE] = - g_signal_new("create", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, create), - webkitWebViewAccumulatorObjectHandled, 0, - webkit_marshal_OBJECT__VOID, - GTK_TYPE_WIDGET, 0); + signals[CREATE] = g_signal_new( + "create", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, create), + webkitWebViewAccumulatorObjectHandled, 0, + g_cclosure_marshal_generic, + GTK_TYPE_WIDGET, 1, + WEBKIT_TYPE_NAVIGATION_ACTION | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::ready-to-show: @@ -980,10 +1247,11 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) /** * WebKitWebView::close: - * @webView: the #WebKitWebView on which the signal is emitted + * @web_view: the #WebKitWebView on which the signal is emitted * * Emitted when closing a #WebKitWebView is requested. This occurs when a - * call is made from JavaScript's <function>window.close</function> function. + * call is made from JavaScript's <function>window.close</function> function or + * after trying to close the @web_view with webkit_web_view_try_close(). * It is the owner's responsibility to handle this signal to hide or * destroy the #WebKitWebView, if necessary. */ @@ -1002,7 +1270,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @dialog: the #WebKitScriptDialog to show * * Emitted when JavaScript code calls <function>window.alert</function>, - * <function>window.confirm</function> or <function>window.prompt</function>. + * <function>window.confirm</function> or <function>window.prompt</function>, + * or when <function>onbeforeunload</function> event is fired. * The @dialog parameter should be used to build the dialog. * If the signal is not handled a different dialog will be built and shown depending * on the dialog type: @@ -1017,6 +1286,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and * a text entry with the default text. * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM: message dialog with Stay and Leave buttons. + * </para></listitem> * </itemizedlist> * * Returns: %TRUE to stop other handlers from being invoked for the event. @@ -1140,9 +1412,10 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * request has not been handled, webkit_permission_request_deny() * will be the default action. * - * By default, if the signal is not handled, - * webkit_permission_request_deny() will be called over the - * #WebKitPermissionRequest. + * If the signal is not handled, the @request will be completed automatically + * by the specific #WebKitPermissionRequest that could allow or deny it. Check the + * documentation of classes implementing #WebKitPermissionRequest interface to know + * their default action. * * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. @@ -1315,8 +1588,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @event: the #GdkEvent that triggered the context menu * @hit_test_result: a #WebKitHitTestResult * - * Emmited when a context menu is about to be displayed to give the application - * a chance to customize the proposed menu, prevent the menu from being displayed + * Emitted when a context menu is about to be displayed to give the application + * a chance to customize the proposed menu, prevent the menu from being displayed, * or build its own context menu. * <itemizedlist> * <listitem><para> @@ -1343,6 +1616,22 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * </para></listitem> * </itemizedlist> * + * The @event is expected to be one of the following types: + * <itemizedlist> + * <listitem><para> + * a #GdkEventButton of type %GDK_BUTTON_PRESS when the context menu + * was triggered with mouse. + * </para></listitem> + * <listitem><para> + * a #GdkEventKey of type %GDK_KEY_PRESS if the keyboard was used to show + * the menu. + * </para></listitem> + * <listitem><para> + * a generic #GdkEvent of type %GDK_NOTHING when the #GtkWidget:popup-menu + * signal was used to show the context menu. + * </para></listitem> + * </itemizedlist> + * * If the signal handler returns %FALSE the context menu represented by @context_menu * will be shown, if it return %TRUE the context menu will not be shown. * @@ -1482,21 +1771,66 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, /* number of parameters */ WEBKIT_TYPE_AUTHENTICATION_REQUEST); -} - -static void webkitWebViewSetIsLoading(WebKitWebView* webView, bool isLoading) -{ - if (webView->priv->isLoading == isLoading) - return; - webView->priv->isLoading = isLoading; - g_object_freeze_notify(G_OBJECT(webView)); - g_object_notify(G_OBJECT(webView), "is-loading"); + /** + * WebKitWebView::show-notification: + * @web_view: the #WebKitWebView + * @notification: a #WebKitNotification + * + * This signal is emitted when a notification should be presented to the + * user. The @notification is kept alive until either: 1) the web page cancels it + * or 2) a navigation happens. + * + * The default handler will emit a notification using libnotify, if built with + * support for it. + * + * Returns: %TRUE to stop other handlers from being invoked. %FALSE otherwise. + * + * Since: 2.8 + */ + signals[SHOW_NOTIFICATION] = + g_signal_new("show-notification", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, show_notification), + g_signal_accumulator_true_handled, nullptr /* accumulator data */, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_NOTIFICATION); - // Update the URI if a new load has started. - if (webView->priv->isLoading) - webkitWebViewUpdateURI(webView); - g_object_thaw_notify(G_OBJECT(webView)); + /** + * WebKitWebView::run-color-chooser: + * @web_view: the #WebKitWebView on which the signal is emitted + * @request: a #WebKitColorChooserRequest + * + * This signal is emitted when the user interacts with a <input + * type='color' /> HTML element, requesting from WebKit to show + * a dialog to select a color. To let the application know the details of + * the color chooser, as well as to allow the client application to either + * cancel the request or perform an actual color selection, the signal will + * pass an instance of the #WebKitColorChooserRequest in the @request + * argument. + * + * It is possible to handle this request asynchronously by increasing the + * reference count of the request. + * + * The default signal handler will asynchronously run a regular + * #GtkColorChooser for the user to interact with. + * + * Returns: %TRUE to stop other handlers from being invoked for the event. + * %FALSE to propagate the event further. + * + * Since: 2.8 + */ + signals[RUN_COLOR_CHOOSER] = + g_signal_new("run-color-chooser", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, run_color_chooser), + g_signal_accumulator_true_handled, nullptr, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_COLOR_CHOOSER_REQUEST); } static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView) @@ -1508,68 +1842,35 @@ static void webkitWebViewCancelAuthenticationRequest(WebKitWebView* webView) webView->priv->authenticationRequest.clear(); } -static void webkitWebViewEmitLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) -{ - if (loadEvent == WEBKIT_LOAD_STARTED) { - webkitWebViewSetIsLoading(webView, true); - webkitWebViewWatchForChangesInFavicon(webView); - webkitWebViewCancelAuthenticationRequest(webView); - } else if (loadEvent == WEBKIT_LOAD_FINISHED) { - webkitWebViewSetIsLoading(webView, false); - webkitWebViewCancelAuthenticationRequest(webView); - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - } else - webkitWebViewUpdateURI(webView); - g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); -} - -static void webkitWebViewEmitDelayedLoadEvents(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (!priv->waitingForMainResource) - return; - ASSERT(priv->lastDelayedEvent == WEBKIT_LOAD_COMMITTED || priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED); - - if (priv->lastDelayedEvent == WEBKIT_LOAD_FINISHED) - webkitWebViewEmitLoadChanged(webView, WEBKIT_LOAD_COMMITTED); - webkitWebViewEmitLoadChanged(webView, priv->lastDelayedEvent); - priv->waitingForMainResource = false; -} - void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) { WebKitWebViewPrivate* priv = webView->priv; - if (loadEvent == WEBKIT_LOAD_STARTED) { - // Finish a possible previous load waiting for main resource. - webkitWebViewEmitDelayedLoadEvents(webView); - + switch (loadEvent) { + case WEBKIT_LOAD_STARTED: webkitWebViewCancelFaviconRequest(webView); + webkitWebViewWatchForChangesInFavicon(webView); + webkitWebViewCancelAuthenticationRequest(webView); priv->loadingResourcesMap.clear(); - priv->mainResource = 0; - priv->waitingForMainResource = false; - } else if (loadEvent == WEBKIT_LOAD_COMMITTED) { - WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context); + priv->mainResource = nullptr; + break; + case WEBKIT_LOAD_COMMITTED: { + WebKitFaviconDatabase* database = webkit_web_context_get_favicon_database(priv->context.get()); GUniquePtr<char> faviconURI(webkit_favicon_database_get_favicon_uri(database, priv->activeURI.data())); webkitWebViewUpdateFaviconURI(webView, faviconURI.get()); - - if (!priv->mainResource) { - // When a page is loaded from the history cache, the main resource load callbacks - // are called when the main frame load is finished. We want to make sure there's a - // main resource available when load has been committed, so we delay the emission of - // load-changed signal until main resource object has been created. - priv->waitingForMainResource = true; - } + break; + } + case WEBKIT_LOAD_FINISHED: + webkitWebViewCancelAuthenticationRequest(webView); + break; + default: + break; } - if (priv->waitingForMainResource) - priv->lastDelayedEvent = loadEvent; - else - webkitWebViewEmitLoadChanged(webView, loadEvent); + g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); } void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error) { - webkitWebViewSetIsLoading(webView, false); webkitWebViewCancelAuthenticationRequest(webView); gboolean returnValue; @@ -1579,15 +1880,12 @@ void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* failingURI, GError* error, GTlsCertificateFlags tlsErrors, GTlsCertificate* certificate) { - webkitWebViewSetIsLoading(webView, false); webkitWebViewCancelAuthenticationRequest(webView); - WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context); + WebKitTLSErrorsPolicy tlsErrorsPolicy = webkit_web_context_get_tls_errors_policy(webView->priv->context.get()); if (tlsErrorsPolicy == WEBKIT_TLS_ERRORS_POLICY_FAIL) { - GUniquePtr<SoupURI> soupURI(soup_uri_new(failingURI)); - WebKitCertificateInfo info(certificate, tlsErrors); gboolean returnValue; - g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, &info, soupURI->host, &returnValue); + g_signal_emit(webView, signals[LOAD_FAILED_WITH_TLS_ERRORS], 0, failingURI, certificate, tlsErrors, &returnValue); if (!returnValue) g_signal_emit(webView, signals[LOAD_FAILED], 0, WEBKIT_LOAD_STARTED, failingURI, error, &returnValue); } @@ -1595,46 +1893,17 @@ void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView* webView, const char* fa g_signal_emit(webView, signals[LOAD_CHANGED], 0, WEBKIT_LOAD_FINISHED); } -void webkitWebViewSetTitle(WebKitWebView* webView, const CString& title) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (priv->title == title) - return; - - priv->title = title; - g_object_notify(G_OBJECT(webView), "title"); -} - -void webkitWebViewSetEstimatedLoadProgress(WebKitWebView* webView, double estimatedLoadProgress) -{ - if (webView->priv->estimatedLoadProgress == estimatedLoadProgress) - return; - - webView->priv->estimatedLoadProgress = estimatedLoadProgress; - g_object_notify(G_OBJECT(webView), "estimated-load-progress"); -} - -void webkitWebViewUpdateURI(WebKitWebView* webView) -{ - CString activeURI = getPage(webView)->pageLoadState().activeURL().utf8(); - if (webView->priv->activeURI == activeURI) - return; - - webView->priv->activeURI = activeURI; - g_object_notify(G_OBJECT(webView), "uri"); -} - -WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, ImmutableDictionary* windowFeatures) +WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView* webView, const WindowFeatures& windowFeatures, WebKitNavigationAction* navigationAction) { WebKitWebView* newWebView; - g_signal_emit(webView, signals[CREATE], 0, &newWebView); + g_signal_emit(webView, signals[CREATE], 0, navigationAction, &newWebView); if (!newWebView) return 0; webkitWindowPropertiesUpdateFromWebWindowFeatures(newWebView->priv->windowProperties.get(), windowFeatures); RefPtr<WebPageProxy> newPage = getPage(newWebView); - return newPage.release().leakRef(); + return newPage.leakRef(); } void webkitWebViewReadyToShowPage(WebKitWebView* webView) @@ -1647,9 +1916,14 @@ void webkitWebViewRunAsModal(WebKitWebView* webView) g_signal_emit(webView, signals[RUN_AS_MODAL], 0, NULL); webView->priv->modalLoop = adoptGRef(g_main_loop_new(0, FALSE)); + +// This is to suppress warnings about gdk_threads_leave and gdk_threads_enter. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" gdk_threads_leave(); g_main_loop_run(webView->priv->modalLoop.get()); gdk_threads_enter(); +#pragma GCC diagnostic pop } void webkitWebViewClosePage(WebKitWebView* webView) @@ -1680,6 +1954,14 @@ CString webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& return dialog.text; } +bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const CString& message) +{ + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM, message); + gboolean returnValue; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.confirmed; +} + void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision) { gboolean returnValue; @@ -1692,9 +1974,9 @@ void webkitWebViewMakePermissionRequest(WebKitWebView* webView, WebKitPermission g_signal_emit(webView, signals[PERMISSION_REQUEST], 0, request, &returnValue); } -void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WebHitTestResult* hitTestResult, unsigned modifiers) +void webkitWebViewMouseTargetChanged(WebKitWebView* webView, const WebHitTestResultData& hitTestResult, unsigned modifiers) { - webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult->elementBoundingBox()); + webkitWebViewBaseSetTooltipArea(WEBKIT_WEB_VIEW_BASE(webView), hitTestResult.elementBoundingBox); WebKitWebViewPrivate* priv = webView->priv; if (priv->mouseTargetHitTestResult @@ -1709,7 +1991,7 @@ void webkitWebViewMouseTargetChanged(WebKitWebView* webView, WebHitTestResult* h void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame) { - GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(webkit_print_operation_new(webView)); + auto printOperation = adoptGRef(webkit_print_operation_new(webView)); webkitPrintOperationSetPrintMode(printOperation.get(), PrintInfo::PrintModeSync); gboolean returnValue; g_signal_emit(webView, signals[PRINT], 0, printOperation.get(), &returnValue); @@ -1722,32 +2004,13 @@ void webkitWebViewPrintFrame(WebKitWebView* webView, WebFrameProxy* frame) g_signal_connect(printOperation.leakRef(), "finished", G_CALLBACK(g_object_unref), 0); } -static void mainResourceResponseChangedCallback(WebKitWebResource*, GParamSpec*, WebKitWebView* webView) -{ - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - webkitWebViewEmitDelayedLoadEvents(webView); -} - -static void waitForMainResourceResponseIfWaitingForResource(WebKitWebView* webView) -{ - WebKitWebViewPrivate* priv = webView->priv; - if (!priv->waitingForMainResource) - return; - - webkitWebViewDisconnectMainResourceResponseChangedSignalHandler(webView); - priv->mainResourceResponseHandlerID = - g_signal_connect(priv->mainResource.get(), "notify::response", G_CALLBACK(mainResourceResponseChangedCallback), webView); -} - void webkitWebViewResourceLoadStarted(WebKitWebView* webView, WebFrameProxy* frame, uint64_t resourceIdentifier, WebKitURIRequest* request) { WebKitWebViewPrivate* priv = webView->priv; bool isMainResource = frame->isMainFrame() && !priv->mainResource; WebKitWebResource* resource = webkitWebResourceCreate(frame, request, isMainResource); - if (isMainResource) { + if (isMainResource) priv->mainResource = resource; - waitForMainResourceResponseIfWaitingForResource(webView); - } priv->loadingResourcesMap.set(resourceIdentifier, adoptGRef(resource)); g_signal_emit(webView, signals[RESOURCE_LOAD_STARTED], 0, resource, request); } @@ -1785,76 +2048,29 @@ void webkitWebViewRunFileChooserRequest(WebKitWebView* webView, WebKitFileChoose g_signal_emit(webView, signals[RUN_FILE_CHOOSER], 0, request, &returnValue); } -static bool webkitWebViewShouldShowInputMethodsMenu(WebKitWebView* webView) -{ - GtkSettings* settings = gtk_widget_get_settings(GTK_WIDGET(webView)); - if (!settings) - return true; - - gboolean showInputMethodMenu; - g_object_get(settings, "gtk-show-input-method-menu", &showInputMethodMenu, NULL); - return showInputMethodMenu; -} - -static int getUnicodeMenuItemPosition(WebKitContextMenu* contextMenu) -{ - GList* items = webkit_context_menu_get_items(contextMenu); - GList* iter; - int i = 0; - for (iter = items, i = 0; iter; iter = g_list_next(iter), ++i) { - WebKitContextMenuItem* item = WEBKIT_CONTEXT_MENU_ITEM(iter->data); - - if (webkit_context_menu_item_is_separator(item)) - continue; - if (webkit_context_menu_item_get_stock_action(item) == WEBKIT_CONTEXT_MENU_ACTION_UNICODE) - return i; - } - return -1; -} - -static void webkitWebViewCreateAndAppendInputMethodsMenuItem(WebKitWebView* webView, WebKitContextMenu* contextMenu) -{ - if (!webkitWebViewShouldShowInputMethodsMenu(webView)) - return; - - // Place the im context menu item right before the unicode menu item - // if it's present. - int unicodeMenuItemPosition = getUnicodeMenuItemPosition(contextMenu); - if (unicodeMenuItemPosition == -1) - webkit_context_menu_append(contextMenu, webkit_context_menu_item_new_separator()); - - GtkIMContext* imContext = webkitWebViewBaseGetIMContext(WEBKIT_WEB_VIEW_BASE(webView)); - GtkMenu* imContextMenu = GTK_MENU(gtk_menu_new()); - gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(imContext), GTK_MENU_SHELL(imContextMenu)); - WebKitContextMenuItem* menuItem = webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INPUT_METHODS); - webkitContextMenuItemSetSubMenuFromGtkMenu(menuItem, imContextMenu); - webkit_context_menu_insert(contextMenu, menuItem, unicodeMenuItemPosition); -} - static void contextMenuDismissed(GtkMenuShell*, WebKitWebView* webView) { g_signal_emit(webView, signals[CONTEXT_MENU_DISMISSED], 0, NULL); } -void webkitWebViewPopulateContextMenu(WebKitWebView* webView, API::Array* proposedMenu, WebHitTestResult* webHitTestResult) +void webkitWebViewPopulateContextMenu(WebKitWebView* webView, const Vector<WebContextMenuItemData>& proposedMenu, const WebHitTestResultData& hitTestResultData, GVariant* userData) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(webView); WebContextMenuProxyGtk* contextMenuProxy = webkitWebViewBaseGetActiveContextMenuProxy(webViewBase); ASSERT(contextMenuProxy); GRefPtr<WebKitContextMenu> contextMenu = adoptGRef(webkitContextMenuCreate(proposedMenu)); - if (webHitTestResult->isContentEditable()) - webkitWebViewCreateAndAppendInputMethodsMenuItem(webView, contextMenu.get()); + if (userData) + webkit_context_menu_set_user_data(WEBKIT_CONTEXT_MENU(contextMenu.get()), userData); - GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(webHitTestResult)); + GRefPtr<WebKitHitTestResult> hitTestResult = adoptGRef(webkitHitTestResultCreate(hitTestResultData)); GUniquePtr<GdkEvent> contextMenuEvent(webkitWebViewBaseTakeContextMenuEvent(webViewBase)); - gboolean returnValue; g_signal_emit(webView, signals[CONTEXT_MENU], 0, contextMenu.get(), contextMenuEvent.get(), hitTestResult.get(), &returnValue); if (returnValue) return; - Vector<ContextMenuItem> contextMenuItems; + Vector<WebContextMenuItemGtk> contextMenuItems; webkitContextMenuPopulate(contextMenu.get(), contextMenuItems); contextMenuProxy->populate(contextMenuItems); @@ -1871,7 +2087,9 @@ void webkitWebViewSubmitFormRequest(WebKitWebView* webView, WebKitFormSubmission void webkitWebViewHandleAuthenticationChallenge(WebKitWebView* webView, AuthenticationChallengeProxy* authenticationChallenge) { - gboolean privateBrowsingEnabled = webkit_settings_get_enable_private_browsing(webkit_web_view_get_settings(webView)); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + gboolean privateBrowsingEnabled = webView->priv->isEphemeral || webkit_settings_get_enable_private_browsing(webView->priv->settings.get()); + G_GNUC_END_IGNORE_DEPRECATIONS; webView->priv->authenticationRequest = adoptGRef(webkitAuthenticationRequestCreate(authenticationChallenge, privateBrowsingEnabled)); gboolean returnValue; g_signal_emit(webView, signals[AUTHENTICATE], 0, webView->priv->authenticationRequest.get(), &returnValue); @@ -1882,12 +2100,51 @@ void webkitWebViewInsecureContentDetected(WebKitWebView* webView, WebKitInsecure g_signal_emit(webView, signals[INSECURE_CONTENT_DETECTED], 0, type); } +bool webkitWebViewEmitShowNotification(WebKitWebView* webView, WebKitNotification* webNotification) +{ + gboolean handled; + g_signal_emit(webView, signals[SHOW_NOTIFICATION], 0, webNotification, &handled); + return handled; +} + +bool webkitWebViewEmitRunColorChooser(WebKitWebView* webView, WebKitColorChooserRequest* request) +{ + gboolean handled; + g_signal_emit(webView, signals[RUN_COLOR_CHOOSER], 0, request, &handled); + return handled; +} + +void webkitWebViewSelectionDidChange(WebKitWebView* webView) +{ + if (!webView->priv->editorState) + return; + + webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView)->editorState()); +} + +void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView* webView, InstallMissingMediaPluginsPermissionRequest& request) +{ +#if ENABLE(VIDEO) + GRefPtr<WebKitInstallMissingMediaPluginsPermissionRequest> installMediaPluginsPermissionRequest = adoptGRef(webkitInstallMissingMediaPluginsPermissionRequestCreate(request)); + webkitWebViewMakePermissionRequest(webView, WEBKIT_PERMISSION_REQUEST(installMediaPluginsPermissionRequest.get())); +#else + ASSERT_NOT_REACHED(); +#endif +} + +WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView* webView) +{ + return webView->priv->websiteDataManager.get(); +} + /** * webkit_web_view_new: * - * Creates a new #WebKitWebView with the default #WebKitWebContext and the - * default #WebKitWebViewGroup. - * See also webkit_web_view_new_with_context() and webkit_web_view_new_with_group(). + * Creates a new #WebKitWebView with the default #WebKitWebContext and + * no #WebKitUserContentManager associated with it. + * See also webkit_web_view_new_with_context(), + * webkit_web_view_new_with_user_content_manager(), and + * webkit_web_view_new_with_settings(). * * Returns: The newly created #WebKitWebView widget */ @@ -1900,9 +2157,10 @@ GtkWidget* webkit_web_view_new() * webkit_web_view_new_with_context: * @context: the #WebKitWebContext to be used by the #WebKitWebView * - * Creates a new #WebKitWebView with the given #WebKitWebContext and the - * default #WebKitWebViewGroup. - * See also webkit_web_view_new_with_group(). + * Creates a new #WebKitWebView with the given #WebKitWebContext and + * no #WebKitUserContentManager associated with it. + * See also webkit_web_view_new_with_user_content_manager() and + * webkit_web_view_new_with_settings(). * * Returns: The newly created #WebKitWebView widget */ @@ -1910,7 +2168,10 @@ GtkWidget* webkit_web_view_new_with_context(WebKitWebContext* context) { g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), 0); - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "web-context", context, NULL)); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, + "is-ephemeral", webkit_web_context_is_ephemeral(context), + "web-context", context, + nullptr)); } /** @@ -1925,6 +2186,9 @@ GtkWidget* webkit_web_view_new_with_context(WebKitWebContext* context) * You can also use this method to implement other process models based on %WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES, * like for example, sharing the same web process for all the views in the same security domain. * + * The newly created #WebKitWebView will also have the same #WebKitUserContentManager + * and #WebKitSettings as @web_view. + * * Returns: (transfer full): The newly created #WebKitWebView widget * * Since: 2.4 @@ -1933,24 +2197,48 @@ GtkWidget* webkit_web_view_new_with_related_view(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "related-view", webView, nullptr)); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, + "user-content-manager", webView->priv->userContentManager.get(), + "settings", webView->priv->settings.get(), + "related-view", webView, + nullptr)); } /** - * webkit_web_view_new_with_group: - * @group: a #WebKitWebViewGroup + * webkit_web_view_new_with_settings: + * @settings: a #WebKitSettings * - * Creates a new #WebKitWebView with the given #WebKitWebViewGroup. - * The view will be part of @group and it will be affected by the - * group properties like the settings. + * Creates a new #WebKitWebView with the given #WebKitSettings. + * See also webkit_web_view_new_with_context(), and + * webkit_web_view_new_with_user_content_manager(). * * Returns: The newly created #WebKitWebView widget + * + * Since: 2.6 */ -GtkWidget* webkit_web_view_new_with_group(WebKitWebViewGroup* group) +GtkWidget* webkit_web_view_new_with_settings(WebKitSettings* settings) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), nullptr); + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "settings", settings, nullptr)); +} - return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "group", group, NULL)); +/** + * webkit_web_view_new_with_user_content_manager: + * @user_content_manager: a #WebKitUserContentManager. + * + * Creates a new #WebKitWebView with the given #WebKitUserContentManager. + * The content loaded in the view may be affected by the content injected + * in the view by the user content manager. + * + * Returns: The newly created #WebKitWebView widget + * + * Since: 2.6 + */ +GtkWidget* webkit_web_view_new_with_user_content_manager(WebKitUserContentManager* userContentManager) +{ + g_return_val_if_fail(WEBKIT_IS_USER_CONTENT_MANAGER(userContentManager), nullptr); + + return GTK_WIDGET(g_object_new(WEBKIT_TYPE_WEB_VIEW, "user-content-manager", userContentManager, nullptr)); } /** @@ -1965,25 +2253,86 @@ WebKitWebContext* webkit_web_view_get_context(WebKitWebView *webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - return webView->priv->context; + return webView->priv->context.get(); } /** - * webkit_web_view_get_group: + * webkit_web_view_get_user_content_manager: * @web_view: a #WebKitWebView * - * Gets the group @web_view belongs to. + * Gets the user content manager associated to @web_view, or %NULL if the + * view does not have an user content manager. + * + * Returns: (transfer none): the #WebKitUserContentManager associated with the view * - * Returns: (transfer none): the #WebKitWebViewGroup to which the view belongs + * Since: 2.6 */ -WebKitWebViewGroup* webkit_web_view_get_group(WebKitWebView* webView) +WebKitUserContentManager* webkit_web_view_get_user_content_manager(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); - if (webView->priv->group) - return webView->priv->group.get(); + return webView->priv->userContentManager.get(); +} - return webkitWebContextGetDefaultWebViewGroup(webView->priv->context); +/** + * webkit_web_view_is_ephemeral: + * @web_view: a #WebKitWebView + * + * Get whether a #WebKitWebView is ephemeral. To create an ephemeral #WebKitWebView you need to + * use g_object_new() and pass is-ephemeral propery with %TRUE value. See + * #WebKitWebView:is-ephemeral for more details. + * If @web_view was created with a ephemeral #WebKitWebView:related-view or an + * ephemeral #WebKitWebView:web-context it will also be ephemeral. + * + * Returns: %TRUE if @web_view is ephemeral or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_web_view_is_ephemeral(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return webView->priv->isEphemeral; +} + +/** + * webkit_web_view_get_website_data_manager: + * @web_view: a #WebKitWebView + * + * Get the #WebKitWebsiteDataManager associated to @web_view. If @web_view is not ephemeral, + * the returned #WebKitWebsiteDataManager will be the same as the #WebKitWebsiteDataManager + * of @web_view's #WebKitWebContext. + * + * Returns: (transfer none): a #WebKitWebsiteDataManager + * + * Since: 2.16 + */ +WebKitWebsiteDataManager* webkit_web_view_get_website_data_manager(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + if (webView->priv->websiteDataManager) + return webView->priv->websiteDataManager.get(); + + return webkit_web_context_get_website_data_manager(webView->priv->context.get()); +} + +/** + * webkit_web_view_try_close: + * @web_view: a #WebKitWebView + * + * Tries to close the @web_view. This will fire the onbeforeunload event + * to ask the user for confirmation to close the page. If there isn't an + * onbeforeunload event handler or the user confirms to close the page, + * the #WebKitWebView::close signal is emitted, otherwise nothing happens. + * + * Since: 2.12 + */ +void webkit_web_view_try_close(WebKitWebView *webView) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + if (getPage(webView)->tryClose()) + webkitWebViewClosePage(webView); } /** @@ -2067,6 +2416,45 @@ void webkit_web_view_load_plain_text(WebKitWebView* webView, const gchar* plainT getPage(webView)->loadPlainTextString(String::fromUTF8(plainText)); } +static void releaseGBytes(unsigned char*, const void* bytes) +{ + // Balanced by g_bytes_ref in webkit_web_view_load_bytes(). + g_bytes_unref(static_cast<GBytes*>(const_cast<void*>(bytes))); +} + +/** + * webkit_web_view_load_bytes: + * @web_view: a #WebKitWebView + * @bytes: input data to load + * @mime_type: (allow-none): the MIME type of @bytes, or %NULL + * @encoding: (allow-none): the character encoding of @bytes, or %NULL + * @base_uri: (allow-none): the base URI for relative locations or %NULL + * + * Load the specified @bytes into @web_view using the given @mime_type and @encoding. + * When @mime_type is %NULL, it defaults to "text/html". + * When @encoding is %NULL, it defaults to "UTF-8". + * When @base_uri is %NULL, it defaults to "about:blank". + * You can monitor the load operation by connecting to #WebKitWebView::load-changed signal. + * + * Since: 2.6 + */ +void webkit_web_view_load_bytes(WebKitWebView* webView, GBytes* bytes, const char* mimeType, const char* encoding, const char* baseURI) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(bytes); + + gsize bytesDataSize; + gconstpointer bytesData = g_bytes_get_data(bytes, &bytesDataSize); + g_return_if_fail(bytesDataSize); + + // Balanced by g_bytes_unref in releaseGBytes. + g_bytes_ref(bytes); + + Ref<API::Data> data = API::Data::createWithoutCopying(static_cast<const unsigned char*>(bytesData), bytesDataSize, releaseGBytes, bytes); + getPage(webView)->loadData(data.ptr(), mimeType ? String::fromUTF8(mimeType) : String::fromUTF8("text/html"), + encoding ? String::fromUTF8(encoding) : String::fromUTF8("UTF-8"), String::fromUTF8(baseURI)); +} + /** * webkit_web_view_load_request: * @web_view: a #WebKitWebView @@ -2130,7 +2518,9 @@ void webkit_web_view_reload(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - getPage(webView)->reload(false); + const bool reloadFromOrigin = false; + const bool contentBlockersEnabled = true; + getPage(webView)->reload(reloadFromOrigin, contentBlockersEnabled); } /** @@ -2144,7 +2534,9 @@ void webkit_web_view_reload_bypass_cache(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - getPage(webView)->reload(true); + const bool reloadFromOrigin = true; + const bool contentBlockersEnabled = true; + getPage(webView)->reload(reloadFromOrigin, contentBlockersEnabled); } /** @@ -2185,6 +2577,27 @@ gboolean webkit_web_view_is_loading(WebKitWebView* webView) } /** + * webkit_web_view_is_playing_audio: + * @web_view: a #WebKitWebView + * + * Gets the value of the #WebKitWebView:is-playing-audio property. + * You can monitor when a page in a #WebKitWebView is playing audio by + * connecting to the notify::is-playing-audio signal of @web_view. This + * is useful when the application wants to provide visual feedback when a + * page is producing sound. + * + * Returns: %TRUE if a page in @web_view is playing audio or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_view_is_playing_audio(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return getPage(webView)->isPlayingAudio(); +} + +/** * webkit_web_view_go_back: * @web_view: a #WebKitWebView * @@ -2382,7 +2795,7 @@ void webkit_web_view_set_custom_charset(WebKitWebView* webView, const gchar* cha gdouble webkit_web_view_get_estimated_load_progress(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - return webView->priv->estimatedLoadProgress; + return getPage(webView)->pageLoadState().estimatedProgress(); } /** @@ -2423,16 +2836,30 @@ void webkit_web_view_go_to_back_forward_list_item(WebKitWebView* webView, WebKit * @web_view: a #WebKitWebView * @settings: a #WebKitSettings * - * Sets the #WebKitSettings to be applied to @web_view. - * This is a convenient method to set new settings to the - * #WebKitWebViewGroup @web_view belongs to. - * New settings are applied immediately on all #WebKitWebView<!-- -->s - * in the @web_view group. - * See also webkit_web_view_group_set_settings(). + * Sets the #WebKitSettings to be applied to @web_view. The + * existing #WebKitSettings of @web_view will be replaced by + * @settings. New settings are applied immediately on @web_view. + * The same #WebKitSettings object can be shared + * by multiple #WebKitWebView<!-- -->s. */ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings) { - webkit_web_view_group_set_settings(webkit_web_view_get_group(webView), settings); + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + if (webView->priv->settings == settings) + return; + + // The "settings" property is set on construction, and in that + // case webkit_web_view_set_settings() will be called *before* + // any settings have been assigned. In that case there are no + // signal handlers to disconnect. + if (webView->priv->settings) + webkitWebViewDisconnectSettingsSignalHandlers(webView); + + webView->priv->settings = settings; + webkitWebViewUpdateSettings(webView); + g_object_notify(G_OBJECT(webView), "settings"); } /** @@ -2440,19 +2867,25 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settin * @web_view: a #WebKitWebView * * Gets the #WebKitSettings currently applied to @web_view. - * This is a convenient method to get the settings of the - * #WebKitWebViewGroup @web_view belongs to. - * #WebKitSettings objects are shared by all the #WebKitWebView<!-- -->s - * in the same #WebKitWebViewGroup, so modifying + * If no other #WebKitSettings have been explicitly applied to + * @web_view with webkit_web_view_set_settings(), the default + * #WebKitSettings will be returned. This method always returns + * a valid #WebKitSettings object. + * To modify any of the @web_view settings, you can either create + * a new #WebKitSettings object with webkit_settings_new(), setting + * the desired preferences, and then replace the existing @web_view + * settings with webkit_web_view_set_settings() or get the existing + * @web_view settings and update it directly. #WebKitSettings objects + * can be shared by multiple #WebKitWebView<!-- -->s, so modifying * the settings of a #WebKitWebView would affect other - * #WebKitWebView<!-- -->s of the same group. - * See also webkit_web_view_group_get_settings(). + * #WebKitWebView<!-- -->s using the same #WebKitSettings. * * Returns: (transfer none): the #WebKitSettings attached to @web_view */ WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView) { - return webkit_web_view_group_get_settings(webkit_web_view_get_group(webView)); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + return webView->priv->settings.get(); } /** @@ -2487,7 +2920,7 @@ void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel) return; WebPageProxy* page = getPage(webView); - if (webkit_settings_get_zoom_text_only(webkit_web_view_get_settings(webView))) + if (webkit_settings_get_zoom_text_only(webView->priv->settings.get())) page->setTextZoomFactor(zoomLevel); else page->setPageZoomFactor(zoomLevel); @@ -2508,16 +2941,10 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView) g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1); WebPageProxy* page = getPage(webView); - gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webkit_web_view_get_settings(webView)); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get()); return zoomTextOnly ? page->textZoomFactor() : page->pageZoomFactor(); } -static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t state, WKErrorRef, void* context) -{ - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - g_task_return_boolean(task.get(), isEnabled); -} - /** * webkit_web_view_can_execute_editing_command: * @web_view: a #WebKitWebView @@ -2526,7 +2953,7 @@ static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t stat * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied * @user_data: (closure): the data to pass to callback function * - * Asynchronously execute the given editing command. + * Asynchronously check if it is possible to execute the given editing command. * * When the operation is finished, @callback will be called. You can then call * webkit_web_view_can_execute_editing_command_finish() to get the result of the operation. @@ -2537,7 +2964,9 @@ void webkit_web_view_can_execute_editing_command(WebKitWebView* webView, const c g_return_if_fail(command); GTask* task = g_task_new(webView, cancellable, callback, userData); - getPage(webView)->validateCommand(String::fromUTF8(command), ValidateCommandCallback::create(task, didValidateCommand)); + getPage(webView)->validateCommand(String::fromUTF8(command), [task](const String&, bool isEnabled, int32_t, WebKit::CallbackBase::Error) { + g_task_return_boolean(adoptGRef(task).get(), isEnabled); + }); } /** @@ -2576,6 +3005,27 @@ void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* } /** + * webkit_web_view_execute_editing_command_with_argument: + * @web_view: a #WebKitWebView + * @command: the command to execute + * @argument: the command argument + * + * Request to execute the given @command with @argument for @web_view. You can use + * webkit_web_view_can_execute_editing_command() to check whether + * it's possible to execute the command. + * + * Since: 2.10 + */ +void webkit_web_view_execute_editing_command_with_argument(WebKitWebView* webView, const char* command, const char* argument) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(command); + g_return_if_fail(argument); + + getPage(webView)->executeEditCommand(String::fromUTF8(command), String::fromUTF8(argument)); +} + +/** * webkit_web_view_get_find_controller: * @web_view: the #WebKitWebView * @@ -2614,20 +3064,20 @@ JSGlobalContextRef webkit_web_view_get_javascript_global_context(WebKitWebView* return webView->priv->javascriptGlobalContext; } -static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSerializedScriptValue, WKErrorRef, void* context) +static void webkitWebViewRunJavaScriptCallback(API::SerializedScriptValue* wkSerializedScriptValue, GTask* task) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); - if (g_task_return_error_if_cancelled(task.get())) + if (g_task_return_error_if_cancelled(task)) return; if (!wkSerializedScriptValue) { - g_task_return_new_error(task.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, + g_task_return_new_error(task, WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED, _("An exception was raised in JavaScript")); return; } - WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get())); - g_task_return_pointer(task.get(), webkitJavascriptResultCreate(webView, toImpl(wkSerializedScriptValue)), + WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task)); + g_task_return_pointer(task, webkitJavascriptResultCreate(webView, + *wkSerializedScriptValue->internalRepresentation()), reinterpret_cast<GDestroyNotify>(webkit_javascript_result_unref)); } @@ -2640,7 +3090,7 @@ static void webkitWebViewRunJavaScriptCallback(WKSerializedScriptValueRef wkSeri * @user_data: (closure): the data to pass to callback function * * Asynchronously run @script in the context of the current page in @web_view. If - * WebKitWebSettings:enable-javascript is FALSE, this method will do nothing. + * WebKitSettings:enable-javascript is FALSE, this method will do nothing. * * When the operation is finished, @callback will be called. You can then call * webkit_web_view_run_javascript_finish() to get the result of the operation. @@ -2651,7 +3101,9 @@ void webkit_web_view_run_javascript(WebKitWebView* webView, const gchar* script, g_return_if_fail(script); GTask* task = g_task_new(webView, cancellable, callback, userData); - getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(script), ScriptValueCallback::create(task, webkitWebViewRunJavaScriptCallback)); + getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(script), [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails&, WebKit::CallbackBase::Error) { + webkitWebViewRunJavaScriptCallback(serializedScriptValue, adoptGRef(task).get()); + }); } /** @@ -2740,7 +3192,9 @@ static void resourcesStreamReadCallback(GObject* object, GAsyncResult* result, g WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get())); gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object)); getPage(webView)->runJavaScriptInMainFrame(String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), - ScriptValueCallback::create(task.leakRef(), webkitWebViewRunJavaScriptCallback)); + [task](API::SerializedScriptValue* serializedScriptValue, bool, const WebCore::ExceptionDetails&, WebKit::CallbackBase::Error) { + webkitWebViewRunJavaScriptCallback(serializedScriptValue, task.get()); + }); } /** @@ -2867,16 +3321,16 @@ static void fileReplaceContentsCallback(GObject* object, GAsyncResult* result, g g_task_return_boolean(task.get(), TRUE); } -static void getContentsAsMHTMLDataCallback(WKDataRef wkData, WKErrorRef, void* context) +static void getContentsAsMHTMLDataCallback(API::Data* wkData, GTask* taskPtr) { - GRefPtr<GTask> task = adoptGRef(G_TASK(context)); + auto task = adoptGRef(taskPtr); if (g_task_return_error_if_cancelled(task.get())) return; ViewSaveAsyncData* data = static_cast<ViewSaveAsyncData*>(g_task_get_task_data(task.get())); // We need to retain the data until the asyncronous process // initiated by the user has finished completely. - data->webData = toImpl(wkData); + data->webData = wkData; // If we are saving to a file we need to write the data on disk before finishing. if (g_task_get_source_tag(task.get()) == webkit_web_view_save_to_file) { @@ -2916,7 +3370,9 @@ void webkit_web_view_save(WebKitWebView* webView, WebKitSaveMode saveMode, GCanc GTask* task = g_task_new(webView, cancellable, callback, userData); g_task_set_source_tag(task, reinterpret_cast<gpointer>(webkit_web_view_save)); g_task_set_task_data(task, createViewSaveAsyncData(), reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData)); - getPage(webView)->getContentsAsMHTMLData(DataCallback::create(task, getContentsAsMHTMLDataCallback), false); + getPage(webView)->getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) { + getContentsAsMHTMLDataCallback(data, task); + }); } /** @@ -2979,7 +3435,9 @@ void webkit_web_view_save_to_file(WebKitWebView* webView, GFile* file, WebKitSav data->file = file; g_task_set_task_data(task, data, reinterpret_cast<GDestroyNotify>(destroyViewSaveAsyncData)); - getPage(webView)->getContentsAsMHTMLData(DataCallback::create(task, getContentsAsMHTMLDataCallback), false); + getPage(webView)->getContentsAsMHTMLData([task](API::Data* data, WebKit::CallbackBase::Error) { + getContentsAsMHTMLDataCallback(data, task); + }); } /** @@ -3012,50 +3470,11 @@ gboolean webkit_web_view_save_to_file_finish(WebKitWebView* webView, GAsyncResul */ WebKitDownload* webkit_web_view_download_uri(WebKitWebView* webView, const char* uri) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - g_return_val_if_fail(uri, 0); - - WebKitDownload* download = webkitWebContextStartDownload(webView->priv->context, uri, getPage(webView)); - webkitDownloadSetWebView(download, webView); - - return download; -} - -/** - * webkit_web_view_set_view_mode: - * @web_view: a #WebKitWebView - * @view_mode: a #WebKitViewMode - * - * Set the view mode of @web_view to @view_mode. This method should be called - * before loading new contents on @web_view so that the new #WebKitViewMode will - * be applied to the new contents. - */ -void webkit_web_view_set_view_mode(WebKitWebView* webView, WebKitViewMode viewMode) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - - if (webView->priv->viewMode == viewMode) - return; - - getPage(webView)->setMainFrameInViewSourceMode(viewMode == WEBKIT_VIEW_MODE_SOURCE); - - webView->priv->viewMode = viewMode; - g_object_notify(G_OBJECT(webView), "view-mode"); -} - -/** - * webkit_web_view_get_view_mode: - * @web_view: a #WebKitWebView - * - * Get the view mode of @web_view. - * - * Returns: the #WebKitViewMode of @web_view. - */ -WebKitViewMode webkit_web_view_get_view_mode(WebKitWebView* webView) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), WEBKIT_VIEW_MODE_WEB); + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + g_return_val_if_fail(uri, nullptr); - return webView->priv->viewMode; + GRefPtr<WebKitDownload> download = webkitWebContextStartDownload(webView->priv->context.get(), uri, getPage(webView)); + return download.leakRef(); } /** @@ -3073,10 +3492,10 @@ WebKitViewMode webkit_web_view_get_view_mode(WebKitWebView* webView) * when it's emitted with %WEBKIT_LOAD_COMMITTED event. * * Note that this function provides no information about the security of the web - * page if the current #WebKitTLSErrorsPolicy is %WEBKIT_TLS_ERRORS_POLICY_IGNORE, + * page if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_IGNORE, * as subresources of the page may be controlled by an attacker. This function * may safely be used to determine the security status of the current page only - * if the current #WebKitTLSErrorsPolicy is %WEBKIT_TLS_ERRORS_POLICY_FAIL, in + * if the current #WebKitTLSErrorsPolicy is @WEBKIT_TLS_ERRORS_POLICY_FAIL, in * which case subresources that fail certificate verification will be blocked. * * Returns: %TRUE if the @web_view connection uses HTTPS and a response has been received @@ -3090,7 +3509,10 @@ gboolean webkit_web_view_get_tls_info(WebKitWebView* webView, GTlsCertificate** if (!mainFrame) return FALSE; - const WebCore::CertificateInfo& certificateInfo = mainFrame->certificateInfo()->certificateInfo(); + auto* wkCertificateInfo = mainFrame->certificateInfo(); + g_return_val_if_fail(wkCertificateInfo, FALSE); + + const auto& certificateInfo = wkCertificateInfo->certificateInfo(); if (certificate) *certificate = certificateInfo.certificate(); if (errors) @@ -3111,15 +3533,9 @@ void webKitWebViewDidReceiveSnapshot(WebKitWebView* webView, uint64_t callbackID return; } - if (RefPtr<ShareableBitmap> image = webImage->bitmap()) - g_task_return_pointer(task.get(), image->createCairoSurface().leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy)); - else - g_task_return_pointer(task.get(), 0, 0); + g_task_return_pointer(task.get(), webImage->bitmap().createCairoSurface().leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy)); } -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_SNAPSHOT_REGION_VISIBLE, SnapshotRegionVisible); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT, SnapshotRegionFullDocument); - static inline unsigned webKitSnapshotOptionsToSnapshotOptions(WebKitSnapshotOptions options) { SnapshotOptions snapshotOptions = 0; @@ -3130,6 +3546,19 @@ static inline unsigned webKitSnapshotOptionsToSnapshotOptions(WebKitSnapshotOpti return snapshotOptions; } +static inline SnapshotRegion toSnapshotRegion(WebKitSnapshotRegion region) +{ + switch (region) { + case WEBKIT_SNAPSHOT_REGION_VISIBLE: + return SnapshotRegionVisible; + case WEBKIT_SNAPSHOT_REGION_FULL_DOCUMENT: + return SnapshotRegionFullDocument; + default: + ASSERT_NOT_REACHED(); + return SnapshotRegionVisible; + } +} + static inline uint64_t generateSnapshotCallbackID() { static uint64_t uniqueCallbackID = 1; @@ -3139,8 +3568,8 @@ static inline uint64_t generateSnapshotCallbackID() /** * webkit_web_view_get_snapshot: * @web_view: a #WebKitWebView - * @options: #WebKitSnapshotOptions for the snapshot * @region: the #WebKitSnapshotRegion for this snapshot + * @options: #WebKitSnapshotOptions for the snapshot * @cancellable: (allow-none): a #GCancellable * @callback: (scope async): a #GAsyncReadyCallback * @user_data: (closure): user data @@ -3156,14 +3585,15 @@ void webkit_web_view_get_snapshot(WebKitWebView* webView, WebKitSnapshotRegion r { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - ImmutableDictionary::MapType message; + API::Dictionary::MapType message; uint64_t callbackID = generateSnapshotCallbackID(); message.set(String::fromUTF8("SnapshotOptions"), API::UInt64::create(static_cast<uint64_t>(webKitSnapshotOptionsToSnapshotOptions(options)))); - message.set(String::fromUTF8("SnapshotRegion"), API::UInt64::create(static_cast<uint64_t>(region))); + message.set(String::fromUTF8("SnapshotRegion"), API::UInt64::create(static_cast<uint64_t>(toSnapshotRegion(region)))); message.set(String::fromUTF8("CallbackID"), API::UInt64::create(callbackID)); + message.set(String::fromUTF8("TransparentBackground"), API::Boolean::create(options & WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND)); webView->priv->snapshotResultsMap.set(callbackID, adoptGRef(g_task_new(webView, cancellable, callback, userData))); - getPage(webView)->postMessageToInjectedBundle(String::fromUTF8("GetSnapshot"), ImmutableDictionary::create(std::move(message)).get()); + getPage(webView)->postMessageToInjectedBundle(String::fromUTF8("GetSnapshot"), API::Dictionary::create(WTFMove(message)).ptr()); } /** @@ -3190,3 +3620,173 @@ void webkitWebViewWebProcessCrashed(WebKitWebView* webView) g_signal_emit(webView, signals[WEB_PROCESS_CRASHED], 0, &returnValue); } +/** + * webkit_web_view_set_background_color: + * @web_view: a #WebKitWebView + * @rgba: a #GdkRGBA + * + * Sets the color that will be used to draw the @web_view background before + * the actual contents are rendered. Note that if the web page loaded in @web_view + * specifies a background color, it will take precedence over the @rgba color. + * By default the @web_view background color is opaque white. + * Note that the parent window must have a RGBA visual and + * #GtkWidget:app-paintable property set to %TRUE for backgrounds colors to work. + * + * <informalexample><programlisting> + * static void browser_window_set_background_color (BrowserWindow *window, + * const GdkRGBA *rgba) + * { + * WebKitWebView *web_view; + * GdkScreen *screen = gtk_window_get_screen (GTK_WINDOW (window)); + * GdkVisual *rgba_visual = gdk_screen_get_rgba_visual (screen); + * + * if (!rgba_visual) + * return; + * + * gtk_widget_set_visual (GTK_WIDGET (window), rgba_visual); + * gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + * + * web_view = browser_window_get_web_view (window); + * webkit_web_view_set_background_color (web_view, rgba); + * } + * </programlisting></informalexample> + * + * Since: 2.8 + */ +void webkit_web_view_set_background_color(WebKitWebView* webView, const GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(rgba); + + Color color(*rgba); + WebPageProxy* page = getPage(webView); + if (page->backgroundColor() == color) + return; + + page->setBackgroundColor(color); + page->setDrawsBackground(color == Color::white); +} + +/** + * webkit_web_view_get_background_color: + * @web_view: a #WebKitWebView + * @rgba: (out): a #GdkRGBA to fill in with the background color + * + * Gets the color that is used to draw the @web_view background before + * the actual contents are rendered. + * For more information see also webkit_web_view_set_background_color() + * + * Since: 2.8 + */ +void webkit_web_view_get_background_color(WebKitWebView* webView, GdkRGBA* rgba) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(rgba); + + *rgba = getPage(webView)->backgroundColor(); +} + +/* + * webkit_web_view_is_editable: + * @web_view: a #WebKitWebView + * + * Gets whether the user is allowed to edit the HTML document. When @web_view + * is not editable an element in the HTML document can only be edited if the + * CONTENTEDITABLE attribute has been set on the element or one of its parent + * elements. By default a #WebKitWebView is not editable. + * + * Returns: %TRUE if the user is allowed to edit the HTML document, or %FALSE otherwise. + * + * Since: 2.8 + */ +gboolean webkit_web_view_is_editable(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE); + + return getPage(webView)->isEditable(); +} + +/** + * webkit_web_view_set_editable: + * @web_view: a #WebKitWebView + * @editable: a #gboolean indicating the editable state + * + * Sets whether the user is allowed to edit the HTML document. + * + * If @editable is %TRUE, @web_view allows the user to edit the HTML document. If + * @editable is %FALSE, an element in @web_view's document can only be edited if the + * CONTENTEDITABLE attribute has been set on the element or one of its parent + * elements. By default a #WebKitWebView is not editable. + * + * Normally, a HTML document is not editable unless the elements within the + * document are editable. This function provides a way to make the contents + * of a #WebKitWebView editable without altering the document or DOM structure. + * + * Since: 2.8 + */ +void webkit_web_view_set_editable(WebKitWebView* webView, gboolean editable) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + + if (editable == getPage(webView)->isEditable()) + return; + + getPage(webView)->setEditable(editable); + + g_object_notify(G_OBJECT(webView), "editable"); +} + +/** + * webkit_web_view_get_editor_state: + * @web_view: a #WebKitWebView + * + * Gets the web editor state of @web_view. + * + * Returns: (transfer none): the #WebKitEditorState of the view + * + * Since: 2.10 + */ +WebKitEditorState* webkit_web_view_get_editor_state(WebKitWebView *webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + if (!webView->priv->editorState) + webView->priv->editorState = adoptGRef(webkitEditorStateCreate(getPage(webView)->editorState())); + + return webView->priv->editorState.get(); +} + +/** + * webkit_web_view_get_session_state: + * @web_view: a #WebKitWebView + * + * Gets the current session state of @web_view + * + * Returns: (transfer full): a #WebKitWebViewSessionState + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_get_session_state(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr); + + SessionState sessionState = getPage(webView)->sessionState(nullptr); + return webkitWebViewSessionStateCreate(WTFMove(sessionState)); +} + +/** + * webkit_web_view_restore_session_state: + * @web_view: a #WebKitWebView + * @state: a #WebKitWebViewSessionState + * + * Restore the @web_view session state from @state + * + * Since: 2.12 + */ +void webkit_web_view_restore_session_state(WebKitWebView* webView, WebKitWebViewSessionState* state) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(state); + + getPage(webView)->restoreFromSessionState(webkitWebViewSessionStateGetSessionState(state), false); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h index 493c68d18..4b524f15d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h @@ -32,22 +32,27 @@ #include <webkit2/WebKitAuthenticationRequest.h> #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitColorChooserRequest.h> +#include <webkit2/WebKitEditorState.h> #include <webkit2/WebKitFileChooserRequest.h> #include <webkit2/WebKitFindController.h> #include <webkit2/WebKitFormSubmissionRequest.h> #include <webkit2/WebKitForwardDeclarations.h> #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitJavascriptResult.h> +#include <webkit2/WebKitNavigationAction.h> +#include <webkit2/WebKitNotification.h> #include <webkit2/WebKitPermissionRequest.h> #include <webkit2/WebKitPolicyDecision.h> #include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> +#include <webkit2/WebKitUserContentManager.h> #include <webkit2/WebKitWebContext.h> #include <webkit2/WebKitWebInspector.h> #include <webkit2/WebKitWebResource.h> #include <webkit2/WebKitWebViewBase.h> -#include <webkit2/WebKitWebViewGroup.h> +#include <webkit2/WebKitWebViewSessionState.h> #include <webkit2/WebKitWindowProperties.h> G_BEGIN_DECLS @@ -150,23 +155,12 @@ typedef enum { } WebKitInsecureContentEvent; /** - * WebKitViewMode: - * @WEBKIT_VIEW_MODE_WEB: The normal view mode to display web contents. - * @WEBKIT_VIEW_MODE_SOURCE: The source mode to display web source code. - * - * Enum values to specify the different ways in which a #WebKitWebView - * can display a web page. - */ -typedef enum { - WEBKIT_VIEW_MODE_WEB, - WEBKIT_VIEW_MODE_SOURCE -} WebKitViewMode; - -/** * WebKitSnapshotOptions: * @WEBKIT_SNAPSHOT_OPTIONS_NONE: Do not include any special options. * @WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING: Whether to include in the * snapshot the highlight of the selected content. + * @WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND: Do not fill the background with white before + * rendering the snapshot. Since 2.8 * * Enum values used to specify options when taking a snapshot * from a #WebKitWebView. @@ -174,6 +168,7 @@ typedef enum { typedef enum { WEBKIT_SNAPSHOT_OPTIONS_NONE = 0, WEBKIT_SNAPSHOT_OPTIONS_INCLUDE_SELECTION_HIGHLIGHTING = 1 << 0, + WEBKIT_SNAPSHOT_OPTIONS_TRANSPARENT_BACKGROUND = 1 << 1, } WebKitSnapshotOptions; /** @@ -207,7 +202,8 @@ struct _WebKitWebViewClass { const gchar *failing_uri, GError *error); - GtkWidget *(* create) (WebKitWebView *web_view); + GtkWidget *(* create) (WebKitWebView *web_view, + WebKitNavigationAction *navigation_action); void (* ready_to_show) (WebKitWebView *web_view); void (* run_as_modal) (WebKitWebView *web_view); void (* close) (WebKitWebView *web_view); @@ -246,14 +242,18 @@ struct _WebKitWebViewClass { gboolean (* authenticate) (WebKitWebView *web_view, WebKitAuthenticationRequest *request); gboolean (* load_failed_with_tls_errors) (WebKitWebView *web_view, - WebKitCertificateInfo *info, - const gchar *host); + const gchar *failing_uri, + GTlsCertificate *certificate, + GTlsCertificateFlags errors); + gboolean (* show_notification) (WebKitWebView *web_view, + WebKitNotification *notification); + gboolean (* run_color_chooser) (WebKitWebView *web_view, + WebKitColorChooserRequest *request); + void (*_webkit_reserved0) (void); void (*_webkit_reserved1) (void); void (*_webkit_reserved2) (void); void (*_webkit_reserved3) (void); - void (*_webkit_reserved4) (void); - void (*_webkit_reserved5) (void); }; WEBKIT_API GType @@ -266,16 +266,25 @@ WEBKIT_API GtkWidget * webkit_web_view_new_with_context (WebKitWebContext *context); WEBKIT_API GtkWidget * +webkit_web_view_new_with_settings (WebKitSettings *settings); + +WEBKIT_API GtkWidget * webkit_web_view_new_with_related_view (WebKitWebView *web_view); WEBKIT_API GtkWidget * -webkit_web_view_new_with_group (WebKitWebViewGroup *group); +webkit_web_view_new_with_user_content_manager (WebKitUserContentManager *user_content_manager); + +WEBKIT_API gboolean +webkit_web_view_is_ephemeral (WebKitWebView *web_view); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_web_view_get_website_data_manager (WebKitWebView *web_view); WEBKIT_API WebKitWebContext * webkit_web_view_get_context (WebKitWebView *web_view); -WEBKIT_API WebKitWebViewGroup * -webkit_web_view_get_group (WebKitWebView *web_view); +WEBKIT_API void +webkit_web_view_try_close (WebKitWebView *web_view); WEBKIT_API void webkit_web_view_load_uri (WebKitWebView *web_view, @@ -295,6 +304,13 @@ webkit_web_view_load_plain_text (WebKitWebView const gchar *plain_text); WEBKIT_API void +webkit_web_view_load_bytes (WebKitWebView *web_view, + GBytes *bytes, + const gchar *mime_type, + const gchar *encoding, + const gchar *base_uri); + +WEBKIT_API void webkit_web_view_load_request (WebKitWebView *web_view, WebKitURIRequest *request); @@ -304,6 +320,9 @@ webkit_web_view_stop_loading (WebKitWebView WEBKIT_API gboolean webkit_web_view_is_loading (WebKitWebView *web_view); +WEBKIT_API gboolean +webkit_web_view_is_playing_audio (WebKitWebView *web_view); + WEBKIT_API guint64 webkit_web_view_get_page_id (WebKitWebView *web_view); @@ -382,6 +401,11 @@ WEBKIT_API void webkit_web_view_execute_editing_command (WebKitWebView *web_view, const gchar *command); +WEBKIT_API void +webkit_web_view_execute_editing_command_with_argument(WebKitWebView *web_view, + const char *command, + const char *argument); + WEBKIT_API WebKitFindController * webkit_web_view_get_find_controller (WebKitWebView *web_view); @@ -450,13 +474,6 @@ WEBKIT_API WebKitDownload * webkit_web_view_download_uri (WebKitWebView *web_view, const char *uri); -WEBKIT_API void -webkit_web_view_set_view_mode (WebKitWebView *web_view, - WebKitViewMode view_mode); - -WEBKIT_API WebKitViewMode -webkit_web_view_get_view_mode (WebKitWebView *web_view); - WEBKIT_API gboolean webkit_web_view_get_tls_info (WebKitWebView *web_view, GTlsCertificate **certificate, @@ -473,6 +490,35 @@ WEBKIT_API cairo_surface_t * webkit_web_view_get_snapshot_finish (WebKitWebView *web_view, GAsyncResult *result, GError **error); + +WEBKIT_API WebKitUserContentManager * +webkit_web_view_get_user_content_manager (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_set_background_color (WebKitWebView *web_view, + const GdkRGBA *rgba); + +WEBKIT_API void +webkit_web_view_get_background_color (WebKitWebView *web_view, + GdkRGBA *rgba); + +WEBKIT_API gboolean +webkit_web_view_is_editable (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_set_editable (WebKitWebView *web_view, + gboolean editable); + +WEBKIT_API WebKitEditorState * +webkit_web_view_get_editor_state (WebKitWebView *web_view); + +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_get_session_state (WebKitWebView *web_view); + +WEBKIT_API void +webkit_web_view_restore_session_state (WebKitWebView *web_view, + WebKitWebViewSessionState *state); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp index b22c71fa1..b057a5a44 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp @@ -29,15 +29,20 @@ #include "config.h" #include "WebKitWebViewBase.h" +#include "APIPageConfiguration.h" +#include "AcceleratedBackingStore.h" +#include "ActivityState.h" #include "DrawingAreaProxyImpl.h" +#include "InputMethodFilter.h" +#include "KeyBindingTranslator.h" +#include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" #include "NativeWebWheelEvent.h" #include "PageClientImpl.h" -#include "ViewState.h" -#include "WebContext.h" #include "WebEventFactory.h" #include "WebFullScreenClientGtk.h" #include "WebInspectorProxy.h" +#include "WebKit2Initialize.h" #include "WebKitAuthenticationDialog.h" #include "WebKitPrivate.h" #include "WebKitWebViewBaseAccessible.h" @@ -45,37 +50,31 @@ #include "WebPageGroup.h" #include "WebPageProxy.h" #include "WebPreferences.h" -#include "WebViewBaseInputMethodFilter.h" +#include "WebProcessPool.h" +#include "WebUserContentControllerProxy.h" #include <WebCore/CairoUtilities.h> -#include <WebCore/ClipboardUtilitiesGtk.h> -#include <WebCore/DataObjectGtk.h> -#include <WebCore/DragData.h> -#include <WebCore/DragIcon.h> #include <WebCore/GUniquePtrGtk.h> -#include <WebCore/GtkClickCounter.h> -#include <WebCore/GtkDragAndDropHelper.h> -#include <WebCore/GtkTouchContextHelper.h> #include <WebCore/GtkUtilities.h> #include <WebCore/GtkVersioning.h> #include <WebCore/NotImplemented.h> #include <WebCore/PasteboardHelper.h> +#include <WebCore/PlatformDisplay.h> #include <WebCore/RefPtrCairo.h> #include <WebCore/Region.h> #include <gdk/gdk.h> #include <gdk/gdkkeysyms.h> -#ifdef GDK_WINDOWING_X11 -#include <gdk/gdkx.h> -#endif +#include <glib/gi18n-lib.h> +#include <memory> #include <wtf/HashMap.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #include <wtf/text/CString.h> #if ENABLE(FULLSCREEN_API) #include "WebFullScreenManagerProxy.h" #endif -#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) -#include <WebCore/RedirectedXCompositeWindow.h> +#if PLATFORM(X11) +#include <gdk/gdkx.h> #endif // gtk_widget_get_scale_factor() appeared in GTK 3.10, but we also need @@ -85,130 +84,200 @@ using namespace WebKit; using namespace WebCore; -typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap; +struct ClickCounter { +public: + void reset() + { + currentClickCount = 0; + previousClickPoint = IntPoint(); + previousClickTime = 0; + previousClickButton = 0; + } -#if USE(TEXTURE_MAPPER_GL) -void redirectedWindowDamagedCallback(void* data); -#endif + int currentClickCountForGdkButtonEvent(GdkEventButton* buttonEvent) + { + GdkEvent* event = reinterpret_cast<GdkEvent*>(buttonEvent); + int doubleClickDistance = 250; + int doubleClickTime = 5; + g_object_get(gtk_settings_get_for_screen(gdk_event_get_screen(event)), + "gtk-double-click-distance", &doubleClickDistance, "gtk-double-click-time", &doubleClickTime, nullptr); + + // GTK+ only counts up to triple clicks, but WebCore wants to know about + // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the + // GDK logic for counting clicks. + guint32 eventTime = gdk_event_get_time(event); + if (!eventTime) { + // Real events always have a non-zero time, but events synthesized + // by the WTR do not and we must calculate a time manually. This time + // is not calculated in the WTR, because GTK+ does not work well with + // anything other than GDK_CURRENT_TIME on synthesized events. + GTimeVal timeValue; + g_get_current_time(&timeValue); + eventTime = (timeValue.tv_sec * 1000) + (timeValue.tv_usec / 1000); + } + + if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) + || ((std::abs(buttonEvent->x - previousClickPoint.x()) < doubleClickDistance) + && (std::abs(buttonEvent->y - previousClickPoint.y()) < doubleClickDistance) + && (eventTime - previousClickTime < static_cast<unsigned>(doubleClickTime)) + && (buttonEvent->button == previousClickButton))) + currentClickCount++; + else + currentClickCount = 1; + + double x, y; + gdk_event_get_coords(event, &x, &y); + previousClickPoint = IntPoint(x, y); + previousClickButton = buttonEvent->button; + previousClickTime = eventTime; + + return currentClickCount; + } + +private: + int currentClickCount; + IntPoint previousClickPoint; + unsigned previousClickButton; + int previousClickTime; +}; + +typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap; +typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap; struct _WebKitWebViewBasePrivate { + _WebKitWebViewBasePrivate() + : updateActivityStateTimer(RunLoop::main(), this, &_WebKitWebViewBasePrivate::updateActivityStateTimerFired) + { + } + + void updateActivityStateTimerFired() + { + if (!pageProxy) + return; + pageProxy->activityStateDidChange(activityStateFlagsToUpdate); + activityStateFlagsToUpdate = ActivityState::NoFlags; + } + WebKitWebViewChildrenMap children; - OwnPtr<PageClientImpl> pageClient; + std::unique_ptr<PageClientImpl> pageClient; RefPtr<WebPageProxy> pageProxy; bool shouldForwardNextKeyEvent; - GtkClickCounter clickCounter; + bool shouldForwardNextWheelEvent; + ClickCounter clickCounter; CString tooltipText; IntRect tooltipArea; -#if ENABLE(DRAG_SUPPORT) - GtkDragAndDropHelper dragAndDropHelper; -#endif - DragIcon dragIcon; -#if !GTK_CHECK_VERSION(3, 13, 4) - IntSize resizerSize; -#endif GRefPtr<AtkObject> accessible; - bool needsResizeOnMap; GtkWidget* authenticationDialog; GtkWidget* inspectorView; AttachmentSide inspectorAttachmentSide; unsigned inspectorViewSize; GUniquePtr<GdkEvent> contextMenuEvent; WebContextMenuProxyGtk* activeContextMenuProxy; - WebViewBaseInputMethodFilter inputMethodFilter; - GtkTouchContextHelper touchContext; + InputMethodFilter inputMethodFilter; + KeyBindingTranslator keyBindingTranslator; + TouchEventsMap touchEvents; + IntSize contentsSize; GtkWindow* toplevelOnScreenWindow; -#if !GTK_CHECK_VERSION(3, 13, 4) - unsigned long toplevelResizeGripVisibilityID; -#endif unsigned long toplevelFocusInEventID; unsigned long toplevelFocusOutEventID; - unsigned long toplevelVisibilityEventID; + unsigned long toplevelWindowStateEventID; + unsigned long toplevelWindowRealizedID; // View State. - bool isInWindowActive : 1; - bool isFocused : 1; - bool isVisible : 1; - bool isWindowVisible : 1; + ActivityState::Flags activityState; + ActivityState::Flags activityStateFlagsToUpdate; + RunLoop::Timer<WebKitWebViewBasePrivate> updateActivityStateTimer; WebKitWebViewBaseDownloadRequestHandler downloadHandler; #if ENABLE(FULLSCREEN_API) bool fullScreenModeActive; WebFullScreenClientGtk fullScreenClient; + GRefPtr<GDBusProxy> screenSaverProxy; + GRefPtr<GCancellable> screenSaverInhibitCancellable; + unsigned screenSaverCookie; +#endif + + std::unique_ptr<AcceleratedBackingStore> acceleratedBackingStore; + +#if ENABLE(DRAG_SUPPORT) + std::unique_ptr<DragAndDropHandler> dragAndDropHandler; #endif -#if USE(TEXTURE_MAPPER_GL) - OwnPtr<RedirectedXCompositeWindow> redirectedWindow; +#if HAVE(GTK_GESTURES) + std::unique_ptr<GestureController> gestureController; #endif }; WEBKIT_DEFINE_TYPE(WebKitWebViewBase, webkit_web_view_base, GTK_TYPE_CONTAINER) -#if !GTK_CHECK_VERSION(3, 13, 4) -static void webkitWebViewBaseNotifyResizerSize(WebKitWebViewBase* webViewBase) +static void webkitWebViewBaseScheduleUpdateActivityState(WebKitWebViewBase* webViewBase, ActivityState::Flags flagsToUpdate) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->toplevelOnScreenWindow) + priv->activityStateFlagsToUpdate |= flagsToUpdate; + if (priv->updateActivityStateTimer.isActive()) return; - gboolean resizerVisible; - g_object_get(G_OBJECT(priv->toplevelOnScreenWindow), "resize-grip-visible", &resizerVisible, NULL); - - IntSize resizerSize; - if (resizerVisible) { - GdkRectangle resizerRect; - gtk_window_get_resize_grip_area(priv->toplevelOnScreenWindow, &resizerRect); - GdkRectangle allocation; - gtk_widget_get_allocation(GTK_WIDGET(webViewBase), &allocation); - if (gdk_rectangle_intersect(&resizerRect, &allocation, 0)) - resizerSize = IntSize(resizerRect.width, resizerRect.height); - } - - if (resizerSize != priv->resizerSize) { - priv->resizerSize = resizerSize; - priv->pageProxy->setWindowResizerSize(resizerSize); - } + priv->updateActivityStateTimer.startOneShot(0); } -static void toplevelWindowResizeGripVisibilityChanged(GObject*, GParamSpec*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) { - webkitWebViewBaseNotifyResizerSize(webViewBase); + // Spurious focus in events can occur when the window is hidden. + if (!gtk_widget_get_visible(widget)) + return FALSE; + + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->activityState & ActivityState::WindowIsActive) + return FALSE; + + priv->activityState |= ActivityState::WindowIsActive; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive); + + return FALSE; } -#endif -static gboolean toplevelWindowFocusInEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowFocusOutEvent(GtkWidget*, GdkEventFocus*, WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->isInWindowActive) { - priv->isInWindowActive = true; - priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); - } + if (!(priv->activityState & ActivityState::WindowIsActive)) + return FALSE; + + priv->activityState &= ~ActivityState::WindowIsActive; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::WindowIsActive); return FALSE; } -static gboolean toplevelWindowFocusOutEvent(GtkWidget* widget, GdkEventFocus*, WebKitWebViewBase* webViewBase) +static gboolean toplevelWindowStateEvent(GtkWidget*, GdkEventWindowState* event, WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->isInWindowActive) { - priv->isInWindowActive = false; - priv->pageProxy->viewStateDidChange(ViewState::WindowIsActive); - } + if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED)) + return FALSE; + + bool visible = !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED); + if ((visible && priv->activityState & ActivityState::IsVisible) || (!visible && !(priv->activityState & ActivityState::IsVisible))) + return FALSE; + + if (visible) + priv->activityState |= ActivityState::IsVisible; + else + priv->activityState &= ~ActivityState::IsVisible; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible); return FALSE; } -static gboolean toplevelWindowVisibilityEvent(GtkWidget*, GdkEventVisibility* visibilityEvent, WebKitWebViewBase* webViewBase) +static void toplevelWindowRealized(WebKitWebViewBase* webViewBase) { + gtk_widget_realize(GTK_WIDGET(webViewBase)); + WebKitWebViewBasePrivate* priv = webViewBase->priv; - bool isWindowVisible = visibilityEvent->state != GDK_VISIBILITY_FULLY_OBSCURED; - if (priv->isWindowVisible != isWindowVisible) { - priv->isWindowVisible = isWindowVisible; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); + if (priv->toplevelWindowRealizedID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID); + priv->toplevelWindowRealizedID = 0; } - - return FALSE; } static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webViewBase, GtkWindow* window) @@ -217,12 +286,6 @@ static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webVie if (priv->toplevelOnScreenWindow == window) return; -#if !GTK_CHECK_VERSION(3, 13, 4) - if (priv->toplevelResizeGripVisibilityID) { - g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelResizeGripVisibilityID); - priv->toplevelResizeGripVisibilityID = 0; - } -#endif if (priv->toplevelFocusInEventID) { g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusInEventID); priv->toplevelFocusInEventID = 0; @@ -231,36 +294,53 @@ static void webkitWebViewBaseSetToplevelOnScreenWindow(WebKitWebViewBase* webVie g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelFocusOutEventID); priv->toplevelFocusOutEventID = 0; } - if (priv->toplevelVisibilityEventID) { - g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelVisibilityEventID); - priv->toplevelVisibilityEventID = 0; + if (priv->toplevelWindowStateEventID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowStateEventID); + priv->toplevelWindowStateEventID = 0; + } + if (priv->toplevelWindowRealizedID) { + g_signal_handler_disconnect(priv->toplevelOnScreenWindow, priv->toplevelWindowRealizedID); + priv->toplevelWindowRealizedID = 0; } priv->toplevelOnScreenWindow = window; - priv->pageProxy->viewStateDidChange(ViewState::IsInWindow); - if (!priv->toplevelOnScreenWindow) - return; -#if !GTK_CHECK_VERSION(3, 13, 4) - webkitWebViewBaseNotifyResizerSize(webViewBase); + if (!priv->toplevelOnScreenWindow) { + ActivityState::Flags flagsToUpdate = 0; + if (priv->activityState & ActivityState::IsInWindow) { + priv->activityState &= ~ActivityState::IsInWindow; + flagsToUpdate |= ActivityState::IsInWindow; + } + if (priv->activityState & ActivityState::WindowIsActive) { + priv->activityState &= ~ActivityState::WindowIsActive; + flagsToUpdate |= ActivityState::IsInWindow; + } + if (flagsToUpdate) + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); + + return; + } - priv->toplevelResizeGripVisibilityID = - g_signal_connect(priv->toplevelOnScreenWindow, "notify::resize-grip-visible", - G_CALLBACK(toplevelWindowResizeGripVisibilityChanged), webViewBase); -#endif priv->toplevelFocusInEventID = g_signal_connect(priv->toplevelOnScreenWindow, "focus-in-event", G_CALLBACK(toplevelWindowFocusInEvent), webViewBase); priv->toplevelFocusOutEventID = g_signal_connect(priv->toplevelOnScreenWindow, "focus-out-event", G_CALLBACK(toplevelWindowFocusOutEvent), webViewBase); - priv->toplevelVisibilityEventID = - g_signal_connect(priv->toplevelOnScreenWindow, "visibility-notify-event", - G_CALLBACK(toplevelWindowVisibilityEvent), webViewBase); + priv->toplevelWindowStateEventID = + g_signal_connect(priv->toplevelOnScreenWindow, "window-state-event", G_CALLBACK(toplevelWindowStateEvent), webViewBase); + + if (gtk_widget_get_realized(GTK_WIDGET(window))) + gtk_widget_realize(GTK_WIDGET(webViewBase)); + else + priv->toplevelWindowRealizedID = g_signal_connect_swapped(window, "realize", G_CALLBACK(toplevelWindowRealized), webViewBase); } static void webkitWebViewBaseRealize(GtkWidget* widget) { + WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webView->priv; + gtk_widget_set_realized(widget, TRUE); GtkAllocation allocation; @@ -281,6 +361,8 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | GDK_POINTER_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_MOTION_MASK @@ -295,12 +377,30 @@ static void webkitWebViewBaseRealize(GtkWidget* widget) gtk_widget_set_window(widget, window); gdk_window_set_user_data(window, widget); +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea())) + drawingArea->setNativeSurfaceHandleForCompositing(GDK_WINDOW_XID(window)); + } +#endif + gtk_style_context_set_background(gtk_widget_get_style_context(widget), window); + gtk_im_context_set_client_window(priv->inputMethodFilter.context(), window); +} + +static void webkitWebViewBaseUnrealize(GtkWidget* widget) +{ WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(widget); - GtkWidget* toplevel = gtk_widget_get_toplevel(widget); - if (widgetIsOnscreenToplevelWindow(toplevel)) - webkitWebViewBaseSetToplevelOnScreenWindow(webView, GTK_WINDOW(toplevel)); +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(webView->priv->pageProxy->drawingArea())) + drawingArea->destroyNativeSurfaceHandleForCompositing(); + } +#endif + gtk_im_context_set_client_window(webView->priv->inputMethodFilter.context(), nullptr); + + GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unrealize(widget); } static bool webkitWebViewChildIsInternalWidget(WebKitWebViewBase* webViewBase, GtkWidget* widget) @@ -406,8 +506,10 @@ void webkitWebViewBaseChildMoveResize(WebKitWebViewBase* webView, GtkWidget* chi static void webkitWebViewBaseDispose(GObject* gobject) { WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(gobject); + g_cancellable_cancel(webView->priv->screenSaverInhibitCancellable.get()); webkitWebViewBaseSetToplevelOnScreenWindow(webView, nullptr); webView->priv->pageProxy->close(); + webView->priv->acceleratedBackingStore = nullptr; G_OBJECT_CLASS(webkit_web_view_base_parent_class)->dispose(gobject); } @@ -417,48 +519,15 @@ static void webkitWebViewBaseConstructed(GObject* object) GtkWidget* viewWidget = GTK_WIDGET(object); gtk_widget_set_can_focus(viewWidget, TRUE); - gtk_drag_dest_set(viewWidget, static_cast<GtkDestDefaults>(0), 0, 0, - static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)); - gtk_drag_dest_set_target_list(viewWidget, PasteboardHelper::defaultPasteboardHelper()->targetList()); + gtk_drag_dest_set(viewWidget, static_cast<GtkDestDefaults>(0), nullptr, 0, + static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)); + gtk_drag_dest_set_target_list(viewWidget, PasteboardHelper::singleton().targetList()); WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(object)->priv; - priv->pageClient = PageClientImpl::create(viewWidget); -#if ENABLE(DRAG_SUPPORT) - priv->dragAndDropHelper.setWidget(viewWidget); -#endif - -#if USE(TEXTURE_MAPPER_GL) && defined(GDK_WINDOWING_X11) - GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get()); - if (GDK_IS_X11_DISPLAY(display)) { - priv->redirectedWindow = RedirectedXCompositeWindow::create(IntSize(1, 1), RedirectedXCompositeWindow::DoNotCreateGLContext); - if (priv->redirectedWindow) - priv->redirectedWindow->setDamageNotifyCallback(redirectedWindowDamagedCallback, object); - } -#endif - + priv->pageClient = std::make_unique<PageClientImpl>(viewWidget); priv->authenticationDialog = 0; } -#if USE(TEXTURE_MAPPER_GL) -static bool webkitWebViewRenderAcceleratedCompositingResults(WebKitWebViewBase* webViewBase, DrawingAreaProxyImpl* drawingArea, cairo_t* cr, GdkRectangle* clipRect) -{ - if (!drawingArea->isInAcceleratedCompositingMode()) - return false; - - // To avoid flashes when initializing accelerated compositing for the first - // time, we wait until we know there's a frame ready before rendering. - WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->redirectedWindow) - return false; - - cairo_rectangle(cr, clipRect->x, clipRect->y, clipRect->width, clipRect->height); - cairo_surface_t* surface = priv->redirectedWindow->cairoSurfaceForWidget(GTK_WIDGET(webViewBase)); - cairo_set_source_surface(cr, surface, 0, 0); - cairo_fill(cr); - return true; -} -#endif - static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); @@ -470,18 +539,11 @@ static gboolean webkitWebViewBaseDraw(GtkWidget* widget, cairo_t* cr) if (!gdk_cairo_get_clip_rectangle(cr, &clipRect)) return FALSE; -#if USE(TEXTURE_MAPPER_GL) - if (webkitWebViewRenderAcceleratedCompositingResults(webViewBase, drawingArea, cr, &clipRect)) - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->draw(widget, cr); -#endif - - WebCore::Region unpaintedRegion; // This is simply unused. - drawingArea->paint(cr, clipRect, unpaintedRegion); - - if (webViewBase->priv->authenticationDialog) { - cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - cairo_set_source_rgba(cr, 0, 0, 0, 0.5); - cairo_paint(cr); + if (webViewBase->priv->acceleratedBackingStore && drawingArea->isInAcceleratedCompositingMode()) + webViewBase->priv->acceleratedBackingStore->paint(cr, clipRect); + else { + WebCore::Region unpaintedRegion; // This is simply unused. + drawingArea->paint(cr, clipRect, unpaintedRegion); } GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->draw(widget, cr); @@ -505,8 +567,11 @@ static void webkitWebViewBaseChildAllocate(GtkWidget* child, gpointer userData) priv->children.set(child, IntRect()); } -static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase, GtkAllocation* allocation, bool sizeChanged) +static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { + GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, allocation); + + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); gtk_container_foreach(GTK_CONTAINER(webViewBase), webkitWebViewBaseChildAllocate, webViewBase); IntRect viewRect(allocation->x, allocation->y, allocation->width, allocation->height); @@ -514,7 +579,7 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase if (priv->inspectorView) { GtkAllocation childAllocation = viewRect; - if (priv->inspectorAttachmentSide == AttachmentSideBottom) { + if (priv->inspectorAttachmentSide == AttachmentSide::Bottom) { int inspectorViewHeight = std::min(static_cast<int>(priv->inspectorViewSize), allocation->height); childAllocation.x = 0; childAllocation.y = allocation->height - inspectorViewHeight; @@ -535,45 +600,29 @@ static void resizeWebKitWebViewBaseFromAllocation(WebKitWebViewBase* webViewBase // never overlaps the web inspector. Thus, we need to calculate the allocation here // after calculating the inspector allocation. if (priv->authenticationDialog) { - GtkRequisition naturalSize; - gtk_widget_get_preferred_size(priv->authenticationDialog, 0, &naturalSize); - - GtkAllocation childAllocation = { - (viewRect.width() - naturalSize.width) / 2, - (viewRect.height() - naturalSize.height) / 2, - naturalSize.width, - naturalSize.height - }; + GtkRequisition minimumSize; + gtk_widget_get_preferred_size(priv->authenticationDialog, &minimumSize, nullptr); + + GtkAllocation childAllocation = { 0, 0, std::max(minimumSize.width, viewRect.width()), std::max(minimumSize.height, viewRect.height()) }; gtk_widget_size_allocate(priv->authenticationDialog, &childAllocation); } -#if USE(TEXTURE_MAPPER_GL) - if (sizeChanged && webViewBase->priv->redirectedWindow) - webViewBase->priv->redirectedWindow->resize(viewRect.size()); -#endif - - if (priv->pageProxy->drawingArea()) - priv->pageProxy->drawingArea()->setSize(viewRect.size(), IntSize(), IntSize()); - -#if !GTK_CHECK_VERSION(3, 13, 4) - webkitWebViewBaseNotifyResizerSize(webViewBase); -#endif + if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea())) + drawingArea->setSize(viewRect.size(), IntSize(), IntSize()); } -static void webkitWebViewBaseSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) +static void webkitWebViewBaseGetPreferredWidth(GtkWidget* widget, gint* minimumSize, gint* naturalSize) { - bool sizeChanged = gtk_widget_get_allocated_width(widget) != allocation->width - || gtk_widget_get_allocated_height(widget) != allocation->height; - - GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->size_allocate(widget, allocation); - - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - if (sizeChanged && !gtk_widget_get_mapped(widget)) { - webViewBase->priv->needsResizeOnMap = true; - return; - } + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + *minimumSize = 0; + *naturalSize = priv->contentsSize.width(); +} - resizeWebKitWebViewBaseFromAllocation(webViewBase, allocation, sizeChanged); +static void webkitWebViewBaseGetPreferredHeight(GtkWidget* widget, gint* minimumSize, gint* naturalSize) +{ + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + *minimumSize = 0; + *naturalSize = priv->contentsSize.height(); } static void webkitWebViewBaseMap(GtkWidget* widget) @@ -582,29 +631,33 @@ static void webkitWebViewBaseMap(GtkWidget* widget) WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (!priv->isVisible) { - priv->isVisible = true; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); + ActivityState::Flags flagsToUpdate = 0; + if (!(priv->activityState & ActivityState::IsVisible)) + flagsToUpdate |= ActivityState::IsVisible; + if (priv->toplevelOnScreenWindow) { + if (!(priv->activityState & ActivityState::IsInWindow)) + flagsToUpdate |= ActivityState::IsInWindow; + if (gtk_window_is_active(GTK_WINDOW(priv->toplevelOnScreenWindow)) && !(priv->activityState & ActivityState::WindowIsActive)) + flagsToUpdate |= ActivityState::WindowIsActive; } - - if (!priv->needsResizeOnMap) + if (!flagsToUpdate) return; - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - resizeWebKitWebViewBaseFromAllocation(webViewBase, &allocation, true /* sizeChanged */); - priv->needsResizeOnMap = false; + priv->activityState |= flagsToUpdate; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); } static void webkitWebViewBaseUnmap(GtkWidget* widget) { GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->unmap(widget); - WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; - if (priv->isVisible) { - priv->isVisible = false; - priv->pageProxy->viewStateDidChange(ViewState::IsVisible); - } + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!(priv->activityState & ActivityState::IsVisible)) + return; + + priv->activityState &= ~ActivityState::IsVisible; + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, ActivityState::IsVisible); } static gboolean webkitWebViewBaseFocusInEvent(GtkWidget* widget, GdkEventFocus* event) @@ -625,17 +678,26 @@ static gboolean webkitWebViewBaseFocusOutEvent(GtkWidget* widget, GdkEventFocus* return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus_out_event(widget, event); } -static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* event) +static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* keyEvent) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; +#if ENABLE(DEVELOPER_MODE) && OS(LINUX) + if ((keyEvent->state & GDK_CONTROL_MASK) && (keyEvent->state & GDK_SHIFT_MASK) && keyEvent->keyval == GDK_KEY_G) { + auto& preferences = priv->pageProxy->preferences(); + preferences.setResourceUsageOverlayVisible(!preferences.resourceUsageOverlayVisible()); + priv->shouldForwardNextKeyEvent = FALSE; + return TRUE; + } +#endif + if (priv->authenticationDialog) - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent); #if ENABLE(FULLSCREEN_API) if (priv->fullScreenModeActive) { - switch (event->keyval) { + switch (keyEvent->keyval) { case GDK_KEY_Escape: case GDK_KEY_f: case GDK_KEY_F: @@ -653,22 +715,35 @@ static gboolean webkitWebViewBaseKeyPressEvent(GtkWidget* widget, GdkEventKey* e // using gtk_main_do_event(). if (priv->shouldForwardNextKeyEvent) { priv->shouldForwardNextKeyEvent = FALSE; - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_press_event(widget, keyEvent); } - priv->inputMethodFilter.filterKeyEvent(event); + + // We need to copy the event as otherwise it could be destroyed before we reach the lambda body. + GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent))); + priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) { + priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked, + !compositionResults.compositionUpdated() ? priv->keyBindingTranslator.commandsForKeyEvent(&event->key) : Vector<String>())); + }); + return TRUE; } -static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event) +static gboolean webkitWebViewBaseKeyReleaseEvent(GtkWidget* widget, GdkEventKey* keyEvent) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; if (priv->shouldForwardNextKeyEvent) { priv->shouldForwardNextKeyEvent = FALSE; - return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, event); + return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->key_release_event(widget, keyEvent); } - priv->inputMethodFilter.filterKeyEvent(event); + + // We need to copy the event as otherwise it could be destroyed before we reach the lambda body. + GUniquePtr<GdkEvent> event(gdk_event_copy(reinterpret_cast<GdkEvent*>(keyEvent))); + priv->inputMethodFilter.filterKeyEvent(keyEvent, [priv, event = WTFMove(event)](const WebCore::CompositionResults& compositionResults, InputMethodFilter::EventFakedForComposition faked) { + priv->pageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(event.get(), compositionResults, faked, { })); + }); + return TRUE; } @@ -684,14 +759,21 @@ static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventBut priv->inputMethodFilter.notifyMouseButtonPress(); - if (!priv->clickCounter.shouldProcessButtonEvent(buttonEvent)) + // For double and triple clicks GDK sends both a normal button press event + // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press + // coming up, ignore this event as it certainly generated the double or triple + // click. The consequence of not eating this event is two DOM button press events + // are generated. + GUniquePtr<GdkEvent> nextEvent(gdk_event_peek()); + if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS)) return TRUE; // If it's a right click event save it as a possible context menu event. if (buttonEvent->button == 3) priv->contextMenuEvent.reset(gdk_event_copy(reinterpret_cast<GdkEvent*>(buttonEvent))); + priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(buttonEvent), - priv->clickCounter.clickCountForGdkButtonEvent(widget, buttonEvent))); + priv->clickCounter.currentClickCountForGdkButtonEvent(buttonEvent))); return TRUE; } @@ -714,41 +796,195 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll* WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (std::exchange(priv->shouldForwardNextWheelEvent, false)) + return FALSE; + if (priv->authenticationDialog) - return TRUE; + return FALSE; priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(reinterpret_cast<GdkEvent*>(event))); return TRUE; } +static gboolean webkitWebViewBasePopupMenu(GtkWidget* widget) +{ + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + + GdkEvent* currentEvent = gtk_get_current_event(); + if (!currentEvent) + currentEvent = gdk_event_new(GDK_NOTHING); + priv->contextMenuEvent.reset(currentEvent); + priv->pageProxy->handleContextMenuKeyEvent(); + + return TRUE; +} + static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event) { WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->authenticationDialog) - return TRUE; + if (priv->authenticationDialog) { + auto* widgetClass = GTK_WIDGET_CLASS(webkit_web_view_base_parent_class); + return widgetClass->motion_notify_event ? widgetClass->motion_notify_event(widget, event) : FALSE; + } priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */)); - return TRUE; + return FALSE; +} + +static gboolean webkitWebViewBaseCrossingNotifyEvent(GtkWidget* widget, GdkEventCrossing* crosssingEvent) +{ + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; + + if (priv->authenticationDialog) + return FALSE; + + // In the case of crossing events, it's very important the actual coordinates the WebProcess receives, because once the mouse leaves + // the web view, the WebProcess won't receive more events until the mouse enters again in the web view. So, if the coordinates of the leave + // event are not accurate, the WebProcess might not know the mouse left the view. This can happen because of double to integer conversion, + // if the coordinates of the leave event are for example (25.2, -0.9), the WebProcess will receive (25, 0) and any hit test will succeed + // because those coordinates are inside the web view. + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + double width = allocation.width; + double height = allocation.height; + double x = crosssingEvent->x; + double y = crosssingEvent->y; + if (x < 0 && x > -1) + x = -1; + else if (x >= width && x < width + 1) + x = width + 1; + if (y < 0 && y > -1) + y = -1; + else if (y >= height && y < height + 1) + y = height + 1; + + GdkEvent* event = reinterpret_cast<GdkEvent*>(crosssingEvent); + GUniquePtr<GdkEvent> copiedEvent; + if (x != crosssingEvent->x || y != crosssingEvent->y) { + copiedEvent.reset(gdk_event_copy(event)); + copiedEvent->crossing.x = x; + copiedEvent->crossing.y = y; + } + + priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(copiedEvent ? copiedEvent.get() : event, 0 /* currentClickCount */)); + + return FALSE; +} + +#if ENABLE(TOUCH_EVENTS) +static void appendTouchEvent(Vector<WebPlatformTouchPoint>& touchPoints, const GdkEvent* event, WebPlatformTouchPoint::TouchPointState state) +{ + gdouble x, y; + gdk_event_get_coords(event, &x, &y); + + gdouble xRoot, yRoot; + gdk_event_get_root_coords(event, &xRoot, &yRoot); + + uint32_t identifier = GPOINTER_TO_UINT(gdk_event_get_event_sequence(event)); + touchPoints.uncheckedAppend(WebPlatformTouchPoint(identifier, state, IntPoint(xRoot, yRoot), IntPoint(x, y))); +} + +static inline WebPlatformTouchPoint::TouchPointState touchPointStateForEvents(const GdkEvent* current, const GdkEvent* event) +{ + if (gdk_event_get_event_sequence(current) != gdk_event_get_event_sequence(event)) + return WebPlatformTouchPoint::TouchStationary; + + switch (current->type) { + case GDK_TOUCH_UPDATE: + return WebPlatformTouchPoint::TouchMoved; + case GDK_TOUCH_BEGIN: + return WebPlatformTouchPoint::TouchPressed; + case GDK_TOUCH_END: + return WebPlatformTouchPoint::TouchReleased; + default: + return WebPlatformTouchPoint::TouchStationary; + } +} + +static void webkitWebViewBaseGetTouchPointsForEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, Vector<WebPlatformTouchPoint>& touchPoints) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + touchPoints.reserveInitialCapacity(event->type == GDK_TOUCH_END ? priv->touchEvents.size() + 1 : priv->touchEvents.size()); + + for (const auto& it : priv->touchEvents) + appendTouchEvent(touchPoints, it.value.get(), touchPointStateForEvents(it.value.get(), event)); + + // Touch was already removed from the TouchEventsMap, add it here. + if (event->type == GDK_TOUCH_END) + appendTouchEvent(touchPoints, event, WebPlatformTouchPoint::TouchReleased); } static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* event) { - WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); + WebKitWebViewBasePrivate* priv = webViewBase->priv; if (priv->authenticationDialog) return TRUE; - priv->touchContext.handleEvent(reinterpret_cast<GdkEvent*>(event)); - priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), priv->touchContext)); + GdkEvent* touchEvent = reinterpret_cast<GdkEvent*>(event); + uint32_t sequence = GPOINTER_TO_UINT(gdk_event_get_event_sequence(touchEvent)); + +#if HAVE(GTK_GESTURES) + GestureController& gestureController = webkitWebViewBaseGestureController(webViewBase); + if (gestureController.isProcessingGestures()) { + // If we are already processing gestures is because the WebProcess didn't handle the + // BEGIN touch event, so pass subsequent events to the GestureController. + gestureController.handleEvent(touchEvent); + // Remove the gesture event sequence from the handled touch events + // list to avoid the gesure sequence and a touch sequence of same + // ID to conflict. + priv->touchEvents.remove(sequence); + return TRUE; + } +#endif + + switch (touchEvent->type) { + case GDK_TOUCH_BEGIN: { + ASSERT(!priv->touchEvents.contains(sequence)); + GUniquePtr<GdkEvent> event(gdk_event_copy(touchEvent)); + priv->touchEvents.add(sequence, WTFMove(event)); + break; + } + case GDK_TOUCH_UPDATE: { + auto it = priv->touchEvents.find(sequence); + ASSERT(it != priv->touchEvents.end()); + it->value.reset(gdk_event_copy(touchEvent)); + break; + } + case GDK_TOUCH_END: + ASSERT(priv->touchEvents.contains(sequence)); + priv->touchEvents.remove(sequence); + break; + default: + break; + } + + Vector<WebPlatformTouchPoint> touchPoints; + webkitWebViewBaseGetTouchPointsForEvent(webViewBase, touchEvent, touchPoints); + priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), WTFMove(touchPoints))); return TRUE; } +#endif // ENABLE(TOUCH_EVENTS) + +#if HAVE(GTK_GESTURES) +GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->gestureController) + priv->gestureController = std::make_unique<GestureController>(*priv->pageProxy); + return *priv->gestureController; +} +#endif -static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, gboolean keyboardMode, GtkTooltip* tooltip) +static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint /* x */, gint /* y */, gboolean keyboardMode, GtkTooltip* tooltip) { WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; @@ -772,39 +1008,23 @@ static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, } #if ENABLE(DRAG_SUPPORT) -static void webkitWebViewBaseDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint time) +static void webkitWebViewBaseDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint /* time */) { - WEBKIT_WEB_VIEW_BASE(widget)->priv->dragAndDropHelper.handleGetDragData(context, selectionData, info); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->fillDragData(context, selectionData, info); } static void webkitWebViewBaseDragEnd(GtkWidget* widget, GdkDragContext* context) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - if (!webViewBase->priv->dragAndDropHelper.handleDragEnd(context)) - return; - - GdkDevice* device = gdk_drag_context_get_device(context); - int x = 0, y = 0; - gdk_device_get_window_at_position(device, &x, &y); - int xRoot = 0, yRoot = 0; - gdk_device_get_position(device, 0, &xRoot, &yRoot); - webViewBase->priv->pageProxy->dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), - gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context))); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->finishDrag(context); } -static void webkitWebViewBaseDragDataReceived(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData* selectionData, guint info, guint time) +static void webkitWebViewBaseDragDataReceived(GtkWidget* widget, GdkDragContext* context, gint /* x */, gint /* y */, GtkSelectionData* selectionData, guint info, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - IntPoint position; - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragDataReceived(context, selectionData, info, position); - if (!dataObject) - return; - - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - webViewBase->priv->pageProxy->resetDragOperation(); - webViewBase->priv->pageProxy->dragEntered(dragData); - DragOperation operation = webViewBase->priv->pageProxy->dragSession().operation; - gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); + webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragEntered(context, selectionData, info, time); } #endif // ENABLE(DRAG_SUPPORT) @@ -839,57 +1059,38 @@ static AtkObject* webkitWebViewBaseGetAccessible(GtkWidget* widget) #if ENABLE(DRAG_SUPPORT) static gboolean webkitWebViewBaseDragMotion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - IntPoint position(x, y); - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragMotion(context, position, time); - if (!dataObject) - return TRUE; - - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - webViewBase->priv->pageProxy->dragUpdated(dragData); - DragOperation operation = webViewBase->priv->pageProxy->dragSession().operation; - gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); + webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragMotion(context, IntPoint(x, y), time); return TRUE; } -static void dragExitedCallback(GtkWidget* widget, DragData& dragData, bool dropHappened) -{ - // Don't call dragExited if we have just received a drag-drop signal. This - // happens in the case of a successful drop onto the view. - if (dropHappened) - return; - - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - webViewBase->priv->pageProxy->dragExited(dragData); - webViewBase->priv->pageProxy->resetDragOperation(); -} - -static void webkitWebViewBaseDragLeave(GtkWidget* widget, GdkDragContext* context, guint time) +static void webkitWebViewBaseDragLeave(GtkWidget* widget, GdkDragContext* context, guint /* time */) { - WEBKIT_WEB_VIEW_BASE(widget)->priv->dragAndDropHelper.handleDragLeave(context, dragExitedCallback); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + priv->dragAndDropHandler->dragLeave(context); } static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time) { - WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget); - DataObjectGtk* dataObject = webViewBase->priv->dragAndDropHelper.handleDragDrop(context); - if (!dataObject) - return FALSE; - - IntPoint position(x, y); - DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); - SandboxExtension::Handle handle; - SandboxExtension::HandleArray sandboxExtensionForUpload; - webViewBase->priv->pageProxy->performDrag(dragData, String(), handle, sandboxExtensionForUpload); - gtk_drag_finish(context, TRUE, FALSE, time); - return TRUE; + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + ASSERT(priv->dragAndDropHandler); + return priv->dragAndDropHandler->drop(context, IntPoint(x, y), time); } #endif // ENABLE(DRAG_SUPPORT) -static void webkitWebViewBaseParentSet(GtkWidget* widget, GtkWidget* oldParent) +static void webkitWebViewBaseHierarchyChanged(GtkWidget* widget, GtkWidget* oldToplevel) { - if (!gtk_widget_get_parent(widget)) - webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), 0); + WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv; + if (widgetIsOnscreenToplevelWindow(oldToplevel) && GTK_WINDOW(oldToplevel) == priv->toplevelOnScreenWindow) { + webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), nullptr); + return; + } + + if (!oldToplevel) { + GtkWidget* toplevel = gtk_widget_get_toplevel(widget); + if (widgetIsOnscreenToplevelWindow(toplevel)) + webkitWebViewBaseSetToplevelOnScreenWindow(WEBKIT_WEB_VIEW_BASE(widget), GTK_WINDOW(toplevel)); + } } static gboolean webkitWebViewBaseFocus(GtkWidget* widget, GtkDirectionType direction) @@ -919,8 +1120,11 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie { GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webkitWebViewBaseClass); widgetClass->realize = webkitWebViewBaseRealize; + widgetClass->unrealize = webkitWebViewBaseUnrealize; widgetClass->draw = webkitWebViewBaseDraw; widgetClass->size_allocate = webkitWebViewBaseSizeAllocate; + widgetClass->get_preferred_width = webkitWebViewBaseGetPreferredWidth; + widgetClass->get_preferred_height = webkitWebViewBaseGetPreferredHeight; widgetClass->map = webkitWebViewBaseMap; widgetClass->unmap = webkitWebViewBaseUnmap; widgetClass->focus = webkitWebViewBaseFocus; @@ -931,8 +1135,13 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->button_press_event = webkitWebViewBaseButtonPressEvent; widgetClass->button_release_event = webkitWebViewBaseButtonReleaseEvent; widgetClass->scroll_event = webkitWebViewBaseScrollEvent; + widgetClass->popup_menu = webkitWebViewBasePopupMenu; widgetClass->motion_notify_event = webkitWebViewBaseMotionNotifyEvent; + widgetClass->enter_notify_event = webkitWebViewBaseCrossingNotifyEvent; + widgetClass->leave_notify_event = webkitWebViewBaseCrossingNotifyEvent; +#if ENABLE(TOUCH_EVENTS) widgetClass->touch_event = webkitWebViewBaseTouchEvent; +#endif widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip; #if ENABLE(DRAG_SUPPORT) widgetClass->drag_end = webkitWebViewBaseDragEnd; @@ -943,7 +1152,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie widgetClass->drag_data_received = webkitWebViewBaseDragDataReceived; #endif // ENABLE(DRAG_SUPPORT) widgetClass->get_accessible = webkitWebViewBaseGetAccessible; - widgetClass->parent_set = webkitWebViewBaseParentSet; + widgetClass->hierarchy_changed = webkitWebViewBaseHierarchyChanged; widgetClass->destroy = webkitWebViewBaseDestroy; GObjectClass* gobjectClass = G_OBJECT_CLASS(webkitWebViewBaseClass); @@ -954,12 +1163,17 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie containerClass->add = webkitWebViewBaseContainerAdd; containerClass->remove = webkitWebViewBaseContainerRemove; containerClass->forall = webkitWebViewBaseContainerForall; + + // Before creating a WebKitWebViewBasePriv we need to be sure that WebKit is started. + // Usually starting a context triggers InitializeWebKit2, but in case + // we create a view without asking before for a default_context we get a crash. + WebKit::InitializeWebKit2(); } -WebKitWebViewBase* webkitWebViewBaseCreate(WebContext* context, WebPageGroup* pageGroup, WebPageProxy* relatedPage) +WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration& configuration) { - WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, NULL)); - webkitWebViewBaseCreateWebPage(webkitWebViewBase, context, pageGroup, relatedPage); + WebKitWebViewBase* webkitWebViewBase = WEBKIT_WEB_VIEW_BASE(g_object_new(WEBKIT_TYPE_WEB_VIEW_BASE, nullptr)); + webkitWebViewBaseCreateWebPage(webkitWebViewBase, configuration.copy()); return webkitWebViewBase; } @@ -973,18 +1187,6 @@ WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase* webkitWebViewBase) return webkitWebViewBase->priv->pageProxy.get(); } -void webkitWebViewBaseUpdatePreferences(WebKitWebViewBase* webkitWebViewBase) -{ - WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; - -#if USE(TEXTURE_MAPPER_GL) - if (priv->redirectedWindow) - return; -#endif - - priv->pageProxy->pageGroup().preferences()->setAcceleratedCompositingEnabled(false); -} - #if HAVE(GTK_SCALE_FACTOR) static void deviceScaleFactorChanged(WebKitWebViewBase* webkitWebViewBase) { @@ -992,32 +1194,22 @@ static void deviceScaleFactorChanged(WebKitWebViewBase* webkitWebViewBase) } #endif // HAVE(GTK_SCALE_FACTOR) -void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, WebContext* context, WebPageGroup* pageGroup, WebPageProxy* relatedPage) +void webkitWebViewBaseCreateWebPage(WebKitWebViewBase* webkitWebViewBase, Ref<API::PageConfiguration>&& configuration) { WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; - - WebPageConfiguration webPageConfiguration; - webPageConfiguration.pageGroup = pageGroup; - webPageConfiguration.relatedPage = relatedPage; - priv->pageProxy = context->createWebPage(*priv->pageClient, std::move(webPageConfiguration)); + WebProcessPool* processPool = configuration->processPool(); + priv->pageProxy = processPool->createWebPage(*priv->pageClient, WTFMove(configuration)); priv->pageProxy->initializeWebPage(); -#if USE(TEXTURE_MAPPER_GL) - if (priv->redirectedWindow) - priv->pageProxy->setAcceleratedCompositingWindowId(priv->redirectedWindow->windowId()); -#endif + priv->acceleratedBackingStore = AcceleratedBackingStore::create(*priv->pageProxy); + + priv->inputMethodFilter.setPage(priv->pageProxy.get()); #if HAVE(GTK_SCALE_FACTOR) // We attach this here, because changes in scale factor are passed directly to the page proxy. priv->pageProxy->setIntrinsicDeviceScaleFactor(gtk_widget_get_scale_factor(GTK_WIDGET(webkitWebViewBase))); g_signal_connect(webkitWebViewBase, "notify::scale-factor", G_CALLBACK(deviceScaleFactorChanged), nullptr); #endif - - webkitWebViewBaseUpdatePreferences(webkitWebViewBase); - - // This must happen here instead of the instance initializer, because the input method - // filter must have access to the page. - priv->inputMethodFilter.setWebView(webkitWebViewBase); } void webkitWebViewBaseSetTooltipText(WebKitWebViewBase* webViewBase, const char* tooltip) @@ -1040,31 +1232,12 @@ void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase* webViewBase, const IntRe } #if ENABLE(DRAG_SUPPORT) -void webkitWebViewBaseStartDrag(WebKitWebViewBase* webViewBase, const DragData& dragData, PassRefPtr<ShareableBitmap> dragImage) +DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase* webViewBase) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - - RefPtr<DataObjectGtk> dataObject = adoptRef(dragData.platformData()); - GRefPtr<GtkTargetList> targetList = adoptGRef(PasteboardHelper::defaultPasteboardHelper()->targetListForDataObject(dataObject.get())); - GUniquePtr<GdkEvent> currentEvent(gtk_get_current_event()); - GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(webViewBase), - targetList.get(), - dragOperationToGdkDragActions(dragData.draggingSourceOperationMask()), - 1, /* button */ - currentEvent.get()); - priv->dragAndDropHelper.startedDrag(context, dataObject.get()); - - - // A drag starting should prevent a double-click from happening. This might - // happen if a drag is followed very quickly by another click (like in the DRT). - priv->clickCounter.reset(); - - if (dragImage) { - RefPtr<cairo_surface_t> image(dragImage->createCairoSurface()); - priv->dragIcon.setImage(image.get()); - priv->dragIcon.useForDrag(context); - } else - gtk_drag_set_icon_default(context); + if (!priv->dragAndDropHandler) + priv->dragAndDropHandler = std::make_unique<DragAndDropHandler>(*priv->pageProxy); + return *priv->dragAndDropHandler; } #endif // ENABLE(DRAG_SUPPORT) @@ -1073,6 +1246,80 @@ void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase) webkitWebViewBase->priv->shouldForwardNextKeyEvent = TRUE; } +void webkitWebViewBaseForwardNextWheelEvent(WebKitWebViewBase* webkitWebViewBase) +{ + webkitWebViewBase->priv->shouldForwardNextWheelEvent = true; +} + +#if ENABLE(FULLSCREEN_API) +static void screenSaverInhibitedCallback(GDBusProxy* screenSaverProxy, GAsyncResult* result, WebKitWebViewBase* webViewBase) +{ + GRefPtr<GVariant> returnValue = adoptGRef(g_dbus_proxy_call_finish(screenSaverProxy, result, nullptr)); + if (returnValue) + g_variant_get(returnValue.get(), "(u)", &webViewBase->priv->screenSaverCookie); + webViewBase->priv->screenSaverInhibitCancellable = nullptr; +} + +static void webkitWebViewBaseSendInhibitMessageToScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + ASSERT(priv->screenSaverProxy); + priv->screenSaverCookie = 0; + if (!priv->screenSaverInhibitCancellable) + priv->screenSaverInhibitCancellable = adoptGRef(g_cancellable_new()); + g_dbus_proxy_call(priv->screenSaverProxy.get(), "Inhibit", g_variant_new("(ss)", g_get_prgname(), _("Website running in fullscreen mode")), + G_DBUS_CALL_FLAGS_NONE, -1, priv->screenSaverInhibitCancellable.get(), reinterpret_cast<GAsyncReadyCallback>(screenSaverInhibitedCallback), webViewBase); +} + +static void screenSaverProxyCreatedCallback(GObject*, GAsyncResult* result, WebKitWebViewBase* webViewBase) +{ + // WebKitWebViewBase cancels the proxy creation on dispose, which means this could be called + // after the web view has been destroyed and g_dbus_proxy_new_for_bus_finish will return nullptr. + // So, make sure we don't use the web view unless we have a valid proxy. + // See https://bugs.webkit.org/show_bug.cgi?id=151653. + GRefPtr<GDBusProxy> proxy = adoptGRef(g_dbus_proxy_new_for_bus_finish(result, nullptr)); + if (!proxy) + return; + + webViewBase->priv->screenSaverProxy = proxy; + webkitWebViewBaseSendInhibitMessageToScreenSaver(webViewBase); +} + +static void webkitWebViewBaseInhibitScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (priv->screenSaverCookie) { + // Already inhibited. + return; + } + + if (priv->screenSaverProxy) { + webkitWebViewBaseSendInhibitMessageToScreenSaver(webViewBase); + return; + } + + priv->screenSaverInhibitCancellable = adoptGRef(g_cancellable_new()); + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS), + nullptr, "org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver", priv->screenSaverInhibitCancellable.get(), + reinterpret_cast<GAsyncReadyCallback>(screenSaverProxyCreatedCallback), webViewBase); +} + +static void webkitWebViewBaseUninhibitScreenSaver(WebKitWebViewBase* webViewBase) +{ + WebKitWebViewBasePrivate* priv = webViewBase->priv; + if (!priv->screenSaverCookie) { + // Not inhibited or it's being inhibited. + g_cancellable_cancel(priv->screenSaverInhibitCancellable.get()); + return; + } + + // If we have a cookie we should have a proxy. + ASSERT(priv->screenSaverProxy); + g_dbus_proxy_call(priv->screenSaverProxy.get(), "UnInhibit", g_variant_new("(u)", priv->screenSaverCookie), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr, nullptr); + priv->screenSaverCookie = 0; +} +#endif + void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase) { #if ENABLE(FULLSCREEN_API) @@ -1091,6 +1338,7 @@ void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase* webkitWebViewBase) gtk_window_fullscreen(GTK_WINDOW(topLevelWindow)); fullScreenManagerProxy->didEnterFullScreen(); priv->fullScreenModeActive = true; + webkitWebViewBaseInhibitScreenSaver(webkitWebViewBase); #endif } @@ -1112,6 +1360,7 @@ void webkitWebViewBaseExitFullScreen(WebKitWebViewBase* webkitWebViewBase) gtk_window_unfullscreen(GTK_WINDOW(topLevelWindow)); fullScreenManagerProxy->didExitFullScreen(); priv->fullScreenModeActive = false; + webkitWebViewBaseUninhibitScreenSaver(webkitWebViewBase); #endif } @@ -1129,9 +1378,16 @@ void webkitWebViewBaseSetInspectorViewSize(WebKitWebViewBase* webkitWebViewBase, gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase)); } +static void activeContextMenuUnmapped(GtkMenu* menu, WebKitWebViewBase* webViewBase) +{ + if (webViewBase->priv->activeContextMenuProxy && webViewBase->priv->activeContextMenuProxy->gtkMenu() == menu) + webViewBase->priv->activeContextMenuProxy = nullptr; +} + void webkitWebViewBaseSetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase, WebContextMenuProxyGtk* contextMenuProxy) { webkitWebViewBase->priv->activeContextMenuProxy = contextMenuProxy; + g_signal_connect_object(contextMenuProxy->gtkMenu(), "unmap", G_CALLBACK(activeContextMenuUnmapped), webkitWebViewBase, static_cast<GConnectFlags>(0)); } WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKitWebViewBase* webkitWebViewBase) @@ -1144,57 +1400,49 @@ GdkEvent* webkitWebViewBaseTakeContextMenuEvent(WebKitWebViewBase* webkitWebView return webkitWebViewBase->priv->contextMenuEvent.release(); } -#if USE(TEXTURE_MAPPER_GL) -void redirectedWindowDamagedCallback(void* data) -{ - gtk_widget_queue_draw(GTK_WIDGET(data)); -} -#endif - void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused) { WebKitWebViewBasePrivate* priv = webViewBase->priv; - if (priv->isFocused == focused) + if ((focused && priv->activityState & ActivityState::IsFocused) || (!focused && !(priv->activityState & ActivityState::IsFocused))) return; - unsigned viewStateFlags = ViewState::IsFocused; - priv->isFocused = focused; - - // If the view has received the focus and the window is not active - // mark the current window as active now. This can happen if the - // toplevel window is a GTK_WINDOW_POPUP and the focus has been - // set programatically like WebKitTestRunner does, because POPUP - // can't be focused. - if (priv->isFocused && !priv->isInWindowActive) { - priv->isInWindowActive = true; - viewStateFlags |= ViewState::WindowIsActive; - } - priv->pageProxy->viewStateDidChange(viewStateFlags); + ActivityState::Flags flagsToUpdate = ActivityState::IsFocused; + if (focused) { + priv->activityState |= ActivityState::IsFocused; + + // If the view has received the focus and the window is not active + // mark the current window as active now. This can happen if the + // toplevel window is a GTK_WINDOW_POPUP and the focus has been + // set programatically like WebKitTestRunner does, because POPUP + // can't be focused. + if (!(priv->activityState & ActivityState::WindowIsActive)) { + priv->activityState |= ActivityState::WindowIsActive; + flagsToUpdate |= ActivityState::WindowIsActive; + } + } else + priv->activityState &= ~ActivityState::IsFocused; + + webkitWebViewBaseScheduleUpdateActivityState(webViewBase, flagsToUpdate); } bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isInWindowActive; + return webViewBase->priv->activityState & ActivityState::WindowIsActive; } bool webkitWebViewBaseIsFocused(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isFocused; + return webViewBase->priv->activityState & ActivityState::IsFocused; } bool webkitWebViewBaseIsVisible(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->isVisible; + return webViewBase->priv->activityState & ActivityState::IsVisible; } bool webkitWebViewBaseIsInWindow(WebKitWebViewBase* webViewBase) { - return webViewBase->priv->toplevelOnScreenWindow; -} - -bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase* webViewBase) -{ - return webViewBase->priv->isWindowVisible; + return webViewBase->priv->activityState & ActivityState::IsInWindow; } void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase* webViewBase, WebKitWebViewBaseDownloadRequestHandler downloadHandler) @@ -1215,10 +1463,79 @@ void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase* webkitWebViewBase, void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase* webkitWebViewBase) { - webkitWebViewBase->priv->inputMethodFilter.setCursorRect(webkitWebViewBase->priv->pageProxy->editorState().cursorRect); + const auto& editorState = webkitWebViewBase->priv->pageProxy->editorState(); + if (!editorState.isMissingPostLayoutData) + webkitWebViewBase->priv->inputMethodFilter.setCursorRect(editorState.postLayoutData().caretRectAtStart); +} + +void webkitWebViewBaseSetContentsSize(WebKitWebViewBase* webkitWebViewBase, const IntSize& contentsSize) +{ + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + if (priv->contentsSize == contentsSize) + return; + priv->contentsSize = contentsSize; } void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase) { webkitWebViewBase->priv->clickCounter.reset(); } + +void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext); +} + +void webkitWebViewBaseUpdateAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(layerTreeContext); +} + +void webkitWebViewBaseExitAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(LayerTreeContext()); +} + +void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase* webkitWebViewBase) +{ + // Queue a resize to ensure the new DrawingAreaProxy is resized. + gtk_widget_queue_resize_no_redraw(GTK_WIDGET(webkitWebViewBase)); + +#if PLATFORM(X11) && USE(TEXTURE_MAPPER_GL) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return; + + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()); + ASSERT(drawingArea); + + if (!gtk_widget_get_realized(GTK_WIDGET(webkitWebViewBase))) + return; + + uint64_t windowID = GDK_WINDOW_XID(gtk_widget_get_window(GTK_WIDGET(webkitWebViewBase))); + drawingArea->setNativeSurfaceHandleForCompositing(windowID); +#else + UNUSED_PARAM(webkitWebViewBase); +#endif +} + +void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase) +{ + if (webkitWebViewBase->priv->acceleratedBackingStore) + webkitWebViewBase->priv->acceleratedBackingStore->update(LayerTreeContext()); +#if PLATFORM(X11) && USE(TEXTURE_MAPPER_GL) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return; + + if (!gtk_widget_get_realized(GTK_WIDGET(webkitWebViewBase))) + return; + + WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv; + DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(priv->pageProxy->drawingArea()); + ASSERT(drawingArea); + drawingArea->destroyNativeSurfaceHandleForCompositing(); +#endif +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp index 7b069dd94..fc2d053a7 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBaseAccessible.cpp @@ -29,7 +29,7 @@ struct _WebKitWebViewBaseAccessiblePrivate { WEBKIT_DEFINE_TYPE(WebKitWebViewBaseAccessible, webkit_web_view_base_accessible, ATK_TYPE_SOCKET) -static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget* widget, WebKitWebViewBaseAccessible* accessible) +static void webkitWebViewBaseAccessibleWidgetDestroyed(GtkWidget*, WebKitWebViewBaseAccessible* accessible) { accessible->priv->widget = 0; atk_object_notify_state_change(ATK_OBJECT(accessible), ATK_STATE_DEFUNCT, TRUE); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h index b9c38c265..6f5ba9d02 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBasePrivate.h @@ -28,20 +28,23 @@ #ifndef WebKitWebViewBasePrivate_h #define WebKitWebViewBasePrivate_h +#include "APIPageConfiguration.h" +#include "DragAndDropHandler.h" +#include "GestureController.h" #include "WebContextMenuProxyGtk.h" #include "WebInspectorProxy.h" #include "WebKitPrivate.h" #include "WebKitWebViewBase.h" #include "WebPageProxy.h" -WebKitWebViewBase* webkitWebViewBaseCreate(WebKit::WebContext*, WebKit::WebPageGroup*, WebKit::WebPageProxy*); +WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration&); GtkIMContext* webkitWebViewBaseGetIMContext(WebKitWebViewBase*); WebKit::WebPageProxy* webkitWebViewBaseGetPage(WebKitWebViewBase*); -void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, WebKit::WebContext*, WebKit::WebPageGroup*, WebKit::WebPageProxy*); +void webkitWebViewBaseCreateWebPage(WebKitWebViewBase*, Ref<API::PageConfiguration>&&); void webkitWebViewBaseSetTooltipText(WebKitWebViewBase*, const char*); void webkitWebViewBaseSetTooltipArea(WebKitWebViewBase*, const WebCore::IntRect&); void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase*); -void webkitWebViewBaseStartDrag(WebKitWebViewBase*, const WebCore::DragData&, PassRefPtr<WebKit::ShareableBitmap> dragImage); +void webkitWebViewBaseForwardNextWheelEvent(WebKitWebViewBase*); void webkitWebViewBaseChildMoveResize(WebKitWebViewBase*, GtkWidget*, const WebCore::IntRect&); void webkitWebViewBaseEnterFullScreen(WebKitWebViewBase*); void webkitWebViewBaseExitFullScreen(WebKitWebViewBase*); @@ -52,18 +55,13 @@ WebKit::WebContextMenuProxyGtk* webkitWebViewBaseGetActiveContextMenuProxy(WebKi GdkEvent* webkitWebViewBaseTakeContextMenuEvent(WebKitWebViewBase*); void webkitWebViewBaseSetInputMethodState(WebKitWebViewBase*, bool enabled); void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase*); -void webkitWebViewBaseUpdatePreferences(WebKitWebViewBase*); - -#if USE(TEXTURE_MAPPER_GL) -void webkitWebViewBaseQueueDrawOfAcceleratedCompositingResults(WebKitWebViewBase*); -#endif +void webkitWebViewBaseSetContentsSize(WebKitWebViewBase*, const WebCore::IntSize&); void webkitWebViewBaseSetFocus(WebKitWebViewBase*, bool focused); bool webkitWebViewBaseIsInWindowActive(WebKitWebViewBase*); bool webkitWebViewBaseIsFocused(WebKitWebViewBase*); bool webkitWebViewBaseIsVisible(WebKitWebViewBase*); bool webkitWebViewBaseIsInWindow(WebKitWebViewBase*); -bool webkitWebViewBaseIsWindowVisible(WebKitWebViewBase*); typedef void (*WebKitWebViewBaseDownloadRequestHandler) (WebKitWebViewBase*, WebKit::DownloadProxy*); void webkitWebViewBaseSetDownloadRequestHandler(WebKitWebViewBase*, WebKitWebViewBaseDownloadRequestHandler); @@ -73,5 +71,18 @@ void webkitWebViewBaseAddAuthenticationDialog(WebKitWebViewBase*, GtkWidget* aut void webkitWebViewBaseCancelAuthenticationDialog(WebKitWebViewBase*); void webkitWebViewBaseAddWebInspector(WebKitWebViewBase*, GtkWidget* inspector, WebKit::AttachmentSide); void webkitWebViewBaseResetClickCounter(WebKitWebViewBase*); +void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase*, const WebKit::LayerTreeContext&); +void webkitWebViewBaseUpdateAcceleratedCompositingMode(WebKitWebViewBase*, const WebKit::LayerTreeContext&); +void webkitWebViewBaseExitAcceleratedCompositingMode(WebKitWebViewBase*); +void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase*); +void webkitWebViewBasePageClosed(WebKitWebViewBase*); + +#if ENABLE(DRAG_SUPPORT) +WebKit::DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase*); +#endif + +#if HAVE(GTK_GESTURES) +WebKit::GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase*); +#endif #endif // WebKitWebViewBasePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp deleted file mode 100644 index 289ecdf03..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebKitWebViewGroup.h" - -#include "APIArray.h" -#include "APIString.h" -#include "WebKitPrivate.h" -#include "WebKitSettingsPrivate.h" -#include "WebKitWebViewGroupPrivate.h" -#include <glib/gi18n-lib.h> -#include <wtf/gobject/GRefPtr.h> -#include <wtf/text/CString.h> - -using namespace WebKit; - -/** - * SECTION: WebKitWebViewGroup - * @Short_description: Group of web views - * @Title: WebKitWebViewGroup - * @See_also: #WebKitWebView, #WebKitSettings - * - * A WebKitWebViewGroup represents a group of #WebKitWebView<!-- -->s that - * share things like settings. There's a default WebKitWebViewGroup where - * all #WebKitWebView<!-- -->s of the same #WebKitWebContext are added by default. - * To create a #WebKitWebView in a different WebKitWebViewGroup you can use - * webkit_web_view_new_with_group(). - * - * WebKitWebViewGroups are identified by a unique name given when the group is - * created with webkit_web_view_group_new(). - * WebKitWebViewGroups have a #WebKitSettings to control the settings of all - * #WebKitWebView<!-- -->s of the group. You can get the settings with - * webkit_web_view_group_get_settings() to handle the settings, or you can set - * your own #WebKitSettings with webkit_web_view_group_set_settings(). When - * the #WebKitSettings of a WebKitWebViewGroup changes, the signal notify::settings - * is emitted on the group. - */ - -enum { - PROP_0, - - PROP_SETTINGS -}; - -struct _WebKitWebViewGroupPrivate { - RefPtr<WebPageGroup> pageGroup; - CString name; - GRefPtr<WebKitSettings> settings; -}; - -WEBKIT_DEFINE_TYPE(WebKitWebViewGroup, webkit_web_view_group, G_TYPE_OBJECT) - -static void webkitWebViewGroupSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object); - - switch (propId) { - case PROP_SETTINGS: - webkit_web_view_group_set_settings(group, WEBKIT_SETTINGS(g_value_get_object(value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); - } -} - -static void webkitWebViewGroupGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(object); - - switch (propId) { - case PROP_SETTINGS: - g_value_set_object(value, webkit_web_view_group_get_settings(group)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); - } -} - -static void webkitWebViewGroupConstructed(GObject* object) -{ - G_OBJECT_CLASS(webkit_web_view_group_parent_class)->constructed(object); - - WebKitWebViewGroupPrivate* priv = WEBKIT_WEB_VIEW_GROUP(object)->priv; - priv->settings = adoptGRef(webkit_settings_new()); -} - -static void webkit_web_view_group_class_init(WebKitWebViewGroupClass* hitTestResultClass) -{ - GObjectClass* objectClass = G_OBJECT_CLASS(hitTestResultClass); - objectClass->set_property = webkitWebViewGroupSetProperty; - objectClass->get_property = webkitWebViewGroupGetProperty; - objectClass->constructed = webkitWebViewGroupConstructed; - - /** - * WebKitWebViewGroup:settings: - * - * The #WebKitSettings of the web view group. - */ - g_object_class_install_property( - objectClass, - PROP_SETTINGS, - g_param_spec_object( - "settings", - _("Settings"), - _("The settings of the web view group"), - WEBKIT_TYPE_SETTINGS, - WEBKIT_PARAM_READWRITE)); -} - -static void webkitWebViewGroupAttachSettingsToPageGroup(WebKitWebViewGroup* group) -{ - group->priv->pageGroup->setPreferences(webkitSettingsGetPreferences(group->priv->settings.get())); -} - -WebKitWebViewGroup* webkitWebViewGroupCreate(WebPageGroup* pageGroup) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL)); - group->priv->pageGroup = pageGroup; - webkitWebViewGroupAttachSettingsToPageGroup(group); - return group; -} - -WebPageGroup* webkitWebViewGroupGetPageGroup(WebKitWebViewGroup* group) -{ - return group->priv->pageGroup.get(); -} - -/** - * webkit_web_view_group_new: - * @name: (allow-none): the name of the group - * - * Creates a new #WebKitWebViewGroup with the given @name. - * If @name is %NULL a unique identifier name will be created - * automatically. - * The newly created #WebKitWebViewGroup doesn't contain any - * #WebKitWebView, web views are added to the new group when created - * with webkit_web_view_new_with_group() passing the group. - * - * Returns: (transfer full): a new #WebKitWebViewGroup - */ -WebKitWebViewGroup* webkit_web_view_group_new(const char* name) -{ - WebKitWebViewGroup* group = WEBKIT_WEB_VIEW_GROUP(g_object_new(WEBKIT_TYPE_WEB_VIEW_GROUP, NULL)); - group->priv->pageGroup = WebPageGroup::create(name ? String::fromUTF8(name) : String()); - webkitWebViewGroupAttachSettingsToPageGroup(group); - return group; -} - -/** - * webkit_web_view_group_get_name: - * @group: a #WebKitWebViewGroup - * - * Gets the name that uniquely identifies the #WebKitWebViewGroup. - * - * Returns: the name of @group - */ -const char* webkit_web_view_group_get_name(WebKitWebViewGroup* group) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); - - WebKitWebViewGroupPrivate* priv = group->priv; - if (priv->name.isNull()) - priv->name = priv->pageGroup->identifier().utf8(); - - return priv->name.data(); -} - -/** - * webkit_web_view_group_get_settings: - * @group: a #WebKitWebViewGroup - * - * Gets the #WebKitSettings of the #WebKitWebViewGroup. - * - * Returns: (transfer none): the settings of @group - */ -WebKitSettings* webkit_web_view_group_get_settings(WebKitWebViewGroup* group) -{ - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group), 0); - - return group->priv->settings.get(); -} - -/** - * webkit_web_view_group_set_settings: - * @group: a #WebKitWebViewGroup - * @settings: a #WebKitSettings - * - * Sets a new #WebKitSettings for the #WebKitWebViewGroup. The settings will - * affect to all the #WebKitWebView<!-- -->s of the group. - * #WebKitWebViewGroup<!-- -->s always have a #WebKitSettings so if you just want to - * modify a setting you can use webkit_web_view_group_get_settings() and modify the - * returned #WebKitSettings instead. - * Setting the same #WebKitSettings multiple times doesn't have any effect. - * You can monitor the settings of a #WebKitWebViewGroup by connecting to the - * notify::settings signal of @group. - */ -void webkit_web_view_group_set_settings(WebKitWebViewGroup* group, WebKitSettings* settings) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); - - if (group->priv->settings == settings) - return; - - group->priv->settings = settings; - webkitWebViewGroupAttachSettingsToPageGroup(group); - g_object_notify(G_OBJECT(group), "settings"); -} - -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_ALL, WebCore::InjectInAllFrames); -COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY, WebCore::InjectInTopFrameOnly); - -static PassRefPtr<API::Array> toAPIArray(const char* const* list) -{ - if (!list) - return 0; - - Vector<RefPtr<API::Object> > entries; - while (*list) { - entries.append(API::String::createFromUTF8String(*list)); - list++; - } - return API::Array::create(std::move(entries)); -} - -/** - * webkit_web_view_group_add_user_style_sheet: - * @group: a #WebKitWebViewGroup - * @source: the source of the style_sheet to inject - * @base_uri: (allow-none): the base URI to use when processing the style_sheet contents or %NULL for about:blank - * @whitelist: (array zero-terminated=1) (allow-none): a whitelist of URI patterns or %NULL - * @blacklist: (array zero-terminated=1) (allow-none): a blacklist of URI patterns or %NULL - * @injected_frames: a #WebKitInjectedContentFrames describing to which frames the style_sheet should apply - * - * Inject an external style sheet into pages. It is possible to only apply the style sheet - * to some URIs by passing non-null values for @whitelist or @blacklist. Passing a %NULL - * whitelist implies that all URIs are on the whitelist. The style sheet is applied if a URI matches - * the whitelist and not the blacklist. URI patterns must be of the form [protocol]://[host]/[path] - * where the host and path components can contain the wildcard character ('*') to represent zero - * or more other characters. - */ -void webkit_web_view_group_add_user_style_sheet(WebKitWebViewGroup* group, const char* source, const char* baseURI, const char* const* whitelist, const char* const* blacklist, WebKitInjectedContentFrames injectedFrames) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - g_return_if_fail(source); - - RefPtr<API::Array> webWhitelist = toAPIArray(whitelist); - RefPtr<API::Array> webBlacklist = toAPIArray(blacklist); - - // We always use UserStyleUserLevel to match the behavior of WKPageGroupAddUserStyleSheet. - group->priv->pageGroup->addUserStyleSheet( - String::fromUTF8(source), - String::fromUTF8(baseURI), - webWhitelist.get(), - webBlacklist.get(), - static_cast<WebCore::UserContentInjectedFrames>(injectedFrames), - WebCore::UserStyleUserLevel); -} - -/** - * webkit_web_view_group_remove_all_user_style_sheets: - * @group: a #WebKitWebViewGroup - * - * Remove all style sheets previously injected into this #WebKitWebViewGroup - * via webkit_web_view_group_add_user_style_sheet(). - */ -void webkit_web_view_group_remove_all_user_style_sheets(WebKitWebViewGroup* group) -{ - g_return_if_fail(WEBKIT_IS_WEB_VIEW_GROUP(group)); - group->priv->pageGroup->removeAllUserStyleSheets(); -} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h deleted file mode 100644 index 685f19904..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewGroup.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) -#error "Only <webkit2/webkit2.h> can be included directly." -#endif - -#ifndef WebKitWebViewGroup_h -#define WebKitWebViewGroup_h - -#include <glib-object.h> -#include <webkit2/WebKitDefines.h> -#include <webkit2/WebKitSettings.h> - -G_BEGIN_DECLS - -#define WEBKIT_TYPE_WEB_VIEW_GROUP (webkit_web_view_group_get_type()) -#define WEBKIT_WEB_VIEW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroup)) -#define WEBKIT_IS_WEB_VIEW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEB_VIEW_GROUP)) -#define WEBKIT_WEB_VIEW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroupClass)) -#define WEBKIT_IS_WEB_VIEW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_VIEW_GROUP)) -#define WEBKIT_WEB_VIEW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_VIEW_GROUP, WebKitWebViewGroupClass)) - -typedef struct _WebKitWebViewGroup WebKitWebViewGroup; -typedef struct _WebKitWebViewGroupClass WebKitWebViewGroupClass; -typedef struct _WebKitWebViewGroupPrivate WebKitWebViewGroupPrivate; - -struct _WebKitWebViewGroup { - GObject parent; - - WebKitWebViewGroupPrivate *priv; -}; - -struct _WebKitWebViewGroupClass { - GObjectClass parent_class; - - void (*_webkit_reserved0) (void); - void (*_webkit_reserved1) (void); - void (*_webkit_reserved2) (void); - void (*_webkit_reserved3) (void); -}; - -/** - * WebKitInjectedContentFrames: - * @WEBKIT_INJECTED_CONTENT_FRAMES_ALL: Content will be injected into all frames. - * @WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY: Content will only be injected into the main frame. - * - * Enum values used for determining into which frames content is injected. - */ -typedef enum { - WEBKIT_INJECTED_CONTENT_FRAMES_ALL, - WEBKIT_INJECTED_CONTENT_FRAMES_TOP_ONLY, -} WebKitInjectedContentFrames; - -WEBKIT_API GType -webkit_web_view_group_get_type (void); - -WEBKIT_API WebKitWebViewGroup * -webkit_web_view_group_new (const gchar *name); - -WEBKIT_API const gchar * -webkit_web_view_group_get_name (WebKitWebViewGroup *group); - -WEBKIT_API WebKitSettings * -webkit_web_view_group_get_settings (WebKitWebViewGroup *group); - -WEBKIT_API void -webkit_web_view_group_set_settings (WebKitWebViewGroup *group, - WebKitSettings *settings); - -WEBKIT_API void -webkit_web_view_group_add_user_style_sheet (WebKitWebViewGroup *group, - const gchar *source, - const gchar *base_uri, - const gchar * const *whitelist, - const gchar * const *blacklist, - WebKitInjectedContentFrames injected_frames); - -WEBKIT_API void -webkit_web_view_group_remove_all_user_style_sheets (WebKitWebViewGroup *group); - -G_END_DECLS - -#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h index 11591ff18..240d73088 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h @@ -27,6 +27,9 @@ #ifndef WebKitWebViewPrivate_h #define WebKitWebViewPrivate_h +#include "InstallMissingMediaPluginsPermissionRequest.h" +#include "WebContextMenuItemData.h" +#include "WebHitTestResultData.h" #include "WebImage.h" #include "WebKitWebView.h" #include <wtf/text/CString.h> @@ -34,19 +37,17 @@ void webkitWebViewLoadChanged(WebKitWebView*, WebKitLoadEvent); void webkitWebViewLoadFailed(WebKitWebView*, WebKitLoadEvent, const char* failingURI, GError*); void webkitWebViewLoadFailedWithTLSErrors(WebKitWebView*, const char* failingURI, GError*, GTlsCertificateFlags, GTlsCertificate*); -void webkitWebViewSetEstimatedLoadProgress(WebKitWebView*, double estimatedLoadProgress); -void webkitWebViewSetTitle(WebKitWebView*, const CString&); -void webkitWebViewUpdateURI(WebKitWebView*); -WebKit::WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView*, WebKit::ImmutableDictionary* windowFeatures); +WebKit::WebPageProxy* webkitWebViewCreateNewPage(WebKitWebView*, const WebCore::WindowFeatures&, WebKitNavigationAction*); void webkitWebViewReadyToShowPage(WebKitWebView*); void webkitWebViewRunAsModal(WebKitWebView*); void webkitWebViewClosePage(WebKitWebView*); void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message); bool webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message); CString webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText); +bool webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message); void webkitWebViewMakePermissionRequest(WebKitWebView*, WebKitPermissionRequest*); void webkitWebViewMakePolicyDecision(WebKitWebView*, WebKitPolicyDecisionType, WebKitPolicyDecision*); -void webkitWebViewMouseTargetChanged(WebKitWebView*, WebKit::WebHitTestResult*, unsigned modifiers); +void webkitWebViewMouseTargetChanged(WebKitWebView*, const WebKit::WebHitTestResultData&, unsigned modifiers); void webkitWebViewPrintFrame(WebKitWebView*, WebKit::WebFrameProxy*); void webkitWebViewResourceLoadStarted(WebKitWebView*, WebKit::WebFrameProxy*, uint64_t resourceIdentifier, WebKitURIRequest*); void webkitWebViewRunFileChooserRequest(WebKitWebView*, WebKitFileChooserRequest*); @@ -55,10 +56,16 @@ void webKitWebViewDidReceiveSnapshot(WebKitWebView*, uint64_t callbackID, WebKit void webkitWebViewRemoveLoadingWebResource(WebKitWebView*, uint64_t resourceIdentifier); bool webkitWebViewEnterFullScreen(WebKitWebView*); bool webkitWebViewLeaveFullScreen(WebKitWebView*); -void webkitWebViewPopulateContextMenu(WebKitWebView*, API::Array* proposedMenu, WebKit::WebHitTestResult*); +void webkitWebViewPopulateContextMenu(WebKitWebView*, const Vector<WebKit::WebContextMenuItemData>& proposedMenu, const WebKit::WebHitTestResultData&, GVariant*); void webkitWebViewSubmitFormRequest(WebKitWebView*, WebKitFormSubmissionRequest*); void webkitWebViewHandleAuthenticationChallenge(WebKitWebView*, WebKit::AuthenticationChallengeProxy*); void webkitWebViewInsecureContentDetected(WebKitWebView*, WebKitInsecureContentEvent); +bool webkitWebViewEmitShowNotification(WebKitWebView*, WebKitNotification*); +bool webkitWebViewEmitRunColorChooser(WebKitWebView*, WebKitColorChooserRequest*); void webkitWebViewWebProcessCrashed(WebKitWebView*); +void webkitWebViewIsPlayingAudioChanged(WebKitWebView*); +void webkitWebViewSelectionDidChange(WebKitWebView*); +void webkitWebViewRequestInstallMissingMediaPlugins(WebKitWebView*, WebKit::InstallMissingMediaPluginsPermissionRequest&); +WebKitWebsiteDataManager* webkitWebViewGetWebsiteDataManager(WebKitWebView*); #endif // WebKitWebViewPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp new file mode 100644 index 000000000..325d0141c --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.cpp @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebViewSessionState.h" + +#include "WebKitWebViewSessionStatePrivate.h" +#include <wtf/glib/GRefPtr.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebKit; + +struct _WebKitWebViewSessionState { + _WebKitWebViewSessionState(SessionState&& state) + : sessionState(WTFMove(state)) + , referenceCount(1) + { + } + + SessionState sessionState; + int referenceCount; +}; + +G_DEFINE_BOXED_TYPE(WebKitWebViewSessionState, webkit_web_view_session_state, webkit_web_view_session_state_ref, webkit_web_view_session_state_unref) + +static const guint16 g_sessionStateVersion = 1; +#define HTTP_BODY_ELEMENT_TYPE_STRING_V1 "(uaysxmxmds)" +#define HTTP_BODY_ELEMENT_FORMAT_STRING_V1 "(uay&sxmxmd&s)" +#define HTTP_BODY_TYPE_STRING_V1 "m(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")" +#define HTTP_BODY_FORMAT_STRING_V1 "m(&sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")" +#define FRAME_STATE_TYPE_STRING_V1 "(ssssasmayxx(ii)d" HTTP_BODY_TYPE_STRING_V1 "av)" +#define FRAME_STATE_FORMAT_STRING_V1 "(&s&s&s&sasmayxx(ii)d@" HTTP_BODY_TYPE_STRING_V1 "av)" +#define BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1 "(ts" FRAME_STATE_TYPE_STRING_V1 "u)" +#define BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1 "(t&s@" FRAME_STATE_TYPE_STRING_V1 "u)" +#define SESSION_STATE_TYPE_STRING_V1 "(qa" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1 "mu)" + +// Use our own enum types to ensure the serialized format even if the core enums change. +enum ExternalURLsPolicy { + Allow, + AllowExternalSchemes, + NotAllow +}; + +static inline unsigned toExternalURLsPolicy(WebCore::ShouldOpenExternalURLsPolicy policy) +{ + switch (policy) { + case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow: + return ExternalURLsPolicy::Allow; + case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes: + return ExternalURLsPolicy::AllowExternalSchemes; + case WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow: + return ExternalURLsPolicy::NotAllow; + } + + return ExternalURLsPolicy::NotAllow; +} + +static inline WebCore::ShouldOpenExternalURLsPolicy toWebCoreExternalURLsPolicy(unsigned policy) +{ + switch (policy) { + case ExternalURLsPolicy::Allow: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow; + case ExternalURLsPolicy::AllowExternalSchemes: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes; + case ExternalURLsPolicy::NotAllow: + return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow; + } + + return WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow; +} + +enum HTMLBodyElementType { + Data, + File, + Blob +}; + +static inline unsigned toHTMLBodyElementType(HTTPBody::Element::Type type) +{ + switch (type) { + case HTTPBody::Element::Type::Data: + return HTMLBodyElementType::Data; + case HTTPBody::Element::Type::File: + return HTMLBodyElementType::File; + case HTTPBody::Element::Type::Blob: + return HTMLBodyElementType::Blob; + } + + return HTMLBodyElementType::Data; +} + +static inline HTTPBody::Element::Type toHTTPBodyElementType(unsigned type) +{ + switch (type) { + case HTMLBodyElementType::Data: + return HTTPBody::Element::Type::Data; + case HTMLBodyElementType::File: + return HTTPBody::Element::Type::File; + case HTMLBodyElementType::Blob: + return HTTPBody::Element::Type::Blob; + } + + return HTTPBody::Element::Type::Data; +} + +static inline void encodeHTTPBody(GVariantBuilder* sessionBuilder, const HTTPBody& httpBody) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("(sa" HTTP_BODY_ELEMENT_TYPE_STRING_V1 ")")); + g_variant_builder_add(sessionBuilder, "s", httpBody.contentType.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" HTTP_BODY_ELEMENT_TYPE_STRING_V1)); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_ELEMENT_TYPE_STRING_V1)); + for (const auto& element : httpBody.elements) { + g_variant_builder_add(sessionBuilder, "u", toHTMLBodyElementType(element.type)); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay")); + for (auto item : element.data) + g_variant_builder_add(sessionBuilder, "y", item); + g_variant_builder_close(sessionBuilder); + g_variant_builder_add(sessionBuilder, "s", element.filePath.utf8().data()); + g_variant_builder_add(sessionBuilder, "x", element.fileStart); + if (element.fileLength) + g_variant_builder_add(sessionBuilder, "mx", TRUE, element.fileLength.value()); + else + g_variant_builder_add(sessionBuilder, "mx", FALSE); + if (element.expectedFileModificationTime) + g_variant_builder_add(sessionBuilder, "md", TRUE, element.expectedFileModificationTime.value()); + else + g_variant_builder_add(sessionBuilder, "md", FALSE); + g_variant_builder_add(sessionBuilder, "s", element.blobURLString.utf8().data()); + } + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); +} + +static inline void encodeFrameState(GVariantBuilder* sessionBuilder, const FrameState& frameState) +{ + g_variant_builder_add(sessionBuilder, "s", frameState.urlString.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.originalURLString.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.referrer.utf8().data()); + g_variant_builder_add(sessionBuilder, "s", frameState.target.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("as")); + for (const auto& state : frameState.documentState) + g_variant_builder_add(sessionBuilder, "s", state.utf8().data()); + g_variant_builder_close(sessionBuilder); + if (!frameState.stateObjectData) + g_variant_builder_add(sessionBuilder, "may", FALSE); + else { + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("may")); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("ay")); + for (auto item : frameState.stateObjectData.value()) + g_variant_builder_add(sessionBuilder, "y", item); + g_variant_builder_close(sessionBuilder); + g_variant_builder_close(sessionBuilder); + } + g_variant_builder_add(sessionBuilder, "x", frameState.documentSequenceNumber); + g_variant_builder_add(sessionBuilder, "x", frameState.itemSequenceNumber); + g_variant_builder_add(sessionBuilder, "(ii)", frameState.scrollPosition.x(), frameState.scrollPosition.y()); + g_variant_builder_add(sessionBuilder, "d", frameState.pageScaleFactor); + if (!frameState.httpBody) + g_variant_builder_add(sessionBuilder, HTTP_BODY_TYPE_STRING_V1, FALSE); + else { + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(HTTP_BODY_TYPE_STRING_V1)); + encodeHTTPBody(sessionBuilder, frameState.httpBody.value()); + g_variant_builder_close(sessionBuilder); + } + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("av")); + for (const auto& child : frameState.children) { + GVariantBuilder frameStateBuilder; + g_variant_builder_init(&frameStateBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1)); + encodeFrameState(&frameStateBuilder, child); + g_variant_builder_add(sessionBuilder, "v", g_variant_builder_end(&frameStateBuilder)); + } + g_variant_builder_close(sessionBuilder); +} + +static inline void encodePageState(GVariantBuilder* sessionBuilder, const PageState& pageState) +{ + g_variant_builder_add(sessionBuilder, "s", pageState.title.utf8().data()); + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(FRAME_STATE_TYPE_STRING_V1)); + encodeFrameState(sessionBuilder, pageState.mainFrameState); + g_variant_builder_close(sessionBuilder); + g_variant_builder_add(sessionBuilder, "u", toExternalURLsPolicy(pageState.shouldOpenExternalURLsPolicy)); +} + +static inline void encodeBackForwardListItemState(GVariantBuilder* sessionBuilder, const BackForwardListItemState& item) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE(BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1)); + g_variant_builder_add(sessionBuilder, "t", item.identifier); + encodePageState(sessionBuilder, item.pageState); + g_variant_builder_close(sessionBuilder); +} + +static inline void encodeBackForwardListState(GVariantBuilder* sessionBuilder, const BackForwardListState& backForwardListState) +{ + g_variant_builder_open(sessionBuilder, G_VARIANT_TYPE("a" BACK_FORWARD_LIST_ITEM_TYPE_STRING_V1)); + for (const auto& item : backForwardListState.items) + encodeBackForwardListItemState(sessionBuilder, item); + g_variant_builder_close(sessionBuilder); + + if (backForwardListState.currentIndex) + g_variant_builder_add(sessionBuilder, "mu", TRUE, backForwardListState.currentIndex.value()); + else + g_variant_builder_add(sessionBuilder, "mu", FALSE); +} + +static GBytes* encodeSessionState(const SessionState& sessionState) +{ + GVariantBuilder sessionBuilder; + g_variant_builder_init(&sessionBuilder, G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1)); + g_variant_builder_add(&sessionBuilder, "q", g_sessionStateVersion); + encodeBackForwardListState(&sessionBuilder, sessionState.backForwardListState); + GRefPtr<GVariant> variant = g_variant_builder_end(&sessionBuilder); + return g_variant_get_data_as_bytes(variant.get()); +} + +static inline bool decodeHTTPBody(GVariant* httpBodyVariant, HTTPBody& httpBody) +{ + gboolean hasHTTPBody; + const char* contentType; + GUniqueOutPtr<GVariantIter> elementsIter; + g_variant_get(httpBodyVariant, HTTP_BODY_FORMAT_STRING_V1, &hasHTTPBody, &contentType, &elementsIter.outPtr()); + if (!hasHTTPBody) + return false; + httpBody.contentType = String::fromUTF8(contentType); + gsize elementsLength = g_variant_iter_n_children(elementsIter.get()); + if (!elementsLength) + return true; + httpBody.elements.reserveInitialCapacity(elementsLength); + unsigned type; + GVariantIter* dataIter; + const char* filePath; + gint64 fileStart; + gboolean hasFileLength; + gint64 fileLength; + gboolean hasFileModificationTime; + gdouble fileModificationTime; + const char* blobURLString; + while (g_variant_iter_loop(elementsIter.get(), HTTP_BODY_ELEMENT_FORMAT_STRING_V1, &type, &dataIter, &filePath, &fileStart, &hasFileLength, &fileLength, &hasFileModificationTime, &fileModificationTime, &blobURLString)) { + HTTPBody::Element element; + element.type = toHTTPBodyElementType(type); + if (gsize dataLength = g_variant_iter_n_children(dataIter)) { + element.data.reserveInitialCapacity(dataLength); + guchar dataValue; + while (g_variant_iter_next(dataIter, "y", &dataValue)) + element.data.uncheckedAppend(dataValue); + } + element.filePath = String::fromUTF8(filePath); + element.fileStart = fileStart; + if (hasFileLength) + element.fileLength = fileLength; + if (hasFileModificationTime) + element.expectedFileModificationTime = fileModificationTime; + element.blobURLString = String::fromUTF8(blobURLString); + + httpBody.elements.uncheckedAppend(WTFMove(element)); + } + + return true; +} + +static inline void decodeFrameState(GVariant* frameStateVariant, FrameState& frameState) +{ + const char* urlString; + const char* originalURLString; + const char* referrer; + const char* target; + GUniqueOutPtr<GVariantIter> documentStateIter; + GUniqueOutPtr<GVariantIter> stateObjectDataIter; + gint64 documentSequenceNumber; + gint64 itemSequenceNumber; + gint32 scrollPositionX, scrollPositionY; + gdouble pageScaleFactor; + GVariant* httpBodyVariant; + GUniqueOutPtr<GVariantIter> childrenIter; + g_variant_get(frameStateVariant, FRAME_STATE_FORMAT_STRING_V1, &urlString, &originalURLString, &referrer, &target, + &documentStateIter.outPtr(), &stateObjectDataIter.outPtr(), &documentSequenceNumber, &itemSequenceNumber, + &scrollPositionX, &scrollPositionY, &pageScaleFactor, &httpBodyVariant, &childrenIter.outPtr()); + frameState.urlString = String::fromUTF8(urlString); + frameState.originalURLString = String::fromUTF8(originalURLString); + // frameState.referrer must not be an empty string since we never want to + // send an empty Referer header. Bug #159606. + if (strlen(referrer)) + frameState.referrer = String::fromUTF8(referrer); + frameState.target = String::fromUTF8(target); + if (gsize documentStateLength = g_variant_iter_n_children(documentStateIter.get())) { + frameState.documentState.reserveInitialCapacity(documentStateLength); + const char* documentStateString; + while (g_variant_iter_next(documentStateIter.get(), "&s", &documentStateString)) + frameState.documentState.uncheckedAppend(String::fromUTF8(documentStateString)); + } + if (stateObjectDataIter) { + Vector<uint8_t> stateObjectVector; + if (gsize stateObjectDataLength = g_variant_iter_n_children(stateObjectDataIter.get())) { + stateObjectVector.reserveInitialCapacity(stateObjectDataLength); + guchar stateObjectDataValue; + while (g_variant_iter_next(stateObjectDataIter.get(), "y", &stateObjectDataValue)) + stateObjectVector.uncheckedAppend(stateObjectDataValue); + } + frameState.stateObjectData = WTFMove(stateObjectVector); + } + frameState.documentSequenceNumber = documentSequenceNumber; + frameState.itemSequenceNumber = itemSequenceNumber; + frameState.scrollPosition.setX(scrollPositionX); + frameState.scrollPosition.setY(scrollPositionY); + frameState.pageScaleFactor = pageScaleFactor; + HTTPBody httpBody; + if (decodeHTTPBody(httpBodyVariant, httpBody)) + frameState.httpBody = WTFMove(httpBody); + g_variant_unref(httpBodyVariant); + while (GRefPtr<GVariant> child = adoptGRef(g_variant_iter_next_value(childrenIter.get()))) { + FrameState childFrameState; + GRefPtr<GVariant> childVariant = adoptGRef(g_variant_get_variant(child.get())); + decodeFrameState(childVariant.get(), childFrameState); + frameState.children.append(WTFMove(childFrameState)); + } +} + +static inline void decodeBackForwardListItemState(GVariantIter* backForwardListStateIter, BackForwardListState& backForwardListState) +{ + gsize backForwardListStateLength = g_variant_iter_n_children(backForwardListStateIter); + if (!backForwardListStateLength) + return; + + backForwardListState.items.reserveInitialCapacity(backForwardListStateLength); + guint64 identifier; + const char* title; + GVariant* frameStateVariant; + unsigned shouldOpenExternalURLsPolicy; + while (g_variant_iter_loop(backForwardListStateIter, BACK_FORWARD_LIST_ITEM_FORMAT_STRING_V1, &identifier, &title, &frameStateVariant, &shouldOpenExternalURLsPolicy)) { + BackForwardListItemState state; + state.identifier = identifier; + state.pageState.title = String::fromUTF8(title); + decodeFrameState(frameStateVariant, state.pageState.mainFrameState); + state.pageState.shouldOpenExternalURLsPolicy = toWebCoreExternalURLsPolicy(shouldOpenExternalURLsPolicy); + backForwardListState.items.uncheckedAppend(WTFMove(state)); + } +} + +static bool decodeSessionState(GBytes* data, SessionState& sessionState) +{ + GRefPtr<GVariant> variant = g_variant_new_from_bytes(G_VARIANT_TYPE(SESSION_STATE_TYPE_STRING_V1), data, FALSE); + if (!g_variant_is_normal_form(variant.get())) + return false; + + guint16 version; + GUniqueOutPtr<GVariantIter> backForwardListStateIter; + gboolean hasCurrentIndex; + guint32 currentIndex; + g_variant_get(variant.get(), SESSION_STATE_TYPE_STRING_V1, &version, &backForwardListStateIter.outPtr(), &hasCurrentIndex, ¤tIndex); + if (!version || version > g_sessionStateVersion) + return false; + + decodeBackForwardListItemState(backForwardListStateIter.get(), sessionState.backForwardListState); + + if (hasCurrentIndex) + sessionState.backForwardListState.currentIndex = currentIndex; + return true; +} + +WebKitWebViewSessionState* webkitWebViewSessionStateCreate(SessionState&& sessionState) +{ + WebKitWebViewSessionState* state = static_cast<WebKitWebViewSessionState*>(fastMalloc(sizeof(WebKitWebViewSessionState))); + new (state) WebKitWebViewSessionState(WTFMove(sessionState)); + return state; +} + +const SessionState& webkitWebViewSessionStateGetSessionState(WebKitWebViewSessionState* state) +{ + return state->sessionState; +} + +/** + * webkit_web_view_session_state_new: + * @data: a #GBytes + * + * Creates a new #WebKitWebViewSessionState from serialized data. + * + * Returns: (transfer full): a new #WebKitWebViewSessionState, or %NULL if @data doesn't contain a + * valid serialized #WebKitWebViewSessionState. + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_session_state_new(GBytes* data) +{ + g_return_val_if_fail(data, nullptr); + + SessionState sessionState; + if (!decodeSessionState(data, sessionState)) + return nullptr; + return webkitWebViewSessionStateCreate(WTFMove(sessionState)); +} + +/** + * webkit_web_view_session_state_ref: + * @state: a #WebKitWebViewSessionState + * + * Atomically increments the reference count of @state by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #WebKitWebViewSessionState + * + * Since: 2.12 + */ +WebKitWebViewSessionState* webkit_web_view_session_state_ref(WebKitWebViewSessionState* state) +{ + g_return_val_if_fail(state, nullptr); + g_atomic_int_inc(&state->referenceCount); + return state; +} + +/** + * webkit_web_view_session_state_unref: + * @state: a #WebKitWebViewSessionState + * + * Atomically decrements the reference count of @state by one. If the + * reference count drops to 0, all memory allocated by the #WebKitWebViewSessionState is + * released. This function is MT-safe and may be called from any thread. + * + * Since: 2.12 + */ +void webkit_web_view_session_state_unref(WebKitWebViewSessionState* state) +{ + g_return_if_fail(state); + if (g_atomic_int_dec_and_test(&state->referenceCount)) { + state->~WebKitWebViewSessionState(); + fastFree(state); + } +} + +/** + * webkit_web_view_session_state_serialize: + * @state: a #WebKitWebViewSessionState + * + * Serializes a #WebKitWebViewSessionState. + * + * Returns: (transfer full): a #GBytes containing the @state serialized. + * + * Since: 2.12 + */ +GBytes* webkit_web_view_session_state_serialize(WebKitWebViewSessionState* state) +{ + g_return_val_if_fail(state, nullptr); + + return encodeSessionState(state->sessionState); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.h index eef16405e..73f4a4a69 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitCertificateInfo.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionState.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Samsung Electronics Inc. All rights reserved. + * Copyright (C) 2016 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -21,33 +21,32 @@ #error "Only <webkit2/webkit2.h> can be included directly." #endif -#ifndef WebKitCertificateInfo_h -#define WebKitCertificateInfo_h +#ifndef WebKitWebViewSessionState_h +#define WebKitWebViewSessionState_h -#include <gio/gio.h> #include <glib-object.h> #include <webkit2/WebKitDefines.h> G_BEGIN_DECLS -#define WEBKIT_TYPE_CERTIFICATE_INFO (webkit_certificate_info_get_type()) +#define WEBKIT_TYPE_WEB_VIEW_SESSION_STATE (webkit_web_view_session_state_get_type()) -typedef struct _WebKitCertificateInfo WebKitCertificateInfo; +typedef struct _WebKitWebViewSessionState WebKitWebViewSessionState; WEBKIT_API GType -webkit_certificate_info_get_type (void); +webkit_web_view_session_state_get_type (void); -WEBKIT_API WebKitCertificateInfo * -webkit_certificate_info_copy (WebKitCertificateInfo *info); +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_session_state_new (GBytes *data); -WEBKIT_API void -webkit_certificate_info_free (WebKitCertificateInfo *info); +WEBKIT_API WebKitWebViewSessionState * +webkit_web_view_session_state_ref (WebKitWebViewSessionState *state); -WEBKIT_API GTlsCertificate * -webkit_certificate_info_get_tls_certificate (WebKitCertificateInfo *info); +WEBKIT_API void +webkit_web_view_session_state_unref (WebKitWebViewSessionState *state); -WEBKIT_API GTlsCertificateFlags -webkit_certificate_info_get_tls_errors (WebKitCertificateInfo *info); +WEBKIT_API GBytes * +webkit_web_view_session_state_serialize (WebKitWebViewSessionState *state); G_END_DECLS diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h new file mode 100644 index 000000000..4c7f4e15a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewSessionStatePrivate.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "SessionState.h" +#include "WebKitWebViewSessionState.h" + +#ifndef WebKitWebViewSessionStatePrivate_h +#define WebKitWebViewSessionStatePrivate_h + +WebKitWebViewSessionState* webkitWebViewSessionStateCreate(WebKit::SessionState&&); +const WebKit::SessionState& webkitWebViewSessionStateGetSessionState(WebKitWebViewSessionState*); + +#endif // WebKitWebViewSessionStatePrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp new file mode 100644 index 000000000..43d4dee16 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebsiteData.h" + +#include "WebKitSecurityOriginPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include <glib/gi18n.h> +#include <wtf/HashTable.h> +#include <wtf/Vector.h> + +using namespace WebKit; + +/** + * SECTION: WebKitWebsiteData + * @Short_description: Website data + * @Title: WebKitWebsiteData + * @See_also: #WebKitWebsiteDataManager + * + * WebKitWebsiteData represents data stored in the client by a particular website. + * A website is normally a set of URLs grouped by domain name. You can get the website name, + * which is usually the domain, with webkit_website_data_get_name(). + * Documents loaded from the file system, like file:// URIs, are all grouped in the same WebKitWebsiteData + * with the name "Local files". + * + * A website can store different types of data in the client side. #WebKitWebsiteDataTypes is an enum containing + * all the possible data types; use webkit_website_data_get_types() to get the bitmask of data types. + * It's also possible to know the size of the data stored for some of the #WebKitWebsiteDataTypes by using + * webkit_website_data_get_size(). + * + * A list of WebKitWebsiteData can be retrieved with webkit_website_data_manager_fetch(). See #WebKitWebsiteDataManager + * for more information. + * + * Since: 2.16 + */ +struct _WebKitWebsiteData { + explicit _WebKitWebsiteData(WebsiteDataRecord&& websiteDataDecord) + : record(WTFMove(websiteDataDecord)) + { + } + + WebsiteDataRecord record; + CString displayName; + int referenceCount { 1 }; +}; + +G_DEFINE_BOXED_TYPE(WebKitWebsiteData, webkit_website_data, webkit_website_data_ref, webkit_website_data_unref) + +static bool recordContainsSupportedDataTypes(const WebsiteDataRecord& record) +{ + static const OptionSet<WebsiteDataType> typesSupported = { + WebsiteDataType::MemoryCache, + WebsiteDataType::DiskCache, + WebsiteDataType::OfflineWebApplicationCache, + WebsiteDataType::SessionStorage, + WebsiteDataType::LocalStorage, + WebsiteDataType::WebSQLDatabases, + WebsiteDataType::IndexedDBDatabases, +#if ENABLE(NETSCAPE_PLUGIN_API) + WebsiteDataType::PlugInData, +#endif + WebsiteDataType::Cookies + }; + return record.types.contains(typesSupported); +} + +static WebKitWebsiteDataTypes toWebKitWebsiteDataTypes(OptionSet<WebsiteDataType> types) +{ + uint32_t returnValue = 0; + if (types.contains(WebsiteDataType::MemoryCache)) + returnValue |= WEBKIT_WEBSITE_DATA_MEMORY_CACHE; + if (types.contains(WebsiteDataType::DiskCache)) + returnValue |= WEBKIT_WEBSITE_DATA_DISK_CACHE; + if (types.contains(WebsiteDataType::OfflineWebApplicationCache)) + returnValue |= WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE; + if (types.contains(WebsiteDataType::SessionStorage)) + returnValue |= WEBKIT_WEBSITE_DATA_SESSION_STORAGE; + if (types.contains(WebsiteDataType::LocalStorage)) + returnValue |= WEBKIT_WEBSITE_DATA_LOCAL_STORAGE; + if (types.contains(WebsiteDataType::WebSQLDatabases)) + returnValue |= WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES; + if (types.contains(WebsiteDataType::IndexedDBDatabases)) + returnValue |= WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES; +#if ENABLE(NETSCAPE_PLUGIN_API) + if (types.contains(WebsiteDataType::PlugInData)) + returnValue |= WEBKIT_WEBSITE_DATA_PLUGIN_DATA; +#endif + if (types.contains(WebsiteDataType::Cookies)) + returnValue |= WEBKIT_WEBSITE_DATA_COOKIES; + return static_cast<WebKitWebsiteDataTypes>(returnValue); +} + +WebKitWebsiteData* webkitWebsiteDataCreate(WebsiteDataRecord&& record) +{ + if (!recordContainsSupportedDataTypes(record)) + return nullptr; + + WebKitWebsiteData* websiteData = static_cast<WebKitWebsiteData*>(fastMalloc(sizeof(WebKitWebsiteData))); + new (websiteData) WebKitWebsiteData(WTFMove(record)); + return websiteData; +} + +const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData* websiteData) +{ + ASSERT(websiteData); + return websiteData->record; +} + +/** + * webkit_website_data_ref: + * @website_data: a #WebKitWebsiteData + * + * Atomically increments the reference count of @website_data by one. + * This function is MT-safe and may be called from any thread. + * + * Returns: The passed #WebKitWebsiteData + * + * Since: 2.16 + */ +WebKitWebsiteData* webkit_website_data_ref(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, nullptr); + + g_atomic_int_inc(&websiteData->referenceCount); + return websiteData; +} + +/** + * webkit_website_data_unref: + * @website_data: A #WebKitWebsiteData + * + * Atomically decrements the reference count of @website_data by one. + * If the reference count drops to 0, all memory allocated by + * #WebKitWebsiteData is released. This function is MT-safe and may be + * called from any thread. + * + * Since: 2.16 + */ +void webkit_website_data_unref(WebKitWebsiteData* websiteData) +{ + g_return_if_fail(websiteData); + + if (g_atomic_int_dec_and_test(&websiteData->referenceCount)) { + websiteData->~WebKitWebsiteData(); + fastFree(websiteData); + } +} + +/** + * webkit_website_data_get_name: + * @website_data: a #WebKitWebsiteData + * + * Gets the name of #WebKitWebsiteData. This is the website name, normally represented by + * a domain or host name. All local documents are grouped in the same #WebKitWebsiteData using + * the name "Local files". + * + * Returns: the website name of @website_data. + * + * Since: 2.16 + */ +const char* webkit_website_data_get_name(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, nullptr); + + if (websiteData->displayName.isNull()) { + if (websiteData->record.displayName == "Local documents on your computer") + websiteData->displayName = _("Local files"); + else + websiteData->displayName = websiteData->record.displayName.utf8(); + } + return websiteData->displayName.data(); +} + +/** + * webkit_website_data_get_types: + * @website_data: a #WebKitWebsiteData + * + * Gets the types of data stored in the client for a #WebKitWebsiteData. These are the + * types actually present, not the types queried with webkit_website_data_manager_fetch(). + * + * Returns: a bitmask of #WebKitWebsiteDataTypes in @website_data + * + * Since: 2.16 + */ +WebKitWebsiteDataTypes webkit_website_data_get_types(WebKitWebsiteData* websiteData) +{ + g_return_val_if_fail(websiteData, static_cast<WebKitWebsiteDataTypes>(0)); + + return toWebKitWebsiteDataTypes(websiteData->record.types); +} + +/** + * webkit_website_data_get_size: + * @website_data: a #WebKitWebsiteData + * @types: a bitmask of #WebKitWebsiteDataTypes + * + * Gets the size of the data of types @types in a #WebKitWebsiteData. + * Note that currently the data size is only known for %WEBKIT_WEBSITE_DATA_DISK_CACHE data type + * so for all other types 0 will be returned. + * + * Returns: the size of @website_data for the given @types. + * + * Since: 2.16 + */ +guint64 webkit_website_data_get_size(WebKitWebsiteData* websiteData, WebKitWebsiteDataTypes types) +{ + g_return_val_if_fail(websiteData, 0); + + if (!types || !websiteData->record.size) + return 0; + + guint64 totalSize = 0; + for (auto type : websiteData->record.size->typeSizes.keys()) { + if (type & types) + totalSize += websiteData->record.size->typeSizes.get(type); + } + + return totalSize; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h new file mode 100644 index 000000000..065047fe1 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteData.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitWebsiteData_h +#define WebKitWebsiteData_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_WEBSITE_DATA (webkit_website_data_get_type()) + +typedef struct _WebKitWebsiteData WebKitWebsiteData; + +/** + * WebKitWebsiteDataTypes: + * @WEBKIT_WEBSITE_DATA_MEMORY_CACHE: Memory cache. + * @WEBKIT_WEBSITE_DATA_DISK_CACHE: HTTP disk cache. + * @WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE: Offline web application cache. + * @WEBKIT_WEBSITE_DATA_SESSION_STORAGE: Session storage data. + * @WEBKIT_WEBSITE_DATA_LOCAL_STORAGE: Local storage data. + * @WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES: WebSQL databases. + * @WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES: IndexedDB databases. + * @WEBKIT_WEBSITE_DATA_PLUGIN_DATA: Plugins data. + * @WEBKIT_WEBSITE_DATA_COOKIES: Cookies. + * @WEBKIT_WEBSITE_DATA_ALL: All types. + * + * Enum values with flags representing types of Website data. + * + * Since: 2.16 + */ +typedef enum { + WEBKIT_WEBSITE_DATA_MEMORY_CACHE = 1 << 0, + WEBKIT_WEBSITE_DATA_DISK_CACHE = 1 << 1, + WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE = 1 << 2, + WEBKIT_WEBSITE_DATA_SESSION_STORAGE = 1 << 3, + WEBKIT_WEBSITE_DATA_LOCAL_STORAGE = 1 << 4, + WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES = 1 << 5, + WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES = 1 << 6, + WEBKIT_WEBSITE_DATA_PLUGIN_DATA = 1 << 7, + WEBKIT_WEBSITE_DATA_COOKIES = 1 << 8, + WEBKIT_WEBSITE_DATA_ALL = (1 << 9) - 1 +} WebKitWebsiteDataTypes; + +WEBKIT_API GType +webkit_website_data_get_type (void); + +WEBKIT_API WebKitWebsiteData * +webkit_website_data_ref (WebKitWebsiteData *website_data); + +WEBKIT_API void +webkit_website_data_unref (WebKitWebsiteData *website_data); + +WEBKIT_API const char * +webkit_website_data_get_name (WebKitWebsiteData *website_data); + +WEBKIT_API WebKitWebsiteDataTypes +webkit_website_data_get_types (WebKitWebsiteData *website_data); + +WEBKIT_API guint64 +webkit_website_data_get_size (WebKitWebsiteData *website_data, + WebKitWebsiteDataTypes types); + +G_END_DECLS + +#endif /* WebKitWebsiteData_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp new file mode 100644 index 000000000..ea430653f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.cpp @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitWebsiteDataManager.h" + +#include "APIWebsiteDataStore.h" +#include "WebKitCookieManagerPrivate.h" +#include "WebKitWebsiteDataManagerPrivate.h" +#include "WebKitWebsiteDataPrivate.h" +#include "WebsiteDataFetchOption.h" +#include <WebCore/FileSystem.h> +#include <glib/gi18n-lib.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebKit; + +/** + * SECTION: WebKitWebsiteDataManager + * @Short_description: Website data manager + * @Title: WebKitWebsiteDataManager + * @See_also: #WebKitWebContext, #WebKitWebsiteData + * + * WebKitWebsiteDataManager allows you to manage the data that websites + * can store in the client file system like databases or caches. + * You can use WebKitWebsiteDataManager to configure the local directories + * where the Website data will be stored, by creating a new manager with + * webkit_website_data_manager_new() passing the values you want to set. + * You can set all the possible configuration values or only some of them, + * a default value will be used automatically for the configuration options + * not provided. #WebKitWebsiteDataManager:base-data-directory and + * #WebKitWebsiteDataManager:base-cache-directory are two special properties + * that can be used to set a common base directory for all Website data and + * caches. It's possible to provide both, a base directory and a specific value, + * but in that case, the specific value takes precedence over the base directory. + * The newly created WebKitWebsiteDataManager must be passed as a construct property + * to a #WebKitWebContext, you can use webkit_web_context_new_with_website_data_manager() + * to create a new #WebKitWebContext with a WebKitWebsiteDataManager. + * In case you don't want to set any specific configuration, you don't need to create + * a WebKitWebsiteDataManager, the #WebKitWebContext will create a WebKitWebsiteDataManager + * with the default configuration. To get the WebKitWebsiteDataManager of a #WebKitWebContext + * you can use webkit_web_context_get_website_data_manager(). + * + * A WebKitWebsiteDataManager can also be ephemeral and then all the directories configuration + * is not needed because website data will never persist. You can create an ephemeral WebKitWebsiteDataManager + * with webkit_website_data_manager_new_ephemeral(). Then you can pass an ephemeral WebKitWebsiteDataManager to + * a #WebKitWebContext to make it ephemeral or use webkit_web_context_new_ephemeral() and the WebKitWebsiteDataManager + * will be automatically created by the #WebKitWebContext. + * + * WebKitWebsiteDataManager can also be used to fetch websites data, remove data + * stored by particular websites, or clear data for all websites modified since a given + * period of time. + * + * Since: 2.10 + */ + +using namespace WebKit; + +enum { + PROP_0, + + PROP_BASE_DATA_DIRECTORY, + PROP_BASE_CACHE_DIRECTORY, + PROP_LOCAL_STORAGE_DIRECTORY, + PROP_DISK_CACHE_DIRECTORY, + PROP_APPLICATION_CACHE_DIRECTORY, + PROP_INDEXEDDB_DIRECTORY, + PROP_WEBSQL_DIRECTORY, + PROP_IS_EPHEMERAL +}; + +struct _WebKitWebsiteDataManagerPrivate { + ~_WebKitWebsiteDataManagerPrivate() + { + ASSERT(processPools.isEmpty()); + } + + RefPtr<API::WebsiteDataStore> websiteDataStore; + GUniquePtr<char> baseDataDirectory; + GUniquePtr<char> baseCacheDirectory; + GUniquePtr<char> localStorageDirectory; + GUniquePtr<char> diskCacheDirectory; + GUniquePtr<char> applicationCacheDirectory; + GUniquePtr<char> indexedDBDirectory; + GUniquePtr<char> webSQLDirectory; + + GRefPtr<WebKitCookieManager> cookieManager; + Vector<WebProcessPool*> processPools; +}; + +WEBKIT_DEFINE_TYPE(WebKitWebsiteDataManager, webkit_website_data_manager, G_TYPE_OBJECT) + +static void webkitWebsiteDataManagerGetProperty(GObject* object, guint propID, GValue* value, GParamSpec* paramSpec) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object); + + switch (propID) { + case PROP_BASE_DATA_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_base_data_directory(manager)); + break; + case PROP_BASE_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_base_cache_directory(manager)); + break; + case PROP_LOCAL_STORAGE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_local_storage_directory(manager)); + break; + case PROP_DISK_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_disk_cache_directory(manager)); + break; + case PROP_APPLICATION_CACHE_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_offline_application_cache_directory(manager)); + break; + case PROP_INDEXEDDB_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_indexeddb_directory(manager)); + break; + case PROP_WEBSQL_DIRECTORY: + g_value_set_string(value, webkit_website_data_manager_get_websql_directory(manager)); + break; + case PROP_IS_EPHEMERAL: + g_value_set_boolean(value, webkit_website_data_manager_is_ephemeral(manager)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebsiteDataManagerSetProperty(GObject* object, guint propID, const GValue* value, GParamSpec* paramSpec) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(object); + + switch (propID) { + case PROP_BASE_DATA_DIRECTORY: + manager->priv->baseDataDirectory.reset(g_value_dup_string(value)); + break; + case PROP_BASE_CACHE_DIRECTORY: + manager->priv->baseCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_LOCAL_STORAGE_DIRECTORY: + manager->priv->localStorageDirectory.reset(g_value_dup_string(value)); + break; + case PROP_DISK_CACHE_DIRECTORY: + manager->priv->diskCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_APPLICATION_CACHE_DIRECTORY: + manager->priv->applicationCacheDirectory.reset(g_value_dup_string(value)); + break; + case PROP_INDEXEDDB_DIRECTORY: + manager->priv->indexedDBDirectory.reset(g_value_dup_string(value)); + break; + case PROP_WEBSQL_DIRECTORY: + manager->priv->webSQLDirectory.reset(g_value_dup_string(value)); + break; + case PROP_IS_EPHEMERAL: + if (g_value_get_boolean(value)) + manager->priv->websiteDataStore = API::WebsiteDataStore::createNonPersistentDataStore(); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec); + } +} + +static void webkitWebsiteDataManagerConstructed(GObject* object) +{ + G_OBJECT_CLASS(webkit_website_data_manager_parent_class)->constructed(object); + + WebKitWebsiteDataManagerPrivate* priv = WEBKIT_WEBSITE_DATA_MANAGER(object)->priv; + if (priv->baseDataDirectory) { + if (!priv->localStorageDirectory) + priv->localStorageDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "localstorage", nullptr)); + if (!priv->indexedDBDirectory) + priv->indexedDBDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", "indexeddb", nullptr)); + if (!priv->webSQLDirectory) + priv->webSQLDirectory.reset(g_build_filename(priv->baseDataDirectory.get(), "databases", nullptr)); + } + + if (priv->baseCacheDirectory) { + if (!priv->diskCacheDirectory) + priv->diskCacheDirectory.reset(g_strdup(priv->baseCacheDirectory.get())); + if (!priv->applicationCacheDirectory) + priv->applicationCacheDirectory.reset(g_build_filename(priv->baseCacheDirectory.get(), "applications", nullptr)); + } +} + +static void webkit_website_data_manager_class_init(WebKitWebsiteDataManagerClass* findClass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass); + + gObjectClass->get_property = webkitWebsiteDataManagerGetProperty; + gObjectClass->set_property = webkitWebsiteDataManagerSetProperty; + gObjectClass->constructed = webkitWebsiteDataManagerConstructed; + + /** + * WebKitWebsiteDataManager:base-data-directory: + * + * The base directory for Website data. This is used as a base directory + * for any Website data when no specific data directory has been provided. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_BASE_DATA_DIRECTORY, + g_param_spec_string( + "base-data-directory", + _("Base Data Directory"), + _("The base directory for Website data"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:base-cache-directory: + * + * The base directory for Website cache. This is used as a base directory + * for any Website cache when no specific cache directory has been provided. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_BASE_CACHE_DIRECTORY, + g_param_spec_string( + "base-cache-directory", + _("Base Cache Directory"), + _("The base directory for Website cache"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:local-storage-directory: + * + * The directory where local storage data will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_LOCAL_STORAGE_DIRECTORY, + g_param_spec_string( + "local-storage-directory", + _("Local Storage Directory"), + _("The directory where local storage data will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:disk-cache-directory: + * + * The directory where HTTP disk cache will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_DISK_CACHE_DIRECTORY, + g_param_spec_string( + "disk-cache-directory", + _("Disk Cache Directory"), + _("The directory where HTTP disk cache will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:offline-application-cache-directory: + * + * The directory where offline web application cache will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_APPLICATION_CACHE_DIRECTORY, + g_param_spec_string( + "offline-application-cache-directory", + _("Offline Web Application Cache Directory"), + _("The directory where offline web application cache will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:indexeddb-directory: + * + * The directory where IndexedDB databases will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_INDEXEDDB_DIRECTORY, + g_param_spec_string( + "indexeddb-directory", + _("IndexedDB Directory"), + _("The directory where IndexedDB databases will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:websql-directory: + * + * The directory where WebSQL databases will be stored. + * + * Since: 2.10 + */ + g_object_class_install_property( + gObjectClass, + PROP_WEBSQL_DIRECTORY, + g_param_spec_string( + "websql-directory", + _("WebSQL Directory"), + _("The directory where WebSQL databases will be stored"), + nullptr, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitWebsiteDataManager:is-ephemeral: + * + * Whether the #WebKitWebsiteDataManager is ephemeral. An ephemeral #WebKitWebsiteDataManager + * handles all websites data as non-persistent, and nothing will be written to the client + * storage. Note that if you create an ephemeral #WebKitWebsiteDataManager all other construction + * parameters to configure data directories will be ignored. + * + * Since: 2.16 + */ + g_object_class_install_property( + gObjectClass, + PROP_IS_EPHEMERAL, + g_param_spec_boolean( + "is-ephemeral", + "Is Ephemeral", + _("Whether the WebKitWebsiteDataManager is ephemeral"), + FALSE, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); +} + +WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(WebsiteDataStore::Configuration&& configuration) +{ + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, nullptr)); + manager->priv->websiteDataStore = API::WebsiteDataStore::create(WTFMove(configuration)); + + return manager; +} + +API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager* manager) +{ + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (!priv->websiteDataStore) { + WebsiteDataStore::Configuration configuration; + configuration.localStorageDirectory = !priv->localStorageDirectory ? + API::WebsiteDataStore::defaultLocalStorageDirectory() : WebCore::stringFromFileSystemRepresentation(priv->localStorageDirectory.get()); + configuration.networkCacheDirectory = !priv->diskCacheDirectory ? + API::WebsiteDataStore::defaultNetworkCacheDirectory() : WebCore::pathByAppendingComponent(WebCore::stringFromFileSystemRepresentation(priv->diskCacheDirectory.get()), networkCacheSubdirectory); + configuration.applicationCacheDirectory = !priv->applicationCacheDirectory ? + API::WebsiteDataStore::defaultApplicationCacheDirectory() : WebCore::stringFromFileSystemRepresentation(priv->applicationCacheDirectory.get()); + configuration.webSQLDatabaseDirectory = !priv->webSQLDirectory ? + API::WebsiteDataStore::defaultWebSQLDatabaseDirectory() : WebCore::stringFromFileSystemRepresentation(priv->webSQLDirectory.get()); + configuration.mediaKeysStorageDirectory = API::WebsiteDataStore::defaultMediaKeysStorageDirectory(); + priv->websiteDataStore = API::WebsiteDataStore::create(WTFMove(configuration)); + } + + return *priv->websiteDataStore; +} + +void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool) +{ + ASSERT(!manager->priv->processPools.contains(&processPool)); + manager->priv->processPools.append(&processPool); +} + +void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager* manager, WebProcessPool& processPool) +{ + ASSERT(manager->priv->processPools.contains(&processPool)); + manager->priv->processPools.removeFirst(&processPool); +} + +const Vector<WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager* manager) +{ + return manager->priv->processPools; +} + +/** + * webkit_website_data_manager_new: + * @first_option_name: name of the first option to set + * @...: value of first option, followed by more options, %NULL-terminated + * + * Creates a new #WebKitWebsiteDataManager with the given options. It must + * be passed as construction parameter of a #WebKitWebContext. + * + * Returns: (transfer full): the newly created #WebKitWebsiteDataManager + * + * Since: 2.10 + */ +WebKitWebsiteDataManager* webkit_website_data_manager_new(const gchar* firstOptionName, ...) +{ + va_list args; + va_start(args, firstOptionName); + WebKitWebsiteDataManager* manager = WEBKIT_WEBSITE_DATA_MANAGER(g_object_new_valist(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, firstOptionName, args)); + va_end(args); + + return manager; +} + +/** + * webkit_website_data_manager_new_ephemeral: + * + * Creates an ephemeral #WebKitWebsiteDataManager. See #WebKitWebsiteDataManager:is-ephemeral for more details. + * + * Returns: (transfer full): a new ephemeral #WebKitWebsiteDataManager. + * + * Since: 2.16 + */ +WebKitWebsiteDataManager* webkit_website_data_manager_new_ephemeral() +{ + return WEBKIT_WEBSITE_DATA_MANAGER(g_object_new(WEBKIT_TYPE_WEBSITE_DATA_MANAGER, "is-ephemeral", TRUE, nullptr)); +} + +/** + * webkit_website_data_manager_is_ephemeral: + * @manager: a #WebKitWebsiteDataManager + * + * Get whether a #WebKitWebsiteDataManager is ephemeral. See #WebKitWebsiteDataManager::is-ephemerla for more details. + * + * Returns: %TRUE if @manager is epheral or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_is_ephemeral(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + + return manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent(); +} + +/** + * webkit_website_data_manager_get_base_data_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:base-data-directory property. + * + * Returns: (allow-none): the base directory for Website data, or %NULL if + * #WebKitWebsiteDataManager:base-data-directory was not provided or @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_base_data_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent()) + return nullptr; + + return manager->priv->baseDataDirectory.get(); +} + +/** + * webkit_website_data_manager_get_base_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:base-cache-directory property. + * + * Returns: (allow-none): the base directory for Website cache, or %NULL if + * #WebKitWebsiteDataManager:base-cache-directory was not provided or @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_base_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (manager->priv->websiteDataStore && !manager->priv->websiteDataStore->isPersistent()) + return nullptr; + + return manager->priv->baseCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_local_storage_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:local-storage-directory property. + * + * Returns: (allow-none): the directory where local storage data is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_local_storage_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->localStorageDirectory) + priv->localStorageDirectory.reset(g_strdup(API::WebsiteDataStore::defaultLocalStorageDirectory().utf8().data())); + return priv->localStorageDirectory.get(); +} + +/** + * webkit_website_data_manager_get_disk_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:disk-cache-directory property. + * + * Returns: (allow-none): the directory where HTTP disk cache is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_disk_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->diskCacheDirectory) { + // The default directory already has the subdirectory. + priv->diskCacheDirectory.reset(g_strdup(WebCore::directoryName(API::WebsiteDataStore::defaultNetworkCacheDirectory()).utf8().data())); + } + return priv->diskCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_offline_application_cache_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:offline-application-cache-directory property. + * + * Returns: (allow-none): the directory where offline web application cache is stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_offline_application_cache_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->applicationCacheDirectory) + priv->applicationCacheDirectory.reset(g_strdup(API::WebsiteDataStore::defaultApplicationCacheDirectory().utf8().data())); + return priv->applicationCacheDirectory.get(); +} + +/** + * webkit_website_data_manager_get_indexeddb_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:indexeddb-directory property. + * + * Returns: (allow-none): the directory where IndexedDB databases are stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_indexeddb_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->indexedDBDirectory) + priv->indexedDBDirectory.reset(g_strdup(API::WebsiteDataStore::defaultIndexedDBDatabaseDirectory().utf8().data())); + return priv->indexedDBDirectory.get(); +} + +/** + * webkit_website_data_manager_get_websql_directory: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitWebsiteDataManager:websql-directory property. + * + * Returns: (allow-none): the directory where WebSQL databases are stored or %NULL if @manager is ephemeral. + * + * Since: 2.10 + */ +const gchar* webkit_website_data_manager_get_websql_directory(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + WebKitWebsiteDataManagerPrivate* priv = manager->priv; + if (priv->websiteDataStore && !priv->websiteDataStore->isPersistent()) + return nullptr; + + if (!priv->webSQLDirectory) + priv->webSQLDirectory.reset(g_strdup(API::WebsiteDataStore::defaultWebSQLDatabaseDirectory().utf8().data())); + return priv->webSQLDirectory.get(); +} + +/** + * webkit_website_data_manager_get_cookie_manager: + * @manager: a #WebKitWebsiteDataManager + * + * Get the #WebKitCookieManager of @manager. + * + * Returns: (transfer none): a #WebKitCookieManager + * + * Since: 2.16 + */ +WebKitCookieManager* webkit_website_data_manager_get_cookie_manager(WebKitWebsiteDataManager* manager) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + + if (!manager->priv->cookieManager) + manager->priv->cookieManager = adoptGRef(webkitCookieManagerCreate(manager)); + + return manager->priv->cookieManager.get(); +} + +static OptionSet<WebsiteDataType> toWebsiteDataTypes(WebKitWebsiteDataTypes types) +{ + OptionSet<WebsiteDataType> returnValue; + if (types & WEBKIT_WEBSITE_DATA_MEMORY_CACHE) + returnValue |= WebsiteDataType::MemoryCache; + if (types & WEBKIT_WEBSITE_DATA_DISK_CACHE) + returnValue |= WebsiteDataType::DiskCache; + if (types & WEBKIT_WEBSITE_DATA_OFFLINE_APPLICATION_CACHE) + returnValue |= WebsiteDataType::OfflineWebApplicationCache; + if (types & WEBKIT_WEBSITE_DATA_SESSION_STORAGE) + returnValue |= WebsiteDataType::SessionStorage; + if (types & WEBKIT_WEBSITE_DATA_LOCAL_STORAGE) + returnValue |= WebsiteDataType::LocalStorage; + if (types & WEBKIT_WEBSITE_DATA_WEBSQL_DATABASES) + returnValue |= WebsiteDataType::WebSQLDatabases; + if (types & WEBKIT_WEBSITE_DATA_INDEXEDDB_DATABASES) + returnValue |= WebsiteDataType::IndexedDBDatabases; +#if ENABLE(NETSCAPE_PLUGIN_API) + if (types & WEBKIT_WEBSITE_DATA_PLUGIN_DATA) + returnValue |= WebsiteDataType::PlugInData; +#endif + if (types & WEBKIT_WEBSITE_DATA_COOKIES) + returnValue |= WebsiteDataType::Cookies; + return returnValue; +} + +/** + * webkit_website_data_manager_fetch: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously get the list of #WebKitWebsiteData for the given @types. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_fetch_finish() to get the result of the operation. + * + * Since: 2.16 + */ +void webkit_website_data_manager_fetch(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + manager->priv->websiteDataStore->websiteDataStore().fetchData(toWebsiteDataTypes(types), WebsiteDataFetchOption::ComputeSizes, [task = WTFMove(task)] (Vector<WebsiteDataRecord> records) { + GList* dataList = nullptr; + while (!records.isEmpty()) { + if (auto* data = webkitWebsiteDataCreate(records.takeLast())) + dataList = g_list_prepend(dataList, data); + } + + g_task_return_pointer(task.get(), dataList, [](gpointer data) { + g_list_free_full(static_cast<GList*>(data), reinterpret_cast<GDestroyNotify>(webkit_website_data_unref)); + }); + }); +} + +/** + * webkit_website_data_manager_fetch_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_fetch(). + * + * Returns: (element-type WebKitWebsiteData) (transfer full): a #GList of #WebKitWebsiteData. You must free the #GList with + * g_list_free() and unref the #WebKitWebsiteData<!-- -->s with webkit_website_data_unref() when you're done with them. + * + * Since: 2.16 + */ +GList* webkit_website_data_manager_fetch_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), nullptr); + g_return_val_if_fail(g_task_is_valid(result, manager), nullptr); + + return static_cast<GList*>(g_task_propagate_pointer(G_TASK(result), error)); +} + +/** + * webkit_website_data_manager_remove: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @website_data: (element-type WebKitWebsiteData): a #GList of #WebKitWebsiteData + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously removes the website data of the for the given @types for websites in the given @website_data list. + * Use webkit_website_data_manager_clear() if you want to remove the website data for all sites. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_remove_finish() to get the result of the operation. + * + * Since: 2.16 + */ +void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GList* websiteData, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + g_return_if_fail(websiteData); + + Vector<WebsiteDataRecord> records; + for (GList* item = websiteData; item; item = g_list_next(item)) { + WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(item->data); + + if (webkit_website_data_get_types(data) & types) + records.append(webkitWebsiteDataGetRecord(data)); + } + + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + if (records.isEmpty()) { + g_task_return_boolean(task.get(), TRUE); + return; + } + + manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), records, [task = WTFMove(task)] { + g_task_return_boolean(task.get(), TRUE); + }); +} + +/** + * webkit_website_data_manager_remove_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_remove(). + * + * Returns: %TRUE if website data resources were succesfully removed, or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_remove_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + g_return_val_if_fail(g_task_is_valid(result, manager), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/** + * webkit_website_data_manager_clear: + * @manager: a #WebKitWebsiteDataManager + * @types: #WebKitWebsiteDataTypes + * @timespan: a #GTimeSpan + * @cancellable: (allow-none): a #GCancellable or %NULL to ignore + * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: (closure): the data to pass to callback function + * + * Asynchronously clear the website data of the given @types modified in the past @timespan. + * If @timespan is 0, all website data will be removed. + * + * When the operation is finished, @callback will be called. You can then call + * webkit_website_data_manager_clear_finish() to get the result of the operation. + * + * Due to implementation limitations, this function does not currently delete + * any stored cookies if @timespan is nonzero. This behavior may change in the + * future. + * + * Since: 2.16 + */ +void webkit_website_data_manager_clear(WebKitWebsiteDataManager* manager, WebKitWebsiteDataTypes types, GTimeSpan timeSpan, GCancellable* cancellable, GAsyncReadyCallback callback, gpointer userData) +{ + g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager)); + + std::chrono::system_clock::time_point timePoint = timeSpan ? std::chrono::system_clock::now() - std::chrono::microseconds(timeSpan) : std::chrono::system_clock::from_time_t(0); + GRefPtr<GTask> task = adoptGRef(g_task_new(manager, cancellable, callback, userData)); + manager->priv->websiteDataStore->websiteDataStore().removeData(toWebsiteDataTypes(types), timePoint, [task = WTFMove(task)] { + g_task_return_boolean(task.get(), TRUE); + }); +} + +/** + * webkit_website_data_manager_clear_finish: + * @manager: a #WebKitWebsiteDataManager + * @result: a #GAsyncResult + * @error: return location for error or %NULL to ignore + * + * Finish an asynchronous operation started with webkit_website_data_manager_clear() + * + * Returns: %TRUE if website data was succesfully cleared, or %FALSE otherwise. + * + * Since: 2.16 + */ +gboolean webkit_website_data_manager_clear_finish(WebKitWebsiteDataManager* manager, GAsyncResult* result, GError** error) +{ + g_return_val_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager), FALSE); + g_return_val_if_fail(g_task_is_valid(result, manager), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h new file mode 100644 index 000000000..cc62ad3d4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManager.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2,1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitWebsiteDataManager_h +#define WebKitWebsiteDataManager_h + +#include <gio/gio.h> +#include <webkit2/WebKitCookieManager.h> +#include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitWebsiteData.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_WEBSITE_DATA_MANAGER (webkit_website_data_manager_get_type()) +#define WEBKIT_WEBSITE_DATA_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManager)) +#define WEBKIT_IS_WEBSITE_DATA_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER)) +#define WEBKIT_WEBSITE_DATA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManagerClass)) +#define WEBKIT_IS_WEBSITE_DATA_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEBSITE_DATA_MANAGER)) +#define WEBKIT_WEBSITE_DATA_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEBSITE_DATA_MANAGER, WebKitWebsiteDataManagerClass)) + +typedef struct _WebKitWebsiteDataManager WebKitWebsiteDataManager; +typedef struct _WebKitWebsiteDataManagerClass WebKitWebsiteDataManagerClass; +typedef struct _WebKitWebsiteDataManagerPrivate WebKitWebsiteDataManagerPrivate; + +struct _WebKitWebsiteDataManager { + GObject parent; + + WebKitWebsiteDataManagerPrivate *priv; +}; + +struct _WebKitWebsiteDataManagerClass { + GObjectClass parent_class; + + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_website_data_manager_get_type (void); + +WEBKIT_API WebKitWebsiteDataManager * +webkit_website_data_manager_new (const gchar *first_option_name, + ...); +WEBKIT_API WebKitWebsiteDataManager * +webkit_website_data_manager_new_ephemeral (void); + +WEBKIT_API gboolean +webkit_website_data_manager_is_ephemeral (WebKitWebsiteDataManager* manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_base_data_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_base_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_local_storage_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_disk_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_offline_application_cache_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_indexeddb_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API const gchar * +webkit_website_data_manager_get_websql_directory (WebKitWebsiteDataManager *manager); + +WEBKIT_API WebKitCookieManager * +webkit_website_data_manager_get_cookie_manager (WebKitWebsiteDataManager *manager); + +WEBKIT_API void +webkit_website_data_manager_fetch (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +WEBKIT_API GList * +webkit_website_data_manager_fetch_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); +WEBKIT_API void +webkit_website_data_manager_remove (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GList *website_data, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +WEBKIT_API gboolean +webkit_website_data_manager_remove_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); + +WEBKIT_API void +webkit_website_data_manager_clear (WebKitWebsiteDataManager *manager, + WebKitWebsiteDataTypes types, + GTimeSpan timespan, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +WEBKIT_API gboolean +webkit_website_data_manager_clear_finish (WebKitWebsiteDataManager *manager, + GAsyncResult *result, + GError **error); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h new file mode 100644 index 000000000..46379aaf3 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataManagerPrivate.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "APIWebsiteDataStore.h" +#include "WebKitPrivate.h" +#include "WebProcessPool.h" +#include "WebsiteDataStore.h" + +WebKitWebsiteDataManager* webkitWebsiteDataManagerCreate(WebKit::WebsiteDataStore::Configuration&&); +API::WebsiteDataStore& webkitWebsiteDataManagerGetDataStore(WebKitWebsiteDataManager*); +void webkitWebsiteDataManagerAddProcessPool(WebKitWebsiteDataManager*, WebKit::WebProcessPool&); +void webkitWebsiteDataManagerRemoveProcessPool(WebKitWebsiteDataManager*, WebKit::WebProcessPool&); +const Vector<WebKit::WebProcessPool*>& webkitWebsiteDataManagerGetProcessPools(WebKitWebsiteDataManager*); + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h new file mode 100644 index 000000000..509591fb4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebsiteDataPrivate.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "WebKitPrivate.h" +#include "WebKitWebsiteData.h" +#include "WebsiteDataRecord.h" + +WebKitWebsiteData* webkitWebsiteDataCreate(WebKit::WebsiteDataRecord&&); +const WebKit::WebsiteDataRecord& webkitWebsiteDataGetRecord(WebKitWebsiteData*); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp index a40e6db4d..5e225db78 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowProperties.cpp @@ -20,12 +20,13 @@ #include "config.h" #include "WebKitWindowProperties.h" +#include "APIDictionary.h" #include "APINumber.h" #include "APIURLRequest.h" -#include "ImmutableDictionary.h" #include "WebKitPrivate.h" #include "WebKitWindowPropertiesPrivate.h" #include <WebCore/IntRect.h> +#include <WebCore/WindowFeatures.h> #include <glib/gi18n-lib.h> using namespace WebKit; @@ -374,54 +375,26 @@ void webkitWindowPropertiesSetFullscreen(WebKitWindowProperties* windowPropertie g_object_notify(G_OBJECT(windowProperties), "fullscreen"); } -void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties* windowProperties, ImmutableDictionary* features) +void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties* windowProperties, const WindowFeatures& windowFeatures) { GdkRectangle geometry = windowProperties->priv->geometry; - - API::Double* doubleValue = static_cast<API::Double*>(features->get("x")); - if (doubleValue) - geometry.x = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("y")); - if (doubleValue) - geometry.y = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("width")); - if (doubleValue) - geometry.width = doubleValue->value(); - - doubleValue = static_cast<API::Double*>(features->get("height")); - if (doubleValue) - geometry.height = doubleValue->value(); + if (windowFeatures.x) + geometry.x = *windowFeatures.x; + if (windowFeatures.y) + geometry.y = *windowFeatures.y; + if (windowFeatures.width) + geometry.width = *windowFeatures.width; + if (windowFeatures.height) + geometry.height = *windowFeatures.height; webkitWindowPropertiesSetGeometry(windowProperties, &geometry); - API::Boolean* booleanValue = static_cast<API::Boolean*>(features->get("menuBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetMenubarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("statusBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetStatusbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("toolBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetToolbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("locationBarVisible")); - if (booleanValue) - webkitWindowPropertiesSetLocationbarVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("scrollbarsVisible")); - if (booleanValue) - webkitWindowPropertiesSetScrollbarsVisible(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("resizable")); - if (booleanValue) - webkitWindowPropertiesSetResizable(windowProperties, booleanValue->value()); - - booleanValue = static_cast<API::Boolean*>(features->get("fullscreen")); - if (booleanValue) - webkitWindowPropertiesSetFullscreen(windowProperties, booleanValue->value()); + webkitWindowPropertiesSetMenubarVisible(windowProperties, windowFeatures.menuBarVisible); + webkitWindowPropertiesSetStatusbarVisible(windowProperties, windowFeatures.statusBarVisible); + webkitWindowPropertiesSetToolbarVisible(windowProperties, windowFeatures.toolBarVisible); + webkitWindowPropertiesSetLocationbarVisible(windowProperties, windowFeatures.locationBarVisible); + webkitWindowPropertiesSetScrollbarsVisible(windowProperties, windowFeatures.scrollbarsVisible); + webkitWindowPropertiesSetResizable(windowProperties, windowFeatures.resizable); + webkitWindowPropertiesSetFullscreen(windowProperties, windowFeatures.fullscreen); } /** diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h index 8ec17b4ea..05e4b9be0 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWindowPropertiesPrivate.h @@ -31,7 +31,7 @@ #include "WebKitWindowProperties.h" WebKitWindowProperties* webkitWindowPropertiesCreate(); -void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties*, WebKit::ImmutableDictionary* features); +void webkitWindowPropertiesUpdateFromWebWindowFeatures(WebKitWindowProperties*, const WebCore::WindowFeatures&); void webkitWindowPropertiesSetGeometry(WebKitWindowProperties*, GdkRectangle*); void webkitWindowPropertiesSetToolbarVisible(WebKitWindowProperties*, bool toolbarsVisible); void webkitWindowPropertiesSetMenubarVisible(WebKitWindowProperties*, bool menuBarVisible); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp b/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp deleted file mode 100644 index 8b87c1522..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebViewBaseInputMethodFilter.h" - -#include "NativeWebKeyboardEvent.h" -#include "WebKitWebViewBasePrivate.h" -#include "WebPageProxy.h" -#include <WebCore/Color.h> -#include <WebCore/CompositionResults.h> -#include <WebCore/Editor.h> - -using namespace WebCore; - -namespace WebKit { - -void WebViewBaseInputMethodFilter::setWebView(WebKitWebViewBase* webView) -{ - GtkInputMethodFilter::setWidget(GTK_WIDGET(webView)); - - m_webPageProxy = webkitWebViewBaseGetPage(webView); - ASSERT(m_webPageProxy); -} - -bool WebViewBaseInputMethodFilter::canEdit() -{ - return true; -} - -bool WebViewBaseInputMethodFilter::sendSimpleKeyEvent(GdkEventKey* event, WTF::String simpleString, EventFakedForComposition faked) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), - CompositionResults(simpleString), faked)); - return true; -} - -bool WebViewBaseInputMethodFilter::sendKeyEventWithCompositionResults(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), - CompositionResults(CompositionResults::WillSendCompositionResultsSoon), - faked)); - - if (resultsToSend & Composition && !m_confirmedComposition.isNull()) - confirmCompositionText(m_confirmedComposition); - if (resultsToSend & Preedit && !m_preedit.isNull()) - setPreedit(m_preedit, m_cursorOffset); - return true; -} - -void WebViewBaseInputMethodFilter::confirmCompositionText(String text) -{ - ASSERT(m_webPageProxy); - m_webPageProxy->confirmComposition(text, -1, 0); -} - -void WebViewBaseInputMethodFilter::confirmCurrentComposition() -{ - ASSERT(m_webPageProxy); - m_webPageProxy->confirmComposition(String(), -1, 0); -} - -void WebViewBaseInputMethodFilter::cancelCurrentComposition() -{ - ASSERT(m_webPageProxy); - m_webPageProxy->cancelComposition(); -} - -void WebViewBaseInputMethodFilter::setPreedit(String newPreedit, int cursorOffset) -{ - // TODO: We should parse the PangoAttrList that we get from the IM context here. - Vector<CompositionUnderline> underlines; - underlines.append(CompositionUnderline(0, newPreedit.length(), Color(1, 1, 1), false)); - - ASSERT(m_webPageProxy); - m_webPageProxy->setComposition(newPreedit, underlines, - m_cursorOffset, m_cursorOffset, - 0 /* replacement start */, - 0 /* replacement end */); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h b/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h deleted file mode 100644 index 9cde8b12d..000000000 --- a/Source/WebKit2/UIProcess/API/gtk/WebViewBaseInputMethodFilter.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebViewBaseInputMethodFilter_h -#define WebViewBaseInputMethodFilter_h - -#include "GtkInputMethodFilter.h" -#include "WebPageProxy.h" - -typedef struct _WebKitWebViewBase WebKitWebViewBase; - -namespace WebKit { - -class WebViewBaseInputMethodFilter : public WebCore::GtkInputMethodFilter { -public: - void setWebView(WebKitWebViewBase*); - -protected: - virtual bool sendSimpleKeyEvent(GdkEventKey*, WTF::String eventString, EventFakedForComposition); - virtual bool sendKeyEventWithCompositionResults(GdkEventKey*, ResultsToSend, EventFakedForComposition); - virtual bool canEdit(); - virtual void confirmCompositionText(String); - virtual void confirmCurrentComposition(); - virtual void cancelCurrentComposition(); - virtual void setPreedit(String, int cursorOffset); - -private: - WebPageProxy* m_webPageProxy; -}; - -} // namespace WebKit - -#endif // WebViewBaseInputMethodFilter_h diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt index a098a00d8..995497075 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt @@ -16,7 +16,8 @@ WEBKIT_WEB_VIEW_BASE_GET_CLASS webkit_web_view_base_get_type WebKitWebViewBasePrivate WEBKIT_API -WEBKIT_OBSOLETE_API +WEBKIT_DEPRECATED +WEBKIT_DEPRECATED_FOR </SECTION> <SECTION> @@ -26,10 +27,19 @@ WebKitWebContext WebKitCacheModel WebKitProcessModel WebKitTLSErrorsPolicy +WebKitNetworkProxyMode webkit_web_context_get_default +webkit_web_context_new +webkit_web_context_new_ephemeral +webkit_web_context_new_with_website_data_manager +webkit_web_context_is_ephemeral +webkit_web_context_get_website_data_manager webkit_web_context_get_cache_model webkit_web_context_set_cache_model +webkit_web_context_get_web_process_count_limit +webkit_web_context_set_web_process_count_limit webkit_web_context_clear_cache +webkit_web_context_set_network_proxy_settings webkit_web_context_download_uri webkit_web_context_get_cookie_manager webkit_web_context_get_favicon_database @@ -53,6 +63,7 @@ webkit_web_context_set_disk_cache_directory webkit_web_context_allow_tls_certificate_for_host webkit_web_context_get_process_model webkit_web_context_set_process_model +webkit_web_context_initialize_notification_permissions <SUBSECTION URI Scheme> WebKitURISchemeRequestCallback @@ -73,13 +84,62 @@ webkit_web_context_get_type </SECTION> <SECTION> +<FILE>WebKitUserContent</FILE> +<TITLE>WebKitUserContent</TITLE> +WebKitUserStyleSheet +WebKitUserScript +WebKitUserContentInjectedFrames +WebKitUserStyleLevel +WebKitUserScriptInjectionTime +webkit_user_style_sheet_ref +webkit_user_style_sheet_unref +webkit_user_style_sheet_new +webkit_user_script_ref +webkit_user_script_unref +webkit_user_script_new + +<SUBSECTION Standard> +WEBKIT_TYPE_USER_STYLE_SHEET +WEBKIT_TYPE_USER_SCRIPT + +<SUBSECTION Private> +webkit_user_style_sheet_get_type +webkit_user_script_get_type +</SECTION> + +<SECTION> +<FILE>WebKitUserContentManager</FILE> +<TITLE>WebKitUserContentManager</TITLE> +WebKitUserContentManager +webkit_user_content_manager_new +webkit_user_content_manager_add_style_sheet +webkit_user_content_manager_remove_all_style_sheets +webkit_user_content_manager_add_script +webkit_user_content_manager_remove_all_scripts +webkit_user_content_manager_register_script_message_handler +webkit_user_content_manager_unregister_script_message_handler + +<SUBSECTION Standard> +WEBKIT_IS_USER_CONTENT_MANAGER +WEBKIT_IS_USER_CONTENT_MANAGER_CLASS +WEBKIT_TYPE_USER_CONTENT_MANAGER +WEBKIT_USER_CONTENT_MANAGER +WEBKIT_USER_CONTENT_MANAGER_CLASS +WEBKIT_USER_CONTENT_MANAGER_GET_CLASS +WebKitUserContentManagerClass + +<SUBSECTION Private> +WebKitUserContentManagerPrivate +webkit_user_content_manager_get_type +</SECTION> + +<SECTION> <FILE>WebKitWebView</FILE> <TITLE>WebKitWebView</TITLE> WebKitWebView WebKitLoadEvent WebKitPolicyDecisionType WebKitSaveMode -WebKitViewMode WebKitInsecureContentEvent WebKitSnapshotOptions WebKitSnapshotRegion @@ -91,18 +151,25 @@ WEBKIT_EDITING_COMMAND_PASTE WEBKIT_EDITING_COMMAND_SELECT_ALL WEBKIT_EDITING_COMMAND_UNDO WEBKIT_EDITING_COMMAND_REDO +WEBKIT_EDITING_COMMAND_INSERT_IMAGE +WEBKIT_EDITING_COMMAND_CREATE_LINK <SUBSECTION> webkit_web_view_new webkit_web_view_new_with_context webkit_web_view_new_with_related_view -webkit_web_view_new_with_group +webkit_web_view_new_with_settings +webkit_web_view_new_with_user_content_manager +webkit_web_view_is_ephemeral webkit_web_view_get_context -webkit_web_view_get_group +webkit_web_view_get_user_content_manager +webkit_web_view_get_website_data_manager +webkit_web_view_try_close webkit_web_view_load_uri webkit_web_view_load_html webkit_web_view_load_alternate_html webkit_web_view_load_plain_text +webkit_web_view_load_bytes webkit_web_view_load_request webkit_web_view_can_go_back webkit_web_view_go_back @@ -114,6 +181,7 @@ webkit_web_view_reload webkit_web_view_reload_bypass_cache webkit_web_view_stop_loading webkit_web_view_is_loading +webkit_web_view_is_playing_audio webkit_web_view_get_estimated_load_progress webkit_web_view_get_custom_charset webkit_web_view_set_custom_charset @@ -129,6 +197,7 @@ webkit_web_view_get_zoom_level webkit_web_view_can_execute_editing_command webkit_web_view_can_execute_editing_command_finish webkit_web_view_execute_editing_command +webkit_web_view_execute_editing_command_with_argument webkit_web_view_get_find_controller webkit_web_view_get_inspector webkit_web_view_get_javascript_global_context @@ -142,11 +211,16 @@ webkit_web_view_save_finish webkit_web_view_save_to_file webkit_web_view_save_to_file_finish webkit_web_view_download_uri -webkit_web_view_set_view_mode -webkit_web_view_get_view_mode webkit_web_view_get_tls_info webkit_web_view_get_snapshot webkit_web_view_get_snapshot_finish +webkit_web_view_set_background_color +webkit_web_view_get_background_color +webkit_web_view_set_editable +webkit_web_view_is_editable +webkit_web_view_get_editor_state +webkit_web_view_get_session_state +webkit_web_view_restore_session_state <SUBSECTION WebKitJavascriptResult> WebKitJavascriptResult @@ -165,6 +239,13 @@ webkit_script_dialog_prompt_get_default_text webkit_script_dialog_prompt_set_text webkit_web_view_get_main_resource +<SUBSECTION WebKitWebViewSessionState> +WebKitWebViewSessionState +webkit_web_view_session_state_new +webkit_web_view_session_state_ref +webkit_web_view_session_state_unref +webkit_web_view_session_state_serialize + <SUBSECTION Standard> WebKitWebViewClass WEBKIT_WEB_VIEW @@ -175,11 +256,13 @@ WEBKIT_IS_WEB_VIEW_CLASS WEBKIT_WEB_VIEW_GET_CLASS WEBKIT_TYPE_JAVASCRIPT_RESULT WEBKIT_TYPE_SCRIPT_DIALOG +WEBKIT_TYPE_WEB_VIEW_SESSION_STATE <SUBSECTION Private> webkit_web_view_get_type webkit_javascript_result_get_type webkit_script_dialog_get_type +webkit_web_view_session_state_get_type WebKitWebViewPrivate </SECTION> @@ -276,6 +359,7 @@ webkit_back_forward_list_item_get_type <SECTION> <FILE>WebKitSettings</FILE> WebKitSettings +WebKitHardwareAccelerationPolicy webkit_settings_new webkit_settings_new_with_settings webkit_settings_get_auto_load_images @@ -375,6 +459,12 @@ webkit_settings_get_enable_spatial_navigation webkit_settings_set_enable_spatial_navigation webkit_settings_get_enable_mediasource webkit_settings_set_enable_mediasource +webkit_settings_get_allow_file_access_from_file_urls +webkit_settings_set_allow_file_access_from_file_urls +webkit_settings_get_allow_universal_access_from_file_urls +webkit_settings_set_allow_universal_access_from_file_urls +webkit_settings_get_hardware_acceleration_policy +webkit_settings_set_hardware_acceleration_policy <SUBSECTION Standard> WebKitSettingsClass @@ -396,6 +486,7 @@ WebKitURIRequest webkit_uri_request_new webkit_uri_request_get_uri webkit_uri_request_set_uri +webkit_uri_request_get_http_method webkit_uri_request_get_http_headers <SUBSECTION Standard> @@ -420,6 +511,7 @@ webkit_uri_response_get_status_code webkit_uri_response_get_content_length webkit_uri_response_get_mime_type webkit_uri_response_get_suggested_filename +webkit_uri_response_get_http_headers <SUBSECTION Standard> WebKitURIResponseClass @@ -473,6 +565,8 @@ webkit_download_get_estimated_progress webkit_download_get_elapsed_time webkit_download_get_received_data_length webkit_download_get_web_view +webkit_download_get_allow_overwrite +webkit_download_set_allow_overwrite <SUBSECTION Standard> WebKitDownloadClass @@ -524,6 +618,105 @@ webkit_geolocation_permission_request_get_type </SECTION> <SECTION> +<FILE>WebKitInstallMissingMediaPluginsPermissionRequest</FILE> +WebKitInstallMissingMediaPluginsPermissionRequest +webkit_install_missing_media_plugins_permission_request_get_description + +<SUBSECTION Standard> +WebKitInstallMissingMediaPluginsPermissionRequestClass +WEBKIT_TYPE_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS +WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_CLASS +WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitInstallMissingMediaPluginsPermissionRequestPrivate +webkit_install_missing_media_plugins_permission_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNavigationAction</FILE> +WebKitNavigationAction +webkit_navigation_action_copy +webkit_navigation_action_free +webkit_navigation_action_get_navigation_type +webkit_navigation_action_get_mouse_button +webkit_navigation_action_get_modifiers +webkit_navigation_action_get_request +webkit_navigation_action_is_user_gesture + +<SUBSECTION Standard> +WEBKIT_TYPE_NAVIGATION_ACTION + +<SUBSECTION Private> +webkit_navigation_action_get_type +</SECTION> + +<SECTION> +<FILE>WebKitUserMediaPermissionRequest</FILE> +WebKitUserMediaPermissionRequest +webkit_user_media_permission_is_for_audio_device +webkit_user_media_permission_is_for_video_device + +<SUBSECTION Standard> +WebKitUserMediaPermissionRequestClass +WEBKIT_TYPE_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST +WEBKIT_USER_MEDIA_PERMISSION_REQUEST_CLASS +WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST_CLASS +WEBKIT_USER_MEDIA_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitUserMediaPermissionRequestPrivate +webkit_user_media_permission_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNotification</FILE> +WebKitNotification +webkit_notification_get_id +webkit_notification_get_title +webkit_notification_get_body +webkit_notification_get_tag +webkit_notification_close +webkit_notification_clicked + +<SUBSECTION Standard> +WebKitNotificationClass +WEBKIT_TYPE_NOTIFICATION +WEBKIT_IS_NOTIFICATION +WEBKIT_NOTIFICATION +WEBKIT_NOTIFICATION_CLASS +WEBKIT_IS_NOTIFICATION_CLASS +WEBKIT_NOTIFICATION_GET_CLASS + +<SUBSECTION Private> +WebKitNotificationPrivate +webkit_notification_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNotificationPermissionRequest</FILE> +WebKitNotificationPermissionRequest + +<SUBSECTION Standard> +WebKitNotificationPermissionRequestClass +WEBKIT_TYPE_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST +WEBKIT_NOTIFICATION_PERMISSION_REQUEST_CLASS +WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST_CLASS +WEBKIT_NOTIFICATION_PERMISSION_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitNotificationPermissionRequestPrivate +webkit_notification_permission_request_get_type +</SECTION> + +<SECTION> <FILE>WebKitPolicyDecision</FILE> WebKitPolicyDecision webkit_policy_decision_download @@ -548,6 +741,7 @@ webkit_policy_decision_get_type <FILE>WebKitNavigationPolicyDecision</FILE> WebKitNavigationPolicyDecision WebKitNavigationType +webkit_navigation_policy_decision_get_navigation_action webkit_navigation_policy_decision_get_frame_name webkit_navigation_policy_decision_get_modifiers webkit_navigation_policy_decision_get_mouse_button @@ -598,6 +792,7 @@ webkit_hit_test_result_context_is_link webkit_hit_test_result_context_is_image webkit_hit_test_result_context_is_media webkit_hit_test_result_context_is_editable +webkit_hit_test_result_context_is_selection webkit_hit_test_result_get_link_uri webkit_hit_test_result_get_link_title webkit_hit_test_result_get_link_label @@ -620,6 +815,26 @@ webkit_hit_test_result_get_type </SECTION> <SECTION> +<FILE>WebKitEditorState</FILE> +WebKitEditorState +WebKitEditorTypingAttributes +webkit_editor_state_get_typing_attributes + +<SUBSECTION Standard> +WebKitEditorStateClass +WEBKIT_TYPE_EDITOR_STATE +WEBKIT_EDITOR_STATE +WEBKIT_IS_EDITOR_STATE +WEBKIT_EDITOR_STATE_CLASS +WEBKIT_IS_EDITOR_STATE_CLASS +WEBKIT_EDITOR_STATE_GET_CLASS + +<SUBSECTION Private> +WebKitEditorStatePrivate +webkit_editor_state_get_type +</SECTION> + +<SECTION> <FILE>WebKitPrintOperation</FILE> WebKitPrintOperation WebKitPrintOperationResponse @@ -834,6 +1049,7 @@ WebKitPluginPrivate WebKitWebInspector webkit_web_inspector_get_web_view webkit_web_inspector_get_inspected_uri +webkit_web_inspector_get_can_attach webkit_web_inspector_is_attached webkit_web_inspector_attach webkit_web_inspector_detach @@ -908,6 +1124,8 @@ webkit_context_menu_last webkit_context_menu_get_item_at_position webkit_context_menu_remove webkit_context_menu_remove_all +webkit_context_menu_set_user_data +webkit_context_menu_get_user_data <SUBSECTION Standard> WebKitContextMenuClass @@ -1003,28 +1221,90 @@ webkit_security_manager_get_type </SECTION> <SECTION> -<FILE>WebKitWebViewGroup</FILE> -WebKitWebViewGroup -WebKitInjectedContentFrames -webkit_web_view_group_new -webkit_web_view_group_get_name -webkit_web_view_group_get_settings -webkit_web_view_group_set_settings -webkit_web_view_group_add_user_style_sheet -webkit_web_view_group_remove_all_user_style_sheets +<FILE>WebKitSecurityOrigin</FILE> +WebKitSecurityOrigin +webkit_security_origin_new +webkit_security_origin_new_for_uri +webkit_security_origin_ref +webkit_security_origin_unref +webkit_security_origin_get_protocol +webkit_security_origin_get_host +webkit_security_origin_get_port +webkit_security_origin_is_opaque +webkit_security_origin_to_string + +<SUBSECTION Standard> +WEBKIT_TYPE_SECURITY_ORIGIN + +<SUBSECTION Private> +webkit_security_origin_get_type +</SECTION> + +<SECTION> +<FILE>WebKitWebsiteDataManager</FILE> +WebKitWebsiteDataManager +webkit_website_data_manager_new +webkit_website_data_manager_new_ephemeral +webkit_website_data_manager_is_ephemeral +webkit_website_data_manager_get_base_data_directory +webkit_website_data_manager_get_base_cache_directory +webkit_website_data_manager_get_local_storage_directory +webkit_website_data_manager_get_disk_cache_directory +webkit_website_data_manager_get_offline_application_cache_directory +webkit_website_data_manager_get_indexeddb_directory +webkit_website_data_manager_get_websql_directory +webkit_website_data_manager_get_cookie_manager +webkit_website_data_manager_fetch +webkit_website_data_manager_fetch_finish +webkit_website_data_manager_remove +webkit_website_data_manager_remove_finish +webkit_website_data_manager_clear +webkit_website_data_manager_clear_finish <SUBSECTION Standard> -WebKitWebViewGroupClass -WEBKIT_TYPE_WEB_VIEW_GROUP -WEBKIT_WEB_VIEW_GROUP -WEBKIT_IS_WEB_VIEW_GROUP -WEBKIT_WEB_VIEW_GROUP_CLASS -WEBKIT_IS_WEB_VIEW_GROUP_CLASS -WEBKIT_WEB_VIEW_GROUP_GET_CLASS +WebKitWebsiteDataManagerClass +WEBKIT_TYPE_WEBSITE_DATA_MANAGER +WEBKIT_WEBSITE_DATA_MANAGER +WEBKIT_IS_WEBSITE_DATA_MANAGER +WEBKIT_WEBSITE_DATA_MANAGER_CLASS +WEBKIT_IS_WEBSITE_DATA_MANAGER_CLASS +WEBKIT_WEBSITE_DATA_MANAGER_GET_CLASS <SUBSECTION Private> -WebKitWebViewGroupPrivate -webkit_web_view_group_get_type +WebKitWebsiteDataManagerPrivate +webkit_website_data_manager_get_type +</SECTION> + +<SECTION> +<FILE>WebKitWebsiteData</FILE> +WebKitWebsiteData +WebKitWebsiteDataTypes +webkit_website_data_ref +webkit_website_data_unref +webkit_website_data_get_name +webkit_website_data_get_types +webkit_website_data_get_size + +<SUBSECTION Standard> +WEBKIT_TYPE_WEBSITE_DATA + +<SUBSECTION Private> +webkit_website_data_get_type +</SECTION> + +<SECTION> +<FILE>WebKitNetworkProxySettings</FILE> +WebKitNetworkProxySettings +webkit_network_proxy_settings_new +webkit_network_proxy_settings_copy +webkit_network_proxy_settings_free +webkit_network_proxy_settings_add_proxy_for_scheme + +<SUBSECTION Private> +webkit_network_proxy_settings_get_type + +<SUBSECTION Standard> +WEBKIT_TYPE_NETWORK_NETWORK_PROXY_SETTINGS </SECTION> <SECTION> @@ -1055,6 +1335,7 @@ webkit_web_page_get_dom_document webkit_web_page_get_id webkit_web_page_get_uri webkit_web_page_get_main_frame +webkit_web_page_get_editor <SUBSECTION Standard> WebKitWebPageClass @@ -1071,6 +1352,25 @@ webkit_web_page_get_type </SECTION> <SECTION> +<FILE>WebKitWebEditor</FILE> +WebKitWebEditor +webkit_web_editor_get_page + +<SUBSECTION Standard> +WebKitWebEditorClass +WEBKIT_TYPE_WEB_EDITOR +WEBKIT_WEB_EDITOR +WEBKIT_IS_WEB_EDITOR +WEBKIT_WEB_EDITOR_CLASS +WEBKIT_IS_WEB_EDITOR_CLASS +WEBKIT_WEB_EDITOR_GET_CLASS + +<SUBSECTION Private> +WebKitWebEditorPrivate +webkit_web_editor_get_type +</SECTION> + +<SECTION> <FILE>WebKitFrame</FILE> WebKitFrame webkit_frame_is_main_frame @@ -1113,16 +1413,84 @@ webkit_script_world_get_type </SECTION> <SECTION> -<FILE>WebKitCertificateInfo</FILE> -WebKitCertificateInfo -webkit_certificate_info_copy -webkit_certificate_info_free -webkit_certificate_info_get_tls_certificate -webkit_certificate_info_get_tls_errors +<FILE>WebKitWebHitTestResult</FILE> +WebKitWebHitTestResult +webkit_web_hit_test_result_get_node + +<SUBSECTION Standard> +WebKitWebHitTestResultClass +WEBKIT_TYPE_WEB_HIT_TEST_RESULT +WEBKIT_WEB_HIT_TEST_RESULT +WEBKIT_IS_WEB_HIT_TEST_RESULT +WEBKIT_WEB_HIT_TEST_RESULT_CLASS +WEBKIT_IS_WEB_HIT_TEST_RESULT_CLASS +WEBKIT_WEB_HIT_TEST_RESULT_GET_CLASS + +<SUBSECTION Private> +WebKitWebHitTestResultPrivate +webkit_web_hit_test_result_get_type +</SECTION> + +<SECTION> +<FILE>WebKitConsoleMessage</FILE> +WebKitConsoleMessage +WebKitConsoleMessageSource +WebKitConsoleMessageLevel +webkit_console_message_copy +webkit_console_message_free +webkit_console_message_get_source +webkit_console_message_get_level +webkit_console_message_get_text +webkit_console_message_get_line +webkit_console_message_get_source_id + +<SUBSECTION Standard> +WEBKIT_TYPE_CONSOLE_MESSAGE + +<SUBSECTION Private> +webkit_console_message_get_type +</SECTION> + +<SECTION> +<FILE>WebKitColorChooserRequest</FILE> +WebKitColorChooserRequest +webkit_color_chooser_request_get_rgba +webkit_color_chooser_request_set_rgba +webkit_color_chooser_request_get_element_rectangle +webkit_color_chooser_request_finish +webkit_color_chooser_request_cancel + +<SUBSECTION Standard> +WebKitColorChooserRequestClass +WEBKIT_TYPE_COLOR_CHOOSER_REQUEST +WEBKIT_COLOR_CHOOSER_REQUEST +WEBKIT_IS_COLOR_CHOOSER_REQUEST +WEBKIT_COLOR_CHOOSER_REQUEST_CLASS +WEBKIT_IS_COLOR_CHOOSER_REQUEST_CLASS +WEBKIT_COLOR_CHOOSER_REQUEST_GET_CLASS + +<SUBSECTION Private> +WebKitColorChooserRequestPrivate +webkit_color_chooser_request_get_type +</SECTION> + +<SECTION> +<FILE>WebKitPrintCustomWidget</FILE> +WebKitPrintCustomWidget +webkit_print_custom_widget_new +webkit_print_custom_widget_get_widget +webkit_print_custom_widget_get_title <SUBSECTION Standard> -WEBKIT_TYPE_CERTIFICATE_INFO +WebKitPrintCustomWidgetClass +WEBKIT_TYPE_PRINT_CUSTOM_WIDGET +WEBKIT_PRINT_CUSTOM_WIDGET +WEBKIT_IS_PRINT_CUSTOM_WIDGET +WEBKIT_PRINT_CUSTOM_WIDGET_CLASS +WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS +WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS <SUBSECTION Private> -webkit_certificate_info_get_type +WebKitPrintCustomWidgetPrivate +webkit_print_custom_widget_get_type </SECTION> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types index 4b583bad9..403051ae7 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types @@ -21,10 +21,17 @@ webkit_web_inspector_get_type webkit_uri_scheme_request_get_type webkit_context_menu_get_type webkit_context_menu_item_get_type -webkit_web_view_group_get_type webkit_web_extension_get_type webkit_web_page_get_type webkit_authentication_request_get_type webkit_credential_get_type webkit_frame_get_type webkit_certificate_info_get_type +webkit_user_content_manager_get_type +webkit_web_hit_test_result_get_type +webkit_website_data_manager_get_type +webkit_editor_state_get_type +webkit_install_missing_media_plugins_permission_request_get_type +webkit_console_message_get_type +webkit_web_view_session_state_get_type +webkit_print_custom_widget_get_type diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml index e3cf9a68c..850d7db0b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml @@ -23,14 +23,20 @@ <xi:include href="xml/WebKitDownload.xml"/> <xi:include href="xml/WebKitPermissionRequest.xml"/> <xi:include href="xml/WebKitGeolocationPermissionRequest.xml"/> + <xi:include href="xml/WebKitInstallMissingMediaPluginsPermissionRequest.xml"/> + <xi:include href="xml/WebKitNavigationAction.xml"/> + <xi:include href="xml/WebKitUserMediaPermissionRequest.xml"/> <xi:include href="xml/WebKitPolicyDecision.xml"/> <xi:include href="xml/WebKitNavigationPolicyDecision.xml"/> <xi:include href="xml/WebKitResponsePolicyDecision.xml"/> <xi:include href="xml/WebKitHitTestResult.xml"/> + <xi:include href="xml/WebKitEditorState.xml"/> + <xi:include href="xml/WebKitPrintCustomWidget.xml"/> <xi:include href="xml/WebKitPrintOperation.xml"/> <xi:include href="xml/WebKitWebResource.xml"/> <xi:include href="xml/WebKitError.xml"/> <xi:include href="xml/WebKitFaviconDatabase.xml"/> + <xi:include href="xml/WebKitColorChooserRequest.xml"/> <xi:include href="xml/WebKitFileChooserRequest.xml"/> <xi:include href="xml/WebKitFindController.xml"/> <xi:include href="xml/WebKitCookieManager.xml"/> @@ -42,8 +48,14 @@ <xi:include href="xml/WebKitContextMenuItem.xml"/> <xi:include href="xml/WebKitFormSubmissionRequest.xml"/> <xi:include href="xml/WebKitSecurityManager.xml"/> - <xi:include href="xml/WebKitWebViewGroup.xml"/> - <xi:include href="xml/WebKitCertificateInfo.xml"/> + <xi:include href="xml/WebKitUserContentManager.xml"/> + <xi:include href="xml/WebKitUserContent.xml"/> + <xi:include href="xml/WebKitNotification.xml"/> + <xi:include href="xml/WebKitNotificationPermissionRequest.xml"/> + <xi:include href="xml/WebKitSecurityOrigin.xml"/> + <xi:include href="xml/WebKitWebsiteDataManager.xml"/> + <xi:include href="xml/WebKitWebsiteData.xml"/> + <xi:include href="xml/WebKitNetworkProxySettings.xml"/> </chapter> <chapter> @@ -52,21 +64,59 @@ <xi:include href="xml/WebKitWebPage.xml"/> <xi:include href="xml/WebKitFrame.xml"/> <xi:include href="xml/WebKitScriptWorld.xml"/> + <xi:include href="xml/WebKitWebHitTestResult.xml"/> + <xi:include href="xml/WebKitWebEditor.xml"/> + <xi:include href="xml/WebKitConsoleMessage.xml"/> </chapter> <index id="index-all"> <title>Index</title> </index> - + + <index id="api-index-deprecated" role="deprecated"> + <title>Index of deprecated symbols</title> + <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-2-2" role="2.2"> <title>Index of new symbols in 2.2</title> <xi:include href="xml/api-index-2.2.xml"><xi:fallback /></xi:include> - </index> + </index> <index id="api-index-2-4" role="2.4"> <title>Index of new symbols in 2.4</title> <xi:include href="xml/api-index-2.4.xml"><xi:fallback /></xi:include> </index> + <index id="api-index-2-6" role="2.6"> + <title>Index of new symbols in 2.6</title> + <xi:include href="xml/api-index-2.6.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-8" role="2.8"> + <title>Index of new symbols in 2.8</title> + <xi:include href="xml/api-index-2.8.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-10" role="2.10"> + <title>Index of new symbols in 2.10</title> + <xi:include href="xml/api-index-2.10.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-12" role="2.12"> + <title>Index of new symbols in 2.12</title> + <xi:include href="xml/api-index-2.12.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-14" role="2.14"> + <title>Index of new symbols in 2.14</title> + <xi:include href="xml/api-index-2.14.xml"><xi:fallback /></xi:include> + </index> + + <index id="api-index-2-16" role="2.16"> + <title>Index of new symbols in 2.16</title> + <xi:include href="xml/api-index-2.16.xml"><xi:fallback /></xi:include> + </index> + <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> </book> diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index c18538a63..63dd1d5be 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -30,7 +30,6 @@ #include <webkit2/WebKitAuthenticationRequest.h> #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitBackForwardListItem.h> -#include <webkit2/WebKitCertificateInfo.h> #include <webkit2/WebKitContextMenu.h> #include <webkit2/WebKitContextMenuActions.h> #include <webkit2/WebKitContextMenuItem.h> @@ -39,36 +38,52 @@ #include <webkit2/WebKitDefines.h> #include <webkit2/WebKitDownload.h> #include <webkit2/WebKitEditingCommands.h> +#include <webkit2/WebKitEditorState.h> #include <webkit2/WebKitEnumTypes.h> #include <webkit2/WebKitError.h> #include <webkit2/WebKitFaviconDatabase.h> +#include <webkit2/WebKitColorChooserRequest.h> #include <webkit2/WebKitFileChooserRequest.h> #include <webkit2/WebKitFindController.h> #include <webkit2/WebKitFormSubmissionRequest.h> #include <webkit2/WebKitGeolocationPermissionRequest.h> #include <webkit2/WebKitHitTestResult.h> +#include <webkit2/WebKitInstallMissingMediaPluginsPermissionRequest.h> #include <webkit2/WebKitJavascriptResult.h> #include <webkit2/WebKitMimeInfo.h> +#include <webkit2/WebKitNavigationAction.h> #include <webkit2/WebKitNavigationPolicyDecision.h> +#include <webkit2/WebKitNetworkProxySettings.h> +#include <webkit2/WebKitNotification.h> +#include <webkit2/WebKitNotificationPermissionRequest.h> #include <webkit2/WebKitPermissionRequest.h> #include <webkit2/WebKitPlugin.h> +#include <webkit2/WebKitPrintCustomWidget.h> #include <webkit2/WebKitPrintOperation.h> #include <webkit2/WebKitResponsePolicyDecision.h> #include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSecurityManager.h> +#include <webkit2/WebKitSecurityOrigin.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> #include <webkit2/WebKitURISchemeRequest.h> +#include <webkit2/WebKitUserContent.h> +#include <webkit2/WebKitUserContentManager.h> +#include <webkit2/WebKitUserMediaPermissionRequest.h> #include <webkit2/WebKitVersion.h> #include <webkit2/WebKitWebContext.h> #include <webkit2/WebKitWebInspector.h> #include <webkit2/WebKitWebResource.h> #include <webkit2/WebKitWebView.h> #include <webkit2/WebKitWebViewBase.h> -#include <webkit2/WebKitWebViewGroup.h> +#include <webkit2/WebKitWebViewSessionState.h> +#include <webkit2/WebKitWebsiteData.h> +#include <webkit2/WebKitWebsiteDataManager.h> #include <webkit2/WebKitWindowProperties.h> +#include <webkit2/WebKitAutocleanups.h> + #undef __WEBKIT2_H_INSIDE__ #endif /* __WEBKIT2_H__ */ diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list index e1cfe0721..d638661f4 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list @@ -1,6 +1,5 @@ BOOLEAN:BOXED BOOLEAN:BOXED,STRING -BOOLEAN:ENUM,STRING,POINTER BOOLEAN:OBJECT BOOLEAN:OBJECT,BOXED,OBJECT BOOLEAN:OBJECT,ENUM diff --git a/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.cpp b/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.cpp new file mode 100644 index 000000000..1a4ff9791 --- /dev/null +++ b/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.cpp @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AcceleratedDrawingAreaProxy.h" + +#include "DrawingAreaMessages.h" +#include "DrawingAreaProxyMessages.h" +#include "LayerTreeContext.h" +#include "UpdateInfo.h" +#include "WebPageProxy.h" +#include "WebPreferences.h" +#include "WebProcessProxy.h" +#include <WebCore/Region.h> + +#if PLATFORM(WAYLAND) +#include "WaylandCompositor.h" +#include <WebCore/PlatformDisplay.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +AcceleratedDrawingAreaProxy::AcceleratedDrawingAreaProxy(WebPageProxy& webPageProxy) + : DrawingAreaProxy(DrawingAreaTypeImpl, webPageProxy) +{ +} + +AcceleratedDrawingAreaProxy::~AcceleratedDrawingAreaProxy() +{ + // Make sure to exit accelerated compositing mode. + if (isInAcceleratedCompositingMode()) + exitAcceleratedCompositingMode(); +} + +bool AcceleratedDrawingAreaProxy::alwaysUseCompositing() const +{ + return m_webPageProxy.preferences().acceleratedCompositingEnabled() && m_webPageProxy.preferences().forceCompositingMode(); +} + +void AcceleratedDrawingAreaProxy::dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)> callbackFunction) +{ + if (!m_webPageProxy.isValid()) { + callbackFunction(CallbackBase::Error::OwnerWasInvalidated); + return; + } + + RunLoop::main().dispatch([callbackFunction] { + callbackFunction(CallbackBase::Error::None); + }); +} + +void AcceleratedDrawingAreaProxy::sizeDidChange() +{ + backingStoreStateDidChange(RespondImmediately); +} + +void AcceleratedDrawingAreaProxy::deviceScaleFactorDidChange() +{ + backingStoreStateDidChange(RespondImmediately); +} + +void AcceleratedDrawingAreaProxy::visibilityDidChange() +{ + // If we don't have a backing store, go ahead and mark the backing store as being changed so + // that when paint we'll actually wait for something to paint and not flash white. + if (m_layerTreeContext.isEmpty()) + backingStoreStateDidChange(DoNotRespondImmediately); +} + +void AcceleratedDrawingAreaProxy::waitForBackingStoreUpdateOnNextPaint() +{ + m_hasReceivedFirstUpdate = true; +} + +void AcceleratedDrawingAreaProxy::didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo& updateInfo, const LayerTreeContext& layerTreeContext) +{ + ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_nextBackingStoreStateID); + ASSERT_ARG(backingStoreStateID, backingStoreStateID > m_currentBackingStoreStateID); + m_currentBackingStoreStateID = backingStoreStateID; + + m_isWaitingForDidUpdateBackingStoreState = false; + + // Stop the responsiveness timer that was started in sendUpdateBackingStoreState. + m_webPageProxy.process().responsivenessTimer().stop(); + + if (layerTreeContext != m_layerTreeContext) { + if (layerTreeContext.isEmpty() && !m_layerTreeContext.isEmpty()) { + exitAcceleratedCompositingMode(); + ASSERT(m_layerTreeContext.isEmpty()); + } else if (!layerTreeContext.isEmpty() && m_layerTreeContext.isEmpty()) { + enterAcceleratedCompositingMode(layerTreeContext); + ASSERT(layerTreeContext == m_layerTreeContext); + } else { + updateAcceleratedCompositingMode(layerTreeContext); + ASSERT(layerTreeContext == m_layerTreeContext); + } + } + + if (m_nextBackingStoreStateID != m_currentBackingStoreStateID) + sendUpdateBackingStoreState(RespondImmediately); + else { + m_hasReceivedFirstUpdate = true; + +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (m_pendingNativeSurfaceHandleForCompositing) { + setNativeSurfaceHandleForCompositing(m_pendingNativeSurfaceHandleForCompositing); + m_pendingNativeSurfaceHandleForCompositing = 0; + } +#endif + } +} + +void AcceleratedDrawingAreaProxy::enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) +{ + ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); + if (backingStoreStateID < m_currentBackingStoreStateID) + return; + + enterAcceleratedCompositingMode(layerTreeContext); +} + +void AcceleratedDrawingAreaProxy::exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo& updateInfo) +{ + ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); + if (backingStoreStateID < m_currentBackingStoreStateID) + return; + + exitAcceleratedCompositingMode(); +} + +void AcceleratedDrawingAreaProxy::updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) +{ + ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); + if (backingStoreStateID < m_currentBackingStoreStateID) + return; + + updateAcceleratedCompositingMode(layerTreeContext); +} + +void AcceleratedDrawingAreaProxy::backingStoreStateDidChange(RespondImmediatelyOrNot respondImmediatelyOrNot) +{ + ++m_nextBackingStoreStateID; + sendUpdateBackingStoreState(respondImmediatelyOrNot); +} + +void AcceleratedDrawingAreaProxy::sendUpdateBackingStoreState(RespondImmediatelyOrNot respondImmediatelyOrNot) +{ + ASSERT(m_currentBackingStoreStateID < m_nextBackingStoreStateID); + + if (!m_webPageProxy.isValid()) + return; + + if (m_isWaitingForDidUpdateBackingStoreState) + return; + + if (m_webPageProxy.viewSize().isEmpty() && !m_webPageProxy.useFixedLayout()) + return; + + m_isWaitingForDidUpdateBackingStoreState = respondImmediatelyOrNot == RespondImmediately; + + m_webPageProxy.process().send(Messages::DrawingArea::UpdateBackingStoreState(m_nextBackingStoreStateID, respondImmediatelyOrNot == RespondImmediately, m_webPageProxy.deviceScaleFactor(), m_size, m_scrollOffset), m_webPageProxy.pageID()); + m_scrollOffset = IntSize(); + + if (m_isWaitingForDidUpdateBackingStoreState) { + // Start the responsiveness timer. We will stop it when we hear back from the WebProcess + // in didUpdateBackingStoreState. + m_webPageProxy.process().responsivenessTimer().start(); + } + + if (m_isWaitingForDidUpdateBackingStoreState && !m_layerTreeContext.isEmpty()) { + // Wait for the DidUpdateBackingStoreState message. Normally we do this in AcceleratedDrawingAreaProxy::paint, but that + // function is never called when in accelerated compositing mode. + waitForAndDispatchDidUpdateBackingStoreState(); + } +} + +void AcceleratedDrawingAreaProxy::waitForAndDispatchDidUpdateBackingStoreState() +{ + ASSERT(m_isWaitingForDidUpdateBackingStoreState); + + if (!m_webPageProxy.isValid()) + return; + if (m_webPageProxy.process().state() == WebProcessProxy::State::Launching) + return; + if (!m_webPageProxy.isViewVisible()) + return; + +#if PLATFORM(WAYLAND) && USE(EGL) + // Never block the UI process in Wayland when waiting for DidUpdateBackingStoreState after a resize, + // because the nested compositor needs to handle the web process requests that happens while resizing. + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland && WaylandCompositor::singleton().isRunning()) + return; +#endif + + // FIXME: waitForAndDispatchImmediately will always return the oldest DidUpdateBackingStoreState message that + // hasn't yet been processed. But it might be better to skip ahead to some other DidUpdateBackingStoreState + // message, if multiple DidUpdateBackingStoreState messages are waiting to be processed. For instance, we could + // choose the most recent one, or the one that is closest to our current size. + + // The timeout, in seconds, we use when waiting for a DidUpdateBackingStoreState message when we're asked to paint. + m_webPageProxy.process().connection()->waitForAndDispatchImmediately<Messages::DrawingAreaProxy::DidUpdateBackingStoreState>(m_webPageProxy.pageID(), Seconds::fromMilliseconds(500)); +} + +void AcceleratedDrawingAreaProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +{ + ASSERT(alwaysUseCompositing() || !isInAcceleratedCompositingMode()); + + m_layerTreeContext = layerTreeContext; + m_webPageProxy.enterAcceleratedCompositingMode(layerTreeContext); +} + +void AcceleratedDrawingAreaProxy::exitAcceleratedCompositingMode() +{ + ASSERT(isInAcceleratedCompositingMode()); + + m_layerTreeContext = LayerTreeContext(); + m_webPageProxy.exitAcceleratedCompositingMode(); +} + +void AcceleratedDrawingAreaProxy::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +{ + ASSERT(isInAcceleratedCompositingMode()); + + m_layerTreeContext = layerTreeContext; + m_webPageProxy.updateAcceleratedCompositingMode(layerTreeContext); +} + +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) +void AcceleratedDrawingAreaProxy::setNativeSurfaceHandleForCompositing(uint64_t handle) +{ + if (!m_hasReceivedFirstUpdate) { + m_pendingNativeSurfaceHandleForCompositing = handle; + return; + } + m_webPageProxy.process().send(Messages::DrawingArea::SetNativeSurfaceHandleForCompositing(handle), m_webPageProxy.pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); +} + +void AcceleratedDrawingAreaProxy::destroyNativeSurfaceHandleForCompositing() +{ + if (m_pendingNativeSurfaceHandleForCompositing) { + m_pendingNativeSurfaceHandleForCompositing = 0; + return; + } + bool handled; + m_webPageProxy.process().sendSync(Messages::DrawingArea::DestroyNativeSurfaceHandleForCompositing(), Messages::DrawingArea::DestroyNativeSurfaceHandleForCompositing::Reply(handled), m_webPageProxy.pageID()); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.h b/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.h new file mode 100644 index 000000000..e7890c807 --- /dev/null +++ b/Source/WebKit2/UIProcess/AcceleratedDrawingAreaProxy.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "DrawingAreaProxy.h" +#include "LayerTreeContext.h" + +namespace WebKit { + +class AcceleratedDrawingAreaProxy : public DrawingAreaProxy { +public: + explicit AcceleratedDrawingAreaProxy(WebPageProxy&); + virtual ~AcceleratedDrawingAreaProxy(); + + bool isInAcceleratedCompositingMode() const { return alwaysUseCompositing() || !m_layerTreeContext.isEmpty(); } + void visibilityDidChange(); + +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + void setNativeSurfaceHandleForCompositing(uint64_t); + void destroyNativeSurfaceHandleForCompositing(); +#endif + + void dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)>) override; + +protected: + // DrawingAreaProxy + void sizeDidChange() override; + void deviceScaleFactorDidChange() override; + void waitForBackingStoreUpdateOnNextPaint() override; + + // IPC message handlers + void didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo&, const LayerTreeContext&) override; + void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override; + void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) override; + void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) override; + + enum RespondImmediatelyOrNot { DoNotRespondImmediately, RespondImmediately }; + void backingStoreStateDidChange(RespondImmediatelyOrNot); + void sendUpdateBackingStoreState(RespondImmediatelyOrNot); + void waitForAndDispatchDidUpdateBackingStoreState(); + + virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); + void exitAcceleratedCompositingMode(); + void updateAcceleratedCompositingMode(const LayerTreeContext&); + + bool alwaysUseCompositing() const; + + // The state ID corresponding to our current backing store. Updated whenever we allocate + // a new backing store. Any messages received that correspond to an earlier state are ignored, + // as they don't apply to our current backing store. + uint64_t m_currentBackingStoreStateID { 0 }; + + // The next backing store state ID we will request the web process update to. Incremented + // whenever our state changes in a way that will require a new backing store to be allocated. + uint64_t m_nextBackingStoreStateID { 0 }; + + // The current layer tree context. + LayerTreeContext m_layerTreeContext; + + // Whether we've sent a UpdateBackingStoreState message and are now waiting for a DidUpdateBackingStoreState message. + // Used to throttle UpdateBackingStoreState messages so we don't send them faster than the Web process can handle. + bool m_isWaitingForDidUpdateBackingStoreState { false }; + + // For a new Drawing Area don't draw anything until the WebProcess has sent over the first content. + bool m_hasReceivedFirstUpdate { false }; + +#if USE(TEXTURE_MAPPER_GL) && PLATFORM(GTK) && PLATFORM(X11) && !USE(REDIRECTED_XCOMPOSITE_WINDOW) + uint64_t m_pendingNativeSurfaceHandleForCompositing { 0 }; +#endif +}; + +} // namespace WebKit + diff --git a/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.cpp b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.cpp new file mode 100644 index 000000000..92a19f8e3 --- /dev/null +++ b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.cpp @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2015, 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPaymentCoordinatorProxy.h" + +#if ENABLE(APPLE_PAY) + +#include "WebPageProxy.h" +#include "WebPaymentCoordinatorMessages.h" +#include "WebPaymentCoordinatorProxyMessages.h" +#include "WebProcessProxy.h" +#include <WebCore/PaymentAuthorizationStatus.h> + +namespace WebKit { + +static WebPaymentCoordinatorProxy* activePaymentCoordinatorProxy; + +WebPaymentCoordinatorProxy::WebPaymentCoordinatorProxy(WebPageProxy& webPageProxy) + : m_webPageProxy(webPageProxy) + , m_weakPtrFactory(this) + , m_state(State::Idle) + , m_merchantValidationState(MerchantValidationState::Idle) +{ + m_webPageProxy.process().addMessageReceiver(Messages::WebPaymentCoordinatorProxy::messageReceiverName(), m_webPageProxy.pageID(), *this); +} + +WebPaymentCoordinatorProxy::~WebPaymentCoordinatorProxy() +{ + if (activePaymentCoordinatorProxy == this) + activePaymentCoordinatorProxy = nullptr; + + if (m_state != State::Idle) + hidePaymentUI(); + + m_webPageProxy.process().removeMessageReceiver(Messages::WebPaymentCoordinatorProxy::messageReceiverName(), m_webPageProxy.pageID()); +} + +void WebPaymentCoordinatorProxy::canMakePayments(bool& reply) +{ + reply = platformCanMakePayments(); +} + +void WebPaymentCoordinatorProxy::canMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, uint64_t requestID) +{ + auto weakThis = m_weakPtrFactory.createWeakPtr(); + platformCanMakePaymentsWithActiveCard(merchantIdentifier, domainName, [weakThis, requestID](bool canMakePayments) { + auto paymentCoordinatorProxy = weakThis.get(); + if (!paymentCoordinatorProxy) + return; + + paymentCoordinatorProxy->m_webPageProxy.send(Messages::WebPaymentCoordinator::CanMakePaymentsWithActiveCardReply(requestID, canMakePayments)); + }); +} + +void WebPaymentCoordinatorProxy::openPaymentSetup(const String& merchantIdentifier, const String& domainName, uint64_t requestID) +{ + auto weakThis = m_weakPtrFactory.createWeakPtr(); + platformOpenPaymentSetup(merchantIdentifier, domainName, [weakThis, requestID](bool result) { + auto paymentCoordinatorProxy = weakThis.get(); + if (!paymentCoordinatorProxy) + return; + + paymentCoordinatorProxy->m_webPageProxy.send(Messages::WebPaymentCoordinator::OpenPaymentSetupReply(requestID, result)); + }); +} + +void WebPaymentCoordinatorProxy::showPaymentUI(const String& originatingURLString, const Vector<String>& linkIconURLStrings, const WebCore::PaymentRequest& paymentRequest, bool& result) +{ + // FIXME: Make this a message check. + ASSERT(canBegin()); + + if (activePaymentCoordinatorProxy) { + activePaymentCoordinatorProxy->hidePaymentUI(); + activePaymentCoordinatorProxy->didCancelPayment(); + } + + activePaymentCoordinatorProxy = this; + + m_state = State::Activating; + + WebCore::URL originatingURL(WebCore::URL(), originatingURLString); + + Vector<WebCore::URL> linkIconURLs; + for (const auto& linkIconURLString : linkIconURLStrings) + linkIconURLs.append(WebCore::URL(WebCore::URL(), linkIconURLString)); + + platformShowPaymentUI(originatingURL, linkIconURLs, paymentRequest, [this](bool result) { + ASSERT(m_state == State::Activating); + if (!result) { + didCancelPayment(); + return; + } + + m_state = State::Active; + }); + + result = true; +} + +static bool isValidEnum(WebCore::PaymentAuthorizationStatus status) +{ + switch (status) { + case WebCore::PaymentAuthorizationStatus::Success: + case WebCore::PaymentAuthorizationStatus::Failure: + case WebCore::PaymentAuthorizationStatus::InvalidBillingPostalAddress: + case WebCore::PaymentAuthorizationStatus::InvalidShippingPostalAddress: + case WebCore::PaymentAuthorizationStatus::InvalidShippingContact: + case WebCore::PaymentAuthorizationStatus::PINRequired: + case WebCore::PaymentAuthorizationStatus::PINIncorrect: + case WebCore::PaymentAuthorizationStatus::PINLockout: + return true; + } + + return false; +} + +void WebPaymentCoordinatorProxy::completeMerchantValidation(const WebCore::PaymentMerchantSession& paymentMerchantSession) +{ + // It's possible that the payment has been canceled already. + if (m_state == State::Idle) + return; + + // FIXME: This should be a MESSAGE_CHECK. + ASSERT(m_merchantValidationState == MerchantValidationState::Validating); + + platformCompleteMerchantValidation(paymentMerchantSession); + m_merchantValidationState = MerchantValidationState::ValidationComplete; +} + +void WebPaymentCoordinatorProxy::completeShippingMethodSelection(uint32_t opaqueStatus, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>& newTotalAndLineItems) +{ + // It's possible that the payment has been canceled already. + if (m_state == State::Idle) + return; + + // FIXME: This should be a MESSAGE_CHECK. + ASSERT(m_state == State::ShippingMethodSelected); + + auto status = static_cast<WebCore::PaymentAuthorizationStatus>(opaqueStatus); + + // FIXME: Make this a message check. + RELEASE_ASSERT(isValidEnum(status)); + + platformCompleteShippingMethodSelection(status, newTotalAndLineItems); + m_state = State::Active; +} + +void WebPaymentCoordinatorProxy::completeShippingContactSelection(uint32_t opaqueStatus, const Vector<WebCore::PaymentRequest::ShippingMethod>& newShippingMethods, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>& newTotalAndLineItems) +{ + // It's possible that the payment has been canceled already. + if (m_state == State::Idle) + return; + + // FIXME: This should be a MESSAGE_CHECK. + ASSERT(m_state == State::ShippingContactSelected); + + auto status = static_cast<WebCore::PaymentAuthorizationStatus>(opaqueStatus); + + // FIXME: Make this a message check. + RELEASE_ASSERT(isValidEnum(status)); + + platformCompleteShippingContactSelection(status, newShippingMethods, newTotalAndLineItems); + m_state = State::Active; +} + +void WebPaymentCoordinatorProxy::completePaymentMethodSelection(const std::optional<WebCore::PaymentRequest::TotalAndLineItems>& newTotalAndLineItems) +{ + // It's possible that the payment has been canceled already. + if (m_state == State::Idle) + return; + + // FIXME: This should be a MESSAGE_CHECK. + ASSERT(m_state == State::PaymentMethodSelected); + + platformCompletePaymentMethodSelection(newTotalAndLineItems); + m_state = State::Active; +} + +void WebPaymentCoordinatorProxy::completePaymentSession(uint32_t opaqueStatus) +{ + // It's possible that the payment has been canceled already. + if (!canCompletePayment()) + return; + + auto status = static_cast<WebCore::PaymentAuthorizationStatus>(opaqueStatus); + + // FIXME: Make this a message check. + RELEASE_ASSERT(isValidEnum(status)); + + platformCompletePaymentSession(status); + + if (!WebCore::isFinalStateStatus(status)) { + m_state = State::Active; + return; + } + + didReachFinalState(); +} + +void WebPaymentCoordinatorProxy::abortPaymentSession() +{ + // It's possible that the payment has been canceled already. + if (!canAbort()) + return; + + hidePaymentUI(); + + didReachFinalState(); +} + +void WebPaymentCoordinatorProxy::didCancelPayment() +{ + ASSERT(canCancel()); + + m_webPageProxy.send(Messages::WebPaymentCoordinator::DidCancelPayment()); + + didReachFinalState(); +} + +void WebPaymentCoordinatorProxy::validateMerchant(const WebCore::URL& url) +{ + ASSERT(m_merchantValidationState == MerchantValidationState::Idle); + + m_merchantValidationState = MerchantValidationState::Validating; + m_webPageProxy.send(Messages::WebPaymentCoordinator::ValidateMerchant(url.string())); +} + +void WebPaymentCoordinatorProxy::didAuthorizePayment(const WebCore::Payment& payment) +{ + m_state = State::Authorized; + m_webPageProxy.send(Messages::WebPaymentCoordinator::DidAuthorizePayment(payment)); +} + +void WebPaymentCoordinatorProxy::didSelectShippingMethod(const WebCore::PaymentRequest::ShippingMethod& shippingMethod) +{ + ASSERT(m_state == State::Active); + + m_state = State::ShippingMethodSelected; + m_webPageProxy.send(Messages::WebPaymentCoordinator::DidSelectShippingMethod(shippingMethod)); +} + +void WebPaymentCoordinatorProxy::didSelectShippingContact(const WebCore::PaymentContact& shippingContact) +{ + ASSERT(m_state == State::Active); + + m_state = State::ShippingContactSelected; + m_webPageProxy.send(Messages::WebPaymentCoordinator::DidSelectShippingContact(shippingContact)); +} + +void WebPaymentCoordinatorProxy::didSelectPaymentMethod(const WebCore::PaymentMethod& paymentMethod) +{ + ASSERT(m_state == State::Active); + + m_state = State::PaymentMethodSelected; + m_webPageProxy.send(Messages::WebPaymentCoordinator::DidSelectPaymentMethod(paymentMethod)); +} + +bool WebPaymentCoordinatorProxy::canBegin() const +{ + switch (m_state) { + case State::Idle: + return true; + + case State::Activating: + case State::Active: + case State::Authorized: + case State::ShippingMethodSelected: + case State::ShippingContactSelected: + case State::PaymentMethodSelected: + return false; + } +} + +bool WebPaymentCoordinatorProxy::canCancel() const +{ + switch (m_state) { + case State::Activating: + case State::Active: + case State::Authorized: + case State::ShippingMethodSelected: + case State::ShippingContactSelected: + case State::PaymentMethodSelected: + return true; + + case State::Idle: + return false; + } +} + +bool WebPaymentCoordinatorProxy::canCompletePayment() const +{ + switch (m_state) { + case State::Authorized: + return true; + + case State::Idle: + case State::Activating: + case State::Active: + case State::ShippingMethodSelected: + case State::ShippingContactSelected: + case State::PaymentMethodSelected: + return false; + } +} + +bool WebPaymentCoordinatorProxy::canAbort() const +{ + switch (m_state) { + case State::Activating: + case State::Active: + case State::Authorized: + case State::ShippingMethodSelected: + case State::ShippingContactSelected: + case State::PaymentMethodSelected: + return true; + + case State::Idle: + return false; + } +} + +void WebPaymentCoordinatorProxy::didReachFinalState() +{ + m_state = State::Idle; + m_merchantValidationState = MerchantValidationState::Idle; + + ASSERT(activePaymentCoordinatorProxy == this); + activePaymentCoordinatorProxy = nullptr; +} + +} + +#endif diff --git a/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.h b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.h new file mode 100644 index 000000000..c26f7ceee --- /dev/null +++ b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(APPLE_PAY) + +#include "MessageReceiver.h" +#include <WebCore/PaymentHeaders.h> +#include <wtf/Forward.h> +#include <wtf/RetainPtr.h> +#include <wtf/WeakPtr.h> + +namespace IPC { +class DataReference; +} + +namespace WebCore { +enum class PaymentAuthorizationStatus; +class Payment; +class PaymentContact; +class PaymentMerchantSession; +class PaymentMethod; +class URL; +} + +OBJC_CLASS NSObject; +OBJC_CLASS NSWindow; +OBJC_CLASS PKPaymentAuthorizationViewController; +OBJC_CLASS WKPaymentAuthorizationViewControllerDelegate; + +namespace WebKit { + +class WebPageProxy; + +class WebPaymentCoordinatorProxy : private IPC::MessageReceiver { +public: + explicit WebPaymentCoordinatorProxy(WebPageProxy&); + ~WebPaymentCoordinatorProxy(); + + void didCancelPayment(); + void validateMerchant(const WebCore::URL&); + void didAuthorizePayment(const WebCore::Payment&); + void didSelectShippingMethod(const WebCore::PaymentRequest::ShippingMethod&); + void didSelectShippingContact(const WebCore::PaymentContact&); + void didSelectPaymentMethod(const WebCore::PaymentMethod&); + + void hidePaymentUI(); + +private: + // IPC::MessageReceiver. + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + + // Message handlers. + void canMakePayments(bool& reply); + void canMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, uint64_t requestID); + void openPaymentSetup(const String& merchantIdentifier, const String& domainName, uint64_t requestID); + void showPaymentUI(const String& originatingURLString, const Vector<String>& linkIconURLStrings, const WebCore::PaymentRequest&, bool& result); + void completeMerchantValidation(const WebCore::PaymentMerchantSession&); + void completeShippingMethodSelection(uint32_t opaqueStatus, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void completeShippingContactSelection(uint32_t opaqueStatus, const Vector<WebCore::PaymentRequest::ShippingMethod>& newShippingMethods, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void completePaymentMethodSelection(const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void completePaymentSession(uint32_t opaqueStatus); + void abortPaymentSession(); + + bool canBegin() const; + bool canCancel() const; + bool canCompletePayment() const; + bool canAbort() const; + + void didReachFinalState(); + + bool platformCanMakePayments(); + void platformCanMakePaymentsWithActiveCard(const String& merchantIdentifier, const String& domainName, std::function<void (bool)> completionHandler); + void platformOpenPaymentSetup(const String& merchantIdentifier, const String& domainName, std::function<void (bool)> completionHandler); + void platformShowPaymentUI(const WebCore::URL& originatingURL, const Vector<WebCore::URL>& linkIconURLs, const WebCore::PaymentRequest&, std::function<void (bool)> completionHandler); + void platformCompleteMerchantValidation(const WebCore::PaymentMerchantSession&); + void platformCompleteShippingMethodSelection(WebCore::PaymentAuthorizationStatus, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void platformCompleteShippingContactSelection(WebCore::PaymentAuthorizationStatus, const Vector<WebCore::PaymentRequest::ShippingMethod>& newShippingMethods, const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void platformCompletePaymentMethodSelection(const std::optional<WebCore::PaymentRequest::TotalAndLineItems>&); + void platformCompletePaymentSession(WebCore::PaymentAuthorizationStatus); + + WebPageProxy& m_webPageProxy; + WeakPtrFactory<WebPaymentCoordinatorProxy> m_weakPtrFactory; + + enum class State { + // Idle - Nothing's happening. + Idle, + + // Activating - Waiting to show the payment UI. + Activating, + + // Active - Showing payment UI. + Active, + + // Authorized - Dispatching the authorized event and waiting for the paymentSessionCompleted message. + Authorized, + + // ShippingMethodSelected - Dispatching the shippingmethodselected event and waiting for a reply. + ShippingMethodSelected, + + // ShippingContactSelected - Dispatching the shippingcontactselected event and waiting for a reply. + ShippingContactSelected, + + // PaymentMethodSelected - Dispatching the paymentmethodselected event and waiting for a reply. + PaymentMethodSelected, + } m_state; + + enum class MerchantValidationState { + // Idle - Nothing's happening. + Idle, + + // Validating - Dispatching the validatemerchant event and waiting for a reply. + Validating, + + // ValidationComplete - A merchant session has been sent along to PassKit. + ValidationComplete + } m_merchantValidationState; + + RetainPtr<PKPaymentAuthorizationViewController> m_paymentAuthorizationViewController; + RetainPtr<WKPaymentAuthorizationViewControllerDelegate> m_paymentAuthorizationViewControllerDelegate; + +#if PLATFORM(MAC) + uint64_t m_showPaymentUIRequestSeed { 0 }; + RetainPtr<NSWindow> m_sheetWindow; + RetainPtr<NSObject *> m_sheetWindowWillCloseObserver; +#endif +}; + +} + +#endif diff --git a/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.messages.in b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.messages.in new file mode 100644 index 000000000..8649816bd --- /dev/null +++ b/Source/WebKit2/UIProcess/ApplePay/WebPaymentCoordinatorProxy.messages.in @@ -0,0 +1,42 @@ +# Copyright (C) 2015 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +#/ + +#if ENABLE(APPLE_PAY) + +messages -> WebPaymentCoordinatorProxy { + + CanMakePayments() -> (bool result) + CanMakePaymentsWithActiveCard(String merchantIdentifier, String domainName, uint64_t requestID) + OpenPaymentSetup(String merchantIdentifier, String domainName, uint64_t requestID) + + ShowPaymentUI(String originatingURLString, Vector<String> linkIconURLStrings, WebCore::PaymentRequest paymentRequest) -> (bool result) + CompleteMerchantValidation(WebCore::PaymentMerchantSession paymentMerchantSession); + CompleteShippingMethodSelection(uint32_t opaqueStatus, std::optional<WebCore::PaymentRequest::TotalAndLineItems> newTotalAndItems) + CompleteShippingContactSelection(uint32_t opaqueStatus, Vector<WebCore::PaymentRequest::ShippingMethod> newShippingMethods, std::optional<WebCore::PaymentRequest::TotalAndLineItems> newTotalAndItems) + CompletePaymentMethodSelection(std::optional<WebCore::PaymentRequest::TotalAndLineItems> newTotalAndItems) + CompletePaymentSession(uint32_t opaqueStatus) + AbortPaymentSession() +} + +#endif diff --git a/Source/WebKit2/UIProcess/ApplicationStateTracker.h b/Source/WebKit2/UIProcess/ApplicationStateTracker.h new file mode 100644 index 000000000..696e29031 --- /dev/null +++ b/Source/WebKit2/UIProcess/ApplicationStateTracker.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ApplicationStateTracker_h +#define ApplicationStateTracker_h + +#if PLATFORM(IOS) + +#import "WeakObjCPtr.h" +#import <wtf/Forward.h> +#import <wtf/WeakPtr.h> + +OBJC_CLASS BKSApplicationStateMonitor; +OBJC_CLASS UIView; + +namespace WebKit { + +class ApplicationStateTracker { +public: + ApplicationStateTracker(UIView *, SEL didEnterBackgroundSelector, SEL didCreateWindowContextSelector, SEL didFinishSnapshottingAfterEnteringBackgroundSelector, SEL willEnterForegroundSelector); + ~ApplicationStateTracker(); + + bool isInBackground() const { return m_isInBackground; } + +private: + void applicationDidEnterBackground(); + void applicationDidCreateWindowContext(); + void applicationDidFinishSnapshottingAfterEnteringBackground(); + void applicationWillEnterForeground(); + + WeakObjCPtr<UIView> m_view; + SEL m_didEnterBackgroundSelector; + SEL m_didCreateWindowContextSelector; + SEL m_didFinishSnapshottingAfterEnteringBackgroundSelector; + SEL m_willEnterForegroundSelector; + + bool m_isInBackground; + + WeakPtrFactory<ApplicationStateTracker> m_weakPtrFactory; + + RetainPtr<BKSApplicationStateMonitor> m_applicationStateMonitor; + + id m_didEnterBackgroundObserver; + id m_didCreateWindowContextObserver; + id m_didFinishSnapshottingAfterEnteringBackgroundObserver; + id m_willEnterForegroundObserver; +}; + +} + +#endif + +#endif // ApplicationStateTracker_h diff --git a/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.cpp b/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.cpp index 8c5d26fc7..9bdd73b44 100644 --- a/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.cpp +++ b/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.cpp @@ -62,15 +62,19 @@ void AuthenticationChallengeProxy::useCredential(WebCredential* credential) if (!m_challengeID) return; - if (!credential) - m_connection->send(Messages::AuthenticationManager::ContinueWithoutCredentialForChallenge(m_challengeID), 0); - else { - WebCertificateInfo* certificateInfo = credential->certificateInfo(); - WebCore::CertificateInfo platformInfo = certificateInfo ? certificateInfo->certificateInfo() : WebCore::CertificateInfo(); - m_connection->send(Messages::AuthenticationManager::UseCredentialForChallenge(m_challengeID, credential->core(), platformInfo), 0); + uint64_t challengeID = m_challengeID; + m_challengeID = 0; + + if (!credential) { + m_connection->send(Messages::AuthenticationManager::ContinueWithoutCredentialForChallenge(challengeID), 0); + return; } - m_challengeID = 0; + WebCore::CertificateInfo certificateInfo; + if (credential->certificateInfo()) + certificateInfo = credential->certificateInfo()->certificateInfo(); + + m_connection->send(Messages::AuthenticationManager::UseCredentialForChallenge(challengeID, credential->credential(), certificateInfo), 0); } void AuthenticationChallengeProxy::cancel() @@ -83,6 +87,26 @@ void AuthenticationChallengeProxy::cancel() m_challengeID = 0; } +void AuthenticationChallengeProxy::performDefaultHandling() +{ + if (!m_challengeID) + return; + + m_connection->send(Messages::AuthenticationManager::PerformDefaultHandling(m_challengeID), 0); + + m_challengeID = 0; +} + +void AuthenticationChallengeProxy::rejectProtectionSpaceAndContinue() +{ + if (!m_challengeID) + return; + + m_connection->send(Messages::AuthenticationManager::RejectProtectionSpaceAndContinue(m_challengeID), 0); + + m_challengeID = 0; +} + WebCredential* AuthenticationChallengeProxy::proposedCredential() const { if (!m_webCredential) diff --git a/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.h b/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.h index a549d5188..9bac83f40 100644 --- a/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.h +++ b/Source/WebKit2/UIProcess/Authentication/AuthenticationChallengeProxy.h @@ -43,15 +43,17 @@ class WebProtectionSpace; class AuthenticationChallengeProxy : public API::ObjectImpl<API::Object::Type::AuthenticationChallenge> { public: - static PassRefPtr<AuthenticationChallengeProxy> create(const WebCore::AuthenticationChallenge& authenticationChallenge, uint64_t challengeID, IPC::Connection* connection) + static Ref<AuthenticationChallengeProxy> create(const WebCore::AuthenticationChallenge& authenticationChallenge, uint64_t challengeID, IPC::Connection* connection) { - return adoptRef(new AuthenticationChallengeProxy(authenticationChallenge, challengeID, connection)); + return adoptRef(*new AuthenticationChallengeProxy(authenticationChallenge, challengeID, connection)); } ~AuthenticationChallengeProxy(); void useCredential(WebCredential*); void cancel(); + void performDefaultHandling(); + void rejectProtectionSpaceAndContinue(); AuthenticationDecisionListener* listener() const { return m_listener.get(); } WebCredential* proposedCredential() const; diff --git a/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.cpp b/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.cpp index 00cd8748c..8bde289e3 100644 --- a/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.cpp +++ b/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.cpp @@ -52,6 +52,18 @@ void AuthenticationDecisionListener::cancel() m_challengeProxy->cancel(); } +void AuthenticationDecisionListener::performDefaultHandling() +{ + if (m_challengeProxy) + m_challengeProxy->performDefaultHandling(); +} + +void AuthenticationDecisionListener::rejectProtectionSpaceAndContinue() +{ + if (m_challengeProxy) + m_challengeProxy->rejectProtectionSpaceAndContinue(); +} + void AuthenticationDecisionListener::detachChallenge() { m_challengeProxy = 0; diff --git a/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.h b/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.h index 057ddd8cd..b5bd2b09a 100644 --- a/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.h +++ b/Source/WebKit2/UIProcess/Authentication/AuthenticationDecisionListener.h @@ -37,14 +37,16 @@ class WebCredential; class AuthenticationDecisionListener : public API::ObjectImpl<API::Object::Type::AuthenticationDecisionListener> { public: - static PassRefPtr<AuthenticationDecisionListener> create(AuthenticationChallengeProxy* authenticationChallenge) + static Ref<AuthenticationDecisionListener> create(AuthenticationChallengeProxy* authenticationChallenge) { - return adoptRef(new AuthenticationDecisionListener(authenticationChallenge)); + return adoptRef(*new AuthenticationDecisionListener(authenticationChallenge)); } void useCredential(WebCredential*); void cancel(); - + void performDefaultHandling(); + void rejectProtectionSpaceAndContinue(); + void detachChallenge(); private: diff --git a/Source/WebKit2/UIProcess/Authentication/WebCredential.cpp b/Source/WebKit2/UIProcess/Authentication/WebCredential.cpp index a69d509c7..a2d1d17cd 100644 --- a/Source/WebKit2/UIProcess/Authentication/WebCredential.cpp +++ b/Source/WebKit2/UIProcess/Authentication/WebCredential.cpp @@ -49,14 +49,9 @@ WebCertificateInfo* WebCredential::certificateInfo() return m_certificateInfo.get(); } -const WebCore::Credential& WebCredential::core() +const WebCore::Credential& WebCredential::credential() { return m_coreCredential; } -const String& WebCredential::user() const -{ - return m_coreCredential.user(); -} - } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Authentication/WebCredential.h b/Source/WebKit2/UIProcess/Authentication/WebCredential.h index efff6548c..eaaa1f70c 100644 --- a/Source/WebKit2/UIProcess/Authentication/WebCredential.h +++ b/Source/WebKit2/UIProcess/Authentication/WebCredential.h @@ -29,7 +29,6 @@ #include "APIObject.h" #include "APIString.h" #include <WebCore/Credential.h> -#include <wtf/PassRefPtr.h> namespace WebKit { @@ -39,27 +38,20 @@ class WebCredential : public API::ObjectImpl<API::Object::Type::Credential> { public: ~WebCredential(); - static PassRefPtr<WebCredential> create(const WebCore::Credential& credential) + static Ref<WebCredential> create(const WebCore::Credential& credential) { - return adoptRef(new WebCredential(credential)); + return adoptRef(*new WebCredential(credential)); } - static PassRefPtr<WebCredential> create(API::String* username, API::String* password, WebCore::CredentialPersistence persistence) + static Ref<WebCredential> create(WebCertificateInfo* certificateInfo) { - return adoptRef(new WebCredential(WebCore::Credential(username->string(), password->string(), persistence))); - } - - static PassRefPtr<WebCredential> create(WebCertificateInfo* certificateInfo) - { - return adoptRef(new WebCredential(certificateInfo)); + return adoptRef(*new WebCredential(certificateInfo)); } WebCertificateInfo* certificateInfo(); - const WebCore::Credential& core(); + const WebCore::Credential& credential(); - const String& user() const; - private: explicit WebCredential(const WebCore::Credential&); explicit WebCredential(WebCertificateInfo*); diff --git a/Source/WebKit2/UIProcess/Authentication/WebProtectionSpace.h b/Source/WebKit2/UIProcess/Authentication/WebProtectionSpace.h index 95ad0bb57..28beba6e8 100644 --- a/Source/WebKit2/UIProcess/Authentication/WebProtectionSpace.h +++ b/Source/WebKit2/UIProcess/Authentication/WebProtectionSpace.h @@ -28,15 +28,14 @@ #include "APIObject.h" #include <WebCore/ProtectionSpace.h> -#include <wtf/PassRefPtr.h> namespace WebKit { class WebProtectionSpace : public API::ObjectImpl<API::Object::Type::ProtectionSpace> { public: - static PassRefPtr<WebProtectionSpace> create(const WebCore::ProtectionSpace& protectionSpace) + static Ref<WebProtectionSpace> create(const WebCore::ProtectionSpace& protectionSpace) { - return adoptRef(new WebProtectionSpace(protectionSpace)); + return adoptRef(*new WebProtectionSpace(protectionSpace)); } const String& protocol() const; diff --git a/Source/WebKit2/UIProcess/AutoCorrectionCallback.h b/Source/WebKit2/UIProcess/AutoCorrectionCallback.h index 90cf9284e..fca183cdc 100644 --- a/Source/WebKit2/UIProcess/AutoCorrectionCallback.h +++ b/Source/WebKit2/UIProcess/AutoCorrectionCallback.h @@ -30,98 +30,13 @@ #include "GenericCallback.h" #include "WKAPICast.h" #include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebKit { -class AutocorrectionDataCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const Vector<WebCore::FloatRect>&, const String&, double, uint64_t, WKErrorRef, void*); - - static PassRefPtr<AutocorrectionDataCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new AutocorrectionDataCallback(context, callback)); - } - - virtual ~AutocorrectionDataCallback() - { - ASSERT(!m_callback); - } - - void performCallbackWithReturnValue(const Vector<WebCore::FloatRect>& returnValue1, const String& returnValue2, double returnValue3, uint64_t returnValue4) - { - ASSERT(m_callback); - - m_callback(returnValue1, returnValue2, returnValue3, returnValue4, 0, context()); - - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - m_callback(Vector<WebCore::FloatRect>(), String(), 0, 0, toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - AutocorrectionDataCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - ASSERT(m_callback); - } - - CallbackFunction m_callback; -}; - -class AutocorrectionContextCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const String&, const String&, const String&, const String&, uint64_t, uint64_t, WKErrorRef, void*); - - static PassRefPtr<AutocorrectionContextCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new AutocorrectionContextCallback(context, callback)); - } - - virtual ~AutocorrectionContextCallback() - { - ASSERT(!m_callback); - } - - void performCallbackWithReturnValue(const String& returnValue1, const String& returnValue2, const String& returnValue3, const String& returnValue4, uint64_t returnValue5, uint64_t returnValue6) - { - ASSERT(m_callback); - - m_callback(returnValue1, returnValue2, returnValue3, returnValue4, returnValue5, returnValue6, 0, context()); - - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - m_callback(String(), String(), String(), String(), 0, 0, toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - AutocorrectionContextCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - ASSERT(m_callback); - } - - CallbackFunction m_callback; -}; +typedef GenericCallback<const Vector<WebCore::FloatRect>&, const String&, double, uint64_t> AutocorrectionDataCallback; +typedef GenericCallback<const String&, const String&, const String&, const String&, uint64_t, uint64_t> AutocorrectionContextCallback; +typedef GenericCallback<const String&, const String&, const String&> SelectionContextCallback; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Automation/Automation.json b/Source/WebKit2/UIProcess/Automation/Automation.json new file mode 100644 index 000000000..bca27b875 --- /dev/null +++ b/Source/WebKit2/UIProcess/Automation/Automation.json @@ -0,0 +1,480 @@ +{ + "domain": "Automation", + "description": "Automation domain exposes commands for automating user interactions with the browser.", + "types": [ + { + "id": "Point", + "type": "object", + "properties": [ + { "name": "x", "type": "number" }, + { "name": "y", "type": "number" } + ] + }, + { + "id": "Size", + "type": "object", + "properties": [ + { "name": "width", "type": "number" }, + { "name": "height", "type": "number" } + ] + }, + { + "id": "Rect", + "type": "object", + "properties": [ + { "name": "origin", "$ref": "Point" }, + { "name": "size", "$ref": "Size" } + ] + }, + { + "id": "BrowsingContextHandle", + "type": "string", + "description": "An opaque identifier for a browsing context." + }, + { + "id": "FrameHandle", + "type": "string", + "description": "An opaque identifier for a frame in a page." + }, + { + "id": "NodeHandle", + "type": "string", + "description": "An opaque identifier for a node in a page." + }, + { + "id": "ErrorMessage", + "type": "string", + "description": "This enum contains predefined error messages that can be used to signal a well-defined error condition, such as a missing implementation, unknown window handle, and so forth. The backend signals one of these errors by using it as a prefix of the commands's error message (the errorString argument in generated C++ backend dispatchers). This will be reported to the frontend as a protocol error with a JSON-RPC error code of 'ServerError'. It is up to the frontend whether and how to deal with errors.", + "enum": [ + "InternalError", + "Timeout", + "JavaScriptError", + "JavaScriptTimeout", + "WindowNotFound", + "FrameNotFound", + "NodeNotFound", + "InvalidElementState", + "NoJavaScriptDialog", + "NotImplemented", + "MissingParameter", + "InvalidParameter" + ] + }, + { + "id": "BrowsingContext", + "type": "object", + "description": "A handle representing an open window or tab in the automation session.", + "properties": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "Opaque handle for a browsing context (window or tab). Used as a key for window-related commands." }, + { "name": "active", "type": "boolean", "description": "Whether the browsing context has focus at the time the command is handled." }, + { "name": "url", "type": "string", "description": "The URL loaded by the browsing context at the time the command is handled." }, + { "name": "windowSize", "$ref": "Size", "description": "The current size of the browsing context's window." }, + { "name": "windowOrigin", "$ref": "Point", "description": "The current (x, y) position of the browsing context's window relative to the top-left of the screen." } + ] + }, + { + "id": "MouseInteraction", + "type": "string", + "description": "Enumerates different ways of interacting with a mouse cursor.", + "enum": [ + "Move", + "Down", + "Up", + "SingleClick", + "DoubleClick" + ] + }, + { + "id": "MouseButton", + "type": "string", + "description": "Enumerates different mouse buttons that can be used.", + "enum": [ + "None", + "Left", + "Middle", + "Right" + ] + }, + { + "id": "KeyModifier", + "type": "string", + "description": "Enumerates different key modifiers that can remain pressed during other mouse/touch interactions.", + "enum": [ + "CapsLock", + "Control", + "Shift", + "Meta", + "Alt" + ] + }, + { + "id": "VirtualKey", + "type": "string", + "description": "Enumerates different platform-independent virtual keys on a physical keyboard whose input via keyboard may or may not produce characters.", + "enum": [ + "Shift", + "Control", + "Alternate", + "Meta", + "Command", + "Cancel", + "Help", + "Backspace", + "Tab", + "Clear", + "Enter", + "Pause", + "Escape", + "PageUp", + "PageDown", + "End", + "Home", + "LeftArrow", + "UpArrow", + "RightArrow", + "DownArrow", + "Insert", + "Delete", + "Space", + "Semicolon", + "Equals", + "Return", + "NumberPad0", + "NumberPad1", + "NumberPad2", + "NumberPad3", + "NumberPad4", + "NumberPad5", + "NumberPad6", + "NumberPad7", + "NumberPad8", + "NumberPad9", + "NumberPadMultiply", + "NumberPadAdd", + "NumberPadSeparator", + "NumberPadSubtract", + "NumberPadDecimal", + "NumberPadDivide", + "Function1", + "Function2", + "Function3", + "Function4", + "Function5", + "Function6", + "Function7", + "Function8", + "Function9", + "Function10", + "Function11", + "Function12" + ] + }, + { + "id": "KeyboardInteractionType", + "type": "string", + "description": "Enumerates different ways of interacting with a keyboard device. 'InsertByKey' implies that a separate KeyDown and KeyUp event are produced for each combining character sequence, regardless of the actual keystrokes required to produce the character sequence.", + "enum": [ + "KeyPress", + "KeyRelease", + "InsertByKey" + ] + }, + { + "id": "KeyboardInteraction", + "type": "object", + "description": "A single step in a key sequence. A step can contain a key up/down of a virtual key, or a sequence of Unicode code points that are delivered to the page at grapheme cluster boundaries. Either a 'key' or 'text' property must be specified.", + "properties": [ + { "name": "type", "$ref": "KeyboardInteractionType", "description": "The type of interaction to be performed by a step." }, + { "name": "key", "$ref": "VirtualKey", "optional": true, "description": "A virtual key to be used to perform the specified interaction." }, + { "name": "text", "type": "string", "optional": true, "description": "A unicode string to be delivered to the page. The sequence of key events is determined by splitting the string at grapheme cluster boundaries." } + ] + }, + { + "id": "Cookie", + "type": "object", + "properties": [ + { "name": "name", "type": "string", "description": "Cookie name." }, + { "name": "value", "type": "string", "description": "Cookie value." }, + { "name": "domain", "type": "string", "description": "Cookie domain. If empty, the domain is inherited from the relevant browsing context." }, + { "name": "path", "type": "string", "description": "Cookie path." }, + { "name": "expires", "type": "number", "description": "Cookie expiration in seconds since the UNIX epoch." }, + { "name": "size", "type": "integer", "description": "Cookie size." }, + { "name": "httpOnly", "type": "boolean", "description": "True if cookie is http-only." }, + { "name": "secure", "type": "boolean", "description": "True if cookie is secure." }, + { "name": "session", "type": "boolean", "description": "True in case of session cookie." } + ] + } + ], + "commands": [ + { + "name": "getBrowsingContexts", + "description": "Fetches information about all open browsing contexts (windows and tabs) in the automation session.", + "returns": [ + { "name": "contexts", "type": "array", "items": { "$ref": "BrowsingContext" }, "description": "All known browsing contexts available to the session." } + ] + }, + { + "name": "getBrowsingContext", + "description": "Fetches information about the specified browsing context.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ], + "returns": [ + { "name": "context", "$ref": "BrowsingContext", "description": "The browsing context available to the session." } + ] + }, + { + "name": "createBrowsingContext", + "description": "Opens a new browsing context in the automation session and makes it the active browsing context for user interaction. This command creates a browsing context in a new window rather than adding a tab to an existing window.", + "returns": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "An opaque handle for the newly created browsing context." } + ] + }, + { + "name": "closeBrowsingContext", + "description": "Try to close the specified browsing context. This can trigger an unload prompt and thereafter succeed or fail.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be closed." } + ] + }, + { + "name": "switchToBrowsingContext", + "description": "Activates the specified browsing context and optional frame, which gives them focus (causing the 'focus' DOM event to fire, and 'blur' DOM event to fire for the previous browsing context and frame).", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be made focused." }, + { "name": "frameHandle", "$ref": "FrameHandle", "optional": true, "description": "The handle for the frame that should be focused. Defaults to the main frame if omitted." } + ] + }, + { + "name": "resizeWindowOfBrowsingContext", + "description": "Resizes the window of the specified browsing context to the specified size.", + "platform": "macos", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to be resized." }, + { "name": "size", "$ref": "Size", "description": "The new size for the browsing context's window." } + ] + }, + { + "name": "moveWindowOfBrowsingContext", + "description": "Moves the window of the specified browsing context to the specified position.", + "platform": "macos", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to be moved." }, + { "name": "origin", "$ref": "Point", "description": "The new origin for the browsing context's window. The position is interpreted in screen coordinate space, relative to the upper left corner of the screen." } + ] + }, + { + "name": "navigateBrowsingContext", + "description": "Navigates a browsing context to a specified URL.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." }, + { "name": "url", "type": "string", "description": "The URL to load in the browsing context." } + ], + "async": true + }, + { + "name": "goBackInBrowsingContext", + "description": "Navigates a browsing context to go back one page in history.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." } + ], + "async": true + }, + { + "name": "goForwardInBrowsingContext", + "description": "Navigates a browsing context to got forward one page in history.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be navigated." } + ], + "async": true + }, + { + "name": "reloadBrowsingContext", + "description": "Reloads the current page in a browsing context.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be reloaded." } + ], + "async": true + }, + { + "name": "inspectBrowsingContext", + "description": "Inspect the specified browsing context using Web Inspector.", + "platform": "macos", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context that should be inspected." }, + { "name": "enableAutoCapturing", "type": "boolean", "optional": true, "description": "If this option is present and set to true, the Web Inspector will automatically start a timeline recording of the specified browsing context once it is attached. Note that this disables the debugger for the duration of the recording." } + ], + "async": true + }, + { + "name": "evaluateJavaScriptFunction", + "description": "Evaluates a script function in a browsing context and calls it with the supplied arguments.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context the script should be evaluated." }, + { "name": "frameHandle", "$ref": "FrameHandle", "optional": true, "description": "The handle for the frame the script should be evaluated. The main frame is used if this parameter empty string or excluded." }, + { "name": "function", "type": "string", "description": "The script to evaluate in the browsing context. It must be a function result." }, + { "name": "arguments", "type": "array", "items": { "type": "string" }, "description": "The arguments to pass to the function when called. They will be parsed as JSON before calling the function." }, + { "name": "expectsImplicitCallbackArgument", "type": "boolean", "optional": true, "description": "The function expects a callback function as the last argument. It is expected to call this callback with a result." }, + { "name": "callbackTimeout", "type": "integer", "optional": true, "description": "The timeout in milliseconds that the implicit callback is expected to be called in, otherwise a <code>JavaScriptTimeout</code> error is returned." } + ], + "returns": [ + { "name": "result", "type": "string", "description": "The result returned by the called function. It is JSON encoded after the function returns or calls the callback." } + ], + "async": true + }, + { + "name": "performMouseInteraction", + "description": "Simulates interaction with a mouse cursor.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The browsing context to be interacted with." }, + { "name": "position", "$ref": "Point", "description": "The requested position for the mouse cursor, specified in viewport coordinates." }, + { "name": "button", "$ref": "MouseButton", "description": "The button to use to perform the interaction. This parameter only has an effect for the <code>Down</code>, <code>Up</code>, <code>Click</code>, and <code>DoubleClick</code> mouse interactions." }, + { "name": "interaction", "$ref": "MouseInteraction", "description": "The type of interaction to be performed with the mouse cursor." }, + { "name": "modifiers", "type": "array", "items": { "$ref": "KeyModifier" }, "description": "Key modifiers to be active during the mouse interaction." } + ], + "returns": [ + { "name": "position", "$ref": "Point", "description": "The updated position of the mouse cursor, specified in viewport coordinates." } + ] + }, + { + "name": "performKeyboardInteractions", + "description": "Simulates delivering the results of pressing one or more keyboard keys together or successively.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context which should receive key." }, + { "name": "interactions", "type": "array", "items": { "$ref": "KeyboardInteraction" }, "description": "An ordered list of key sequences to be delivered using native key events." } + ], + "async": true + }, + { + "name": "takeScreenshot", + "description": "Take a screenshot of the current page in a browsing context.", + "parameters": [ + { "name": "handle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context to take a screenshot of." } + ], + "returns": [ + { "name": "data", "type": "string", "description": "Base64-encoded image data (PNG)." } + ], + "async": true + }, + { + "name": "resolveChildFrameHandle", + "description": "Determines the <code>FrameHandle</code> based on the ordinal, name or node handle of a child frame.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context in which to search for the frame." }, + { "name": "frameHandle", "$ref": "FrameHandle", "optional": true, "description": "The handle for the frame in which to search for the frame. The main frame is used if this parameter empty string or excluded." }, + { "name": "ordinal", "type": "integer", "optional": true, "description": "The ordinal of the child frame to resolve as a <code>FrameHandle</code>. This is analogous to 'window.frames[ordinal]' in JavaScript." }, + { "name": "name", "type": "string", "optional": true, "description": "The name of the child frame to resolve as a <code>FrameHandle</code>. This is analogous to 'window.frames[name]' in JavaScript." }, + { "name": "nodeHandle", "$ref": "NodeHandle", "optional": true, "description": "The handle of the child frame owner element to resolve as a <code>FrameHandle</code>." } + ], + "returns": [ + { "name": "result", "$ref": "FrameHandle", "description": "The <code>FrameHandle</code> for the requested frame." } + ], + "async": true + }, + { + "name": "resolveParentFrameHandle", + "description": "Determines the <code>FrameHandle</code> for the parent frame of the supplied <code>FrameHandle</code>.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context the frame is located." }, + { "name": "frameHandle", "$ref": "FrameHandle", "description": "The handle for the frame that should resolve its parent frame." } + ], + "returns": [ + { "name": "result", "$ref": "FrameHandle", "description": "The <code>FrameHandle</code> for the requested frame." } + ], + "async": true + }, + { + "name": "computeElementLayout", + "description": "Computes the layout for an element.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context the frame is located." }, + { "name": "frameHandle", "$ref": "FrameHandle", "description": "The handle for the frame that contains the element." }, + { "name": "nodeHandle", "$ref": "NodeHandle", "description": "The handle of the element to use." }, + { "name": "scrollIntoViewIfNeeded", "optional": true, "type": "boolean", "description": "If the element should be scrolled into view before computing its layout." }, + { "name": "useViewportCoordinates", "optional": true, "type": "boolean", "description": "If the result coordinates should be represented as viewport coordinates or not. Defaults to false, which means coordinates should be represented as page coordinates." } + ], + "returns": [ + { "name": "rect", "$ref": "Rect", "description": "The layout rect for the requested element. Specified in page or viewport coordinates based on the useViewportCoordinates parameter." } + ], + "async": true + }, + { + "name": "isShowingJavaScriptDialog", + "description": "Checks if a browsing context is showing a JavaScript alert, confirm, or prompt dialog.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ], + "returns": [ + { "name": "result", "type": "boolean", "description": "If the browsing context is showing a JavaScript dialog or not." } + ] + }, + { + "name": "dismissCurrentJavaScriptDialog", + "description": "Dismisses a JavaScript alert, confirm, or prompt dialog currently showing in a browsing context. Equivalent to clicking the 'Cancel' button.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ] + }, + { + "name": "acceptCurrentJavaScriptDialog", + "description": "Accepts a JavaScript alert, confirm, or prompt dialog currently showing in a browsing context. Equivalent to clicking the 'OK' button.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ] + }, + { + "name": "messageOfCurrentJavaScriptDialog", + "description": "Returns the text displayed in a JavaScript alert, confirm, or prompt dialog currently showing in a browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ], + "returns": [ + { "name": "message", "type": "string", "description": "Text being displayed in the current JavaScript dialog." } + ] + }, + { + "name": "setUserInputForCurrentJavaScriptPrompt", + "description": "Sets the user entered value in a JavaScript prompt dialog currently showing in a browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }, + { "name": "userInput", "type": "string", "description": "The text to enter in the prompt." } + ] + }, + { + "name": "getAllCookies", + "description": "Returns all cookies visible to the specified browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ], + "returns": [ + { "name": "cookies", "type": "array", "items": { "$ref": "Cookie" }, "description": "Array of cookie objects." } + ], + "async": true + }, + { + "name": "deleteSingleCookie", + "description": "Deletes a cookie with the given name if visible to the specified browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }, + { "name": "cookieName", "type": "string", "description": "Name of the cookie to remove." } + ], + "async": true + }, + { + "name": "addSingleCookie", + "description": "Add a cookie to cookie storage for the specified browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." }, + { "name": "cookie", "$ref": "Cookie", "description": "The cookie that should be added to storage." } + ], + "async": true + }, + { + "name": "deleteAllCookies", + "description": "Delete all cookies that are visible to the specified browsing context.", + "parameters": [ + { "name": "browsingContextHandle", "$ref": "BrowsingContextHandle", "description": "The handle for the browsing context." } + ] + } + ] +} diff --git a/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp new file mode 100644 index 000000000..f748eeeee --- /dev/null +++ b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.cpp @@ -0,0 +1,951 @@ +/* + * Copyright (C) 2016, 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebAutomationSession.h" + +#include "APIAutomationSessionClient.h" +#include "AutomationProtocolObjects.h" +#include "WebAutomationSessionMacros.h" +#include "WebAutomationSessionMessages.h" +#include "WebAutomationSessionProxyMessages.h" +#include "WebCookieManagerProxy.h" +#include "WebInspectorProxy.h" +#include "WebProcessPool.h" +#include <JavaScriptCore/InspectorBackendDispatcher.h> +#include <JavaScriptCore/InspectorFrontendRouter.h> +#include <WebCore/URL.h> +#include <WebCore/UUID.h> +#include <algorithm> +#include <wtf/HashMap.h> +#include <wtf/Optional.h> +#include <wtf/text/StringConcatenate.h> + +using namespace Inspector; + +namespace WebKit { + +WebAutomationSession::WebAutomationSession() + : m_client(std::make_unique<API::AutomationSessionClient>()) + , m_frontendRouter(FrontendRouter::create()) + , m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef())) + , m_domainDispatcher(AutomationBackendDispatcher::create(m_backendDispatcher, this)) +{ +} + +WebAutomationSession::~WebAutomationSession() +{ + ASSERT(!m_client); + + if (m_processPool) + m_processPool->removeMessageReceiver(Messages::WebAutomationSession::messageReceiverName()); +} + +void WebAutomationSession::setClient(std::unique_ptr<API::AutomationSessionClient> client) +{ + m_client = WTFMove(client); +} + +void WebAutomationSession::setProcessPool(WebKit::WebProcessPool* processPool) +{ + if (m_processPool) + m_processPool->removeMessageReceiver(Messages::WebAutomationSession::messageReceiverName()); + + m_processPool = processPool; + + if (m_processPool) + m_processPool->addMessageReceiver(Messages::WebAutomationSession::messageReceiverName(), *this); +} + +// NOTE: this class could be split at some point to support local and remote automation sessions. +// For now, it only works with a remote automation driver over a RemoteInspector connection. + +#if ENABLE(REMOTE_INSPECTOR) + +// Inspector::RemoteAutomationTarget API + +void WebAutomationSession::dispatchMessageFromRemote(const String& message) +{ + m_backendDispatcher->dispatch(message); +} + +void WebAutomationSession::connect(Inspector::FrontendChannel* channel, bool isAutomaticConnection) +{ + UNUSED_PARAM(isAutomaticConnection); + + m_remoteChannel = channel; + m_frontendRouter->connectFrontend(channel); + + setIsPaired(true); +} + +void WebAutomationSession::disconnect(Inspector::FrontendChannel* channel) +{ + ASSERT(channel == m_remoteChannel); + terminate(); +} + +#endif // ENABLE(REMOTE_INSPECTOR) + +void WebAutomationSession::terminate() +{ +#if ENABLE(REMOTE_INSPECTOR) + if (Inspector::FrontendChannel* channel = m_remoteChannel) { + m_remoteChannel = nullptr; + m_frontendRouter->disconnectFrontend(channel); + } + + setIsPaired(false); +#endif + + if (m_client) + m_client->didDisconnectFromRemote(this); +} + +WebPageProxy* WebAutomationSession::webPageProxyForHandle(const String& handle) +{ + auto iter = m_handleWebPageMap.find(handle); + if (iter == m_handleWebPageMap.end()) + return nullptr; + return WebProcessProxy::webPage(iter->value); +} + +String WebAutomationSession::handleForWebPageProxy(const WebPageProxy& webPageProxy) +{ + auto iter = m_webPageHandleMap.find(webPageProxy.pageID()); + if (iter != m_webPageHandleMap.end()) + return iter->value; + + String handle = "page-" + WebCore::createCanonicalUUIDString().convertToASCIIUppercase(); + + auto firstAddResult = m_webPageHandleMap.add(webPageProxy.pageID(), handle); + RELEASE_ASSERT(firstAddResult.isNewEntry); + + auto secondAddResult = m_handleWebPageMap.add(handle, webPageProxy.pageID()); + RELEASE_ASSERT(secondAddResult.isNewEntry); + + return handle; +} + +std::optional<uint64_t> WebAutomationSession::webFrameIDForHandle(const String& handle) +{ + if (handle.isEmpty()) + return 0; + + auto iter = m_handleWebFrameMap.find(handle); + if (iter == m_handleWebFrameMap.end()) + return std::nullopt; + + return iter->value; +} + +String WebAutomationSession::handleForWebFrameID(uint64_t frameID) +{ + if (!frameID) + return emptyString(); + + for (auto& process : m_processPool->processes()) { + if (WebFrameProxy* frame = process->webFrame(frameID)) { + if (frame->isMainFrame()) + return emptyString(); + break; + } + } + + auto iter = m_webFrameHandleMap.find(frameID); + if (iter != m_webFrameHandleMap.end()) + return iter->value; + + String handle = "frame-" + WebCore::createCanonicalUUIDString().convertToASCIIUppercase(); + + auto firstAddResult = m_webFrameHandleMap.add(frameID, handle); + RELEASE_ASSERT(firstAddResult.isNewEntry); + + auto secondAddResult = m_handleWebFrameMap.add(handle, frameID); + RELEASE_ASSERT(secondAddResult.isNewEntry); + + return handle; +} + +String WebAutomationSession::handleForWebFrameProxy(const WebFrameProxy& webFrameProxy) +{ + return handleForWebFrameID(webFrameProxy.frameID()); +} + +RefPtr<Inspector::Protocol::Automation::BrowsingContext> WebAutomationSession::buildBrowsingContextForPage(WebPageProxy& page) +{ + WebCore::FloatRect windowFrame; + page.getWindowFrame(windowFrame); + + auto originObject = Inspector::Protocol::Automation::Point::create() + .setX(windowFrame.x()) + .setY(windowFrame.y()) + .release(); + + auto sizeObject = Inspector::Protocol::Automation::Size::create() + .setWidth(windowFrame.width()) + .setHeight(windowFrame.height()) + .release(); + + String handle = handleForWebPageProxy(page); + + return Inspector::Protocol::Automation::BrowsingContext::create() + .setHandle(handle) + .setActive(m_activeBrowsingContextHandle == handle) + .setUrl(page.pageLoadState().activeURL()) + .setWindowOrigin(WTFMove(originObject)) + .setWindowSize(WTFMove(sizeObject)) + .release(); +} + +// Platform-independent Commands. + +void WebAutomationSession::getBrowsingContexts(Inspector::ErrorString& errorString, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Automation::BrowsingContext>>& contexts) +{ + contexts = Inspector::Protocol::Array<Inspector::Protocol::Automation::BrowsingContext>::create(); + + for (auto& process : m_processPool->processes()) { + for (auto* page : process->pages()) { + ASSERT(page); + if (!page->isControlledByAutomation()) + continue; + + contexts->addItem(buildBrowsingContextForPage(*page)); + } + } +} + +void WebAutomationSession::getBrowsingContext(Inspector::ErrorString& errorString, const String& handle, RefPtr<Inspector::Protocol::Automation::BrowsingContext>& context) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + context = buildBrowsingContextForPage(*page); +} + +void WebAutomationSession::createBrowsingContext(Inspector::ErrorString& errorString, String* handle) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session could not request a new browsing context."); + + WebPageProxy* page = m_client->didRequestNewWindow(this); + if (!page) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "The remote session failed to create a new browsing context."); + + m_activeBrowsingContextHandle = *handle = handleForWebPageProxy(*page); +} + +void WebAutomationSession::closeBrowsingContext(Inspector::ErrorString& errorString, const String& handle) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (handle == m_activeBrowsingContextHandle) + m_activeBrowsingContextHandle = emptyString(); + + page->closePage(false); +} + +void WebAutomationSession::switchToBrowsingContext(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString()); + if (!frameID) + FAIL_WITH_PREDEFINED_ERROR(FrameNotFound); + + // FIXME: We don't need to track this in WK2. Remove in a follow up. + m_activeBrowsingContextHandle = browsingContextHandle; + + page->setFocus(true); + page->process().send(Messages::WebAutomationSessionProxy::FocusFrame(page->pageID(), frameID.value()), 0); +} + +void WebAutomationSession::navigateBrowsingContext(Inspector::ErrorString& errorString, const String& handle, const String& url, Ref<NavigateBrowsingContextCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID())) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout)); + m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback)); + + page->loadRequest(WebCore::URL(WebCore::URL(), url)); +} + +void WebAutomationSession::goBackInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<GoBackInBrowsingContextCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID())) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout)); + m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback)); + + page->goBack(); +} + +void WebAutomationSession::goForwardInBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<GoForwardInBrowsingContextCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID())) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout)); + m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback)); + + page->goForward(); +} + +void WebAutomationSession::reloadBrowsingContext(Inspector::ErrorString& errorString, const String& handle, Ref<ReloadBrowsingContextCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page->pageID())) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout)); + m_pendingNavigationInBrowsingContextCallbacksPerPage.set(page->pageID(), WTFMove(callback)); + + const bool reloadFromOrigin = false; + page->reload(reloadFromOrigin, { }); +} + +void WebAutomationSession::navigationOccurredForPage(const WebPageProxy& page) +{ + if (auto callback = m_pendingNavigationInBrowsingContextCallbacksPerPage.take(page.pageID())) + callback->sendSuccess(InspectorObject::create()); +} + +void WebAutomationSession::inspectorFrontendLoaded(const WebPageProxy& page) +{ + if (auto callback = m_pendingInspectorCallbacksPerPage.take(page.pageID())) + callback->sendSuccess(InspectorObject::create()); +} + +void WebAutomationSession::keyboardEventsFlushedForPage(const WebPageProxy& page) +{ + if (auto callback = m_pendingKeyboardEventsFlushedCallbacksPerPage.take(page.pageID())) + callback->sendSuccess(InspectorObject::create()); +} + +void WebAutomationSession::evaluateJavaScriptFunction(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<EvaluateJavaScriptFunctionCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString()); + if (!frameID) + FAIL_WITH_PREDEFINED_ERROR(FrameNotFound); + + Vector<String> argumentsVector; + argumentsVector.reserveCapacity(arguments.length()); + + for (auto& argument : arguments) { + String argumentString; + argument->asString(argumentString); + argumentsVector.uncheckedAppend(argumentString); + } + + bool expectsImplicitCallbackArgument = optionalExpectsImplicitCallbackArgument ? *optionalExpectsImplicitCallbackArgument : false; + int callbackTimeout = optionalCallbackTimeout ? *optionalCallbackTimeout : 0; + + uint64_t callbackID = m_nextEvaluateJavaScriptCallbackID++; + m_evaluateJavaScriptFunctionCallbacks.set(callbackID, WTFMove(callback)); + + page->process().send(Messages::WebAutomationSessionProxy::EvaluateJavaScriptFunction(page->pageID(), frameID.value(), function, argumentsVector, expectsImplicitCallbackArgument, callbackTimeout, callbackID), 0); +} + +void WebAutomationSession::didEvaluateJavaScriptFunction(uint64_t callbackID, const String& result, const String& errorType) +{ + auto callback = m_evaluateJavaScriptFunctionCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE_AND_DETAILS(errorType, result)); + else + callback->sendSuccess(result); +} + +void WebAutomationSession::resolveChildFrameHandle(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&& callback) +{ + if (!optionalOrdinal && !optionalName && !optionalNodeHandle) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "Command must specify a child frame by ordinal, name, or element handle."); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + std::optional<uint64_t> frameID = webFrameIDForHandle(optionalFrameHandle ? *optionalFrameHandle : emptyString()); + if (!frameID) + FAIL_WITH_PREDEFINED_ERROR(FrameNotFound); + + uint64_t callbackID = m_nextResolveFrameCallbackID++; + m_resolveChildFrameHandleCallbacks.set(callbackID, WTFMove(callback)); + + if (optionalNodeHandle) { + page->process().send(Messages::WebAutomationSessionProxy::ResolveChildFrameWithNodeHandle(page->pageID(), frameID.value(), *optionalNodeHandle, callbackID), 0); + return; + } + + if (optionalName) { + page->process().send(Messages::WebAutomationSessionProxy::ResolveChildFrameWithName(page->pageID(), frameID.value(), *optionalName, callbackID), 0); + return; + } + + if (optionalOrdinal) { + page->process().send(Messages::WebAutomationSessionProxy::ResolveChildFrameWithOrdinal(page->pageID(), frameID.value(), *optionalOrdinal, callbackID), 0); + return; + } + + ASSERT_NOT_REACHED(); +} + +void WebAutomationSession::didResolveChildFrame(uint64_t callbackID, uint64_t frameID, const String& errorType) +{ + auto callback = m_resolveChildFrameHandleCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + else + callback->sendSuccess(handleForWebFrameID(frameID)); +} + +void WebAutomationSession::resolveParentFrameHandle(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + std::optional<uint64_t> frameID = webFrameIDForHandle(frameHandle); + if (!frameID) + FAIL_WITH_PREDEFINED_ERROR(FrameNotFound); + + uint64_t callbackID = m_nextResolveParentFrameCallbackID++; + m_resolveParentFrameHandleCallbacks.set(callbackID, WTFMove(callback)); + + page->process().send(Messages::WebAutomationSessionProxy::ResolveParentFrame(page->pageID(), frameID.value(), callbackID), 0); +} + +void WebAutomationSession::didResolveParentFrame(uint64_t callbackID, uint64_t frameID, const String& errorType) +{ + auto callback = m_resolveParentFrameHandleCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + else + callback->sendSuccess(handleForWebFrameID(frameID)); +} + +void WebAutomationSession::computeElementLayout(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* optionalUseViewportCoordinates, Ref<ComputeElementLayoutCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + std::optional<uint64_t> frameID = webFrameIDForHandle(frameHandle); + if (!frameID) + FAIL_WITH_PREDEFINED_ERROR(FrameNotFound); + + uint64_t callbackID = m_nextComputeElementLayoutCallbackID++; + m_computeElementLayoutCallbacks.set(callbackID, WTFMove(callback)); + + bool scrollIntoViewIfNeeded = optionalScrollIntoViewIfNeeded ? *optionalScrollIntoViewIfNeeded : false; + bool useViewportCoordinates = optionalUseViewportCoordinates ? *optionalUseViewportCoordinates : false; + + page->process().send(Messages::WebAutomationSessionProxy::ComputeElementLayout(page->pageID(), frameID.value(), nodeHandle, scrollIntoViewIfNeeded, useViewportCoordinates, callbackID), 0); +} + +void WebAutomationSession::didComputeElementLayout(uint64_t callbackID, WebCore::IntRect rect, const String& errorType) +{ + auto callback = m_computeElementLayoutCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) { + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + return; + } + + auto originObject = Inspector::Protocol::Automation::Point::create() + .setX(rect.x()) + .setY(rect.y()) + .release(); + + auto sizeObject = Inspector::Protocol::Automation::Size::create() + .setWidth(rect.width()) + .setHeight(rect.height()) + .release(); + + auto rectObject = Inspector::Protocol::Automation::Rect::create() + .setOrigin(WTFMove(originObject)) + .setSize(WTFMove(sizeObject)) + .release(); + + callback->sendSuccess(WTFMove(rectObject)); +} + +void WebAutomationSession::isShowingJavaScriptDialog(Inspector::ErrorString& errorString, const String& browsingContextHandle, bool* result) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR(InternalError); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + *result = m_client->isShowingJavaScriptDialogOnPage(this, page); +} + +void WebAutomationSession::dismissCurrentJavaScriptDialog(Inspector::ErrorString& errorString, const String& browsingContextHandle) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR(InternalError); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (!m_client->isShowingJavaScriptDialogOnPage(this, page)) + FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog); + + m_client->dismissCurrentJavaScriptDialogOnPage(this, page); +} + +void WebAutomationSession::acceptCurrentJavaScriptDialog(Inspector::ErrorString& errorString, const String& browsingContextHandle) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR(InternalError); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (!m_client->isShowingJavaScriptDialogOnPage(this, page)) + FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog); + + m_client->acceptCurrentJavaScriptDialogOnPage(this, page); +} + +void WebAutomationSession::messageOfCurrentJavaScriptDialog(Inspector::ErrorString& errorString, const String& browsingContextHandle, String* text) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR(InternalError); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (!m_client->isShowingJavaScriptDialogOnPage(this, page)) + FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog); + + *text = m_client->messageOfCurrentJavaScriptDialogOnPage(this, page); +} + +void WebAutomationSession::setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString& errorString, const String& browsingContextHandle, const String& promptValue) +{ + ASSERT(m_client); + if (!m_client) + FAIL_WITH_PREDEFINED_ERROR(InternalError); + + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (!m_client->isShowingJavaScriptDialogOnPage(this, page)) + FAIL_WITH_PREDEFINED_ERROR(NoJavaScriptDialog); + + m_client->setUserInputForCurrentJavaScriptPromptOnPage(this, page, promptValue); +} + +void WebAutomationSession::getAllCookies(ErrorString& errorString, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + // Always send the main frame ID as 0 so it is resolved on the WebProcess side. This avoids a race when page->mainFrame() is null still. + const uint64_t mainFrameID = 0; + + uint64_t callbackID = m_nextGetCookiesCallbackID++; + m_getCookieCallbacks.set(callbackID, WTFMove(callback)); + + page->process().send(Messages::WebAutomationSessionProxy::GetCookiesForFrame(page->pageID(), mainFrameID, callbackID), 0); +} + +static Ref<Inspector::Protocol::Automation::Cookie> buildObjectForCookie(const WebCore::Cookie& cookie) +{ + return Inspector::Protocol::Automation::Cookie::create() + .setName(cookie.name) + .setValue(cookie.value) + .setDomain(cookie.domain) + .setPath(cookie.path) + .setExpires(cookie.expires) + .setSize((cookie.name.length() + cookie.value.length())) + .setHttpOnly(cookie.httpOnly) + .setSecure(cookie.secure) + .setSession(cookie.session) + .release(); +} + +static Ref<Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>> buildArrayForCookies(Vector<WebCore::Cookie>& cookiesList) +{ + auto cookies = Inspector::Protocol::Array<Inspector::Protocol::Automation::Cookie>::create(); + + for (const auto& cookie : cookiesList) + cookies->addItem(buildObjectForCookie(cookie)); + + return cookies; +} + +void WebAutomationSession::didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, const String& errorType) +{ + auto callback = m_getCookieCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) { + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + return; + } + + callback->sendSuccess(buildArrayForCookies(cookies)); +} + +void WebAutomationSession::deleteSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + // Always send the main frame ID as 0 so it is resolved on the WebProcess side. This avoids a race when page->mainFrame() is null still. + const uint64_t mainFrameID = 0; + + uint64_t callbackID = m_nextDeleteCookieCallbackID++; + m_deleteCookieCallbacks.set(callbackID, WTFMove(callback)); + + page->process().send(Messages::WebAutomationSessionProxy::DeleteCookie(page->pageID(), mainFrameID, cookieName, callbackID), 0); +} + +void WebAutomationSession::didDeleteCookie(uint64_t callbackID, const String& errorType) +{ + auto callback = m_deleteCookieCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) { + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + return; + } + + callback->sendSuccess(); +} + +void WebAutomationSession::addSingleCookie(ErrorString& errorString, const String& browsingContextHandle, const Inspector::InspectorObject& cookieObject, Ref<AddSingleCookieCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL()); + ASSERT(activeURL.isValid()); + + WebCore::Cookie cookie; + + if (!cookieObject.getString(WTF::ASCIILiteral("name"), cookie.name)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'name' was not found."); + + if (!cookieObject.getString(WTF::ASCIILiteral("value"), cookie.value)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'value' was not found."); + + String domain; + if (!cookieObject.getString(WTF::ASCIILiteral("domain"), domain)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'domain' was not found."); + + // Inherit the domain/host from the main frame's URL if it is not explicitly set. + if (domain.isEmpty()) + domain = activeURL.host(); + + cookie.domain = domain; + + if (!cookieObject.getString(WTF::ASCIILiteral("path"), cookie.path)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'path' was not found."); + + double expires; + if (!cookieObject.getDouble(WTF::ASCIILiteral("expires"), expires)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'expires' was not found."); + + cookie.expires = expires * 1000.0; + + if (!cookieObject.getBoolean(WTF::ASCIILiteral("secure"), cookie.secure)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'secure' was not found."); + + if (!cookieObject.getBoolean(WTF::ASCIILiteral("session"), cookie.session)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'session' was not found."); + + if (!cookieObject.getBoolean(WTF::ASCIILiteral("httpOnly"), cookie.httpOnly)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'httpOnly' was not found."); + + WebCookieManagerProxy* cookieManager = m_processPool->supplement<WebCookieManagerProxy>(); + cookieManager->addCookie(WebCore::SessionID::defaultSessionID(), cookie, activeURL.host()); + + callback->sendSuccess(); +} + +void WebAutomationSession::deleteAllCookies(ErrorString& errorString, const String& browsingContextHandle) +{ + WebPageProxy* page = webPageProxyForHandle(browsingContextHandle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + WebCore::URL activeURL = WebCore::URL(WebCore::URL(), page->pageLoadState().activeURL()); + ASSERT(activeURL.isValid()); + + WebCookieManagerProxy* cookieManager = m_processPool->supplement<WebCookieManagerProxy>(); + cookieManager->deleteCookiesForHostname(WebCore::SessionID::defaultSessionID(), activeURL.host()); +} + +#if USE(APPKIT) +static WebEvent::Modifiers protocolModifierToWebEventModifier(Inspector::Protocol::Automation::KeyModifier modifier) +{ + switch (modifier) { + case Inspector::Protocol::Automation::KeyModifier::Alt: + return WebEvent::AltKey; + case Inspector::Protocol::Automation::KeyModifier::Meta: + return WebEvent::MetaKey; + case Inspector::Protocol::Automation::KeyModifier::Control: + return WebEvent::ControlKey; + case Inspector::Protocol::Automation::KeyModifier::Shift: + return WebEvent::ShiftKey; + case Inspector::Protocol::Automation::KeyModifier::CapsLock: + return WebEvent::CapsLockKey; + } +} +#endif // USE(APPKIT) + +void WebAutomationSession::performMouseInteraction(Inspector::ErrorString& errorString, const String& handle, const Inspector::InspectorObject& requestedPositionObject, const String& mouseButtonString, const String& mouseInteractionString, const Inspector::InspectorArray& keyModifierStrings, RefPtr<Inspector::Protocol::Automation::Point>& updatedPositionObject) +{ +#if !USE(APPKIT) + FAIL_WITH_PREDEFINED_ERROR(NotImplemented); +#else + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + float x; + if (!requestedPositionObject.getDouble(WTF::ASCIILiteral("x"), x)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'x' was not found."); + + float y; + if (!requestedPositionObject.getDouble(WTF::ASCIILiteral("y"), y)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "The parameter 'y' was not found."); + + WebCore::FloatRect windowFrame; + page->getWindowFrame(windowFrame); + + x = std::min(std::max(0.0f, x), windowFrame.size().width()); + y = std::min(std::max(0.0f, y + page->topContentInset()), windowFrame.size().height()); + + WebCore::IntPoint viewPosition = WebCore::IntPoint(static_cast<int>(x), static_cast<int>(y)); + + auto parsedInteraction = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::MouseInteraction>(mouseInteractionString); + if (!parsedInteraction) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'interaction' is invalid."); + + auto parsedButton = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::MouseButton>(mouseButtonString); + if (!parsedButton) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'button' is invalid."); + + WebEvent::Modifiers keyModifiers = (WebEvent::Modifiers)0; + for (auto it = keyModifierStrings.begin(); it != keyModifierStrings.end(); ++it) { + String modifierString; + if (!it->get()->asString(modifierString)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'modifiers' is invalid."); + + auto parsedModifier = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::KeyModifier>(modifierString); + if (!parsedModifier) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "A modifier in the 'modifiers' array is invalid."); + WebEvent::Modifiers enumValue = protocolModifierToWebEventModifier(parsedModifier.value()); + keyModifiers = (WebEvent::Modifiers)(enumValue | keyModifiers); + } + + platformSimulateMouseInteraction(*page, viewPosition, parsedInteraction.value(), parsedButton.value(), keyModifiers); + + updatedPositionObject = Inspector::Protocol::Automation::Point::create() + .setX(x) + .setY(y - page->topContentInset()) + .release(); +#endif // USE(APPKIT) +} + +void WebAutomationSession::performKeyboardInteractions(ErrorString& errorString, const String& handle, const Inspector::InspectorArray& interactions, Ref<PerformKeyboardInteractionsCallback>&& callback) +{ +#if !USE(APPKIT) + FAIL_WITH_PREDEFINED_ERROR(NotImplemented); +#else + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + if (!interactions.length()) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "The parameter 'interactions' was not found or empty."); + + // Validate all of the parameters before performing any interactions with the browsing context under test. + Vector<std::function<void()>> actionsToPerform; + actionsToPerform.reserveCapacity(interactions.length()); + + for (auto interaction : interactions) { + RefPtr<InspectorObject> interactionObject; + if (!interaction->asObject(interactionObject)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter was invalid."); + + String interactionTypeString; + if (!interactionObject->getString(ASCIILiteral("type"), interactionTypeString)) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter is missing the 'type' key."); + auto interactionType = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::KeyboardInteractionType>(interactionTypeString); + if (!interactionType) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'type' key."); + + String virtualKeyString; + bool foundVirtualKey = interactionObject->getString(ASCIILiteral("key"), virtualKeyString); + if (foundVirtualKey) { + auto virtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(virtualKeyString); + if (!virtualKey) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value."); + + actionsToPerform.uncheckedAppend([this, page, interactionType, virtualKey] { + platformSimulateKeyStroke(*page, interactionType.value(), virtualKey.value()); + }); + } + + String keySequence; + bool foundKeySequence = interactionObject->getString(ASCIILiteral("text"), keySequence); + if (foundKeySequence) { + switch (interactionType.value()) { + case Inspector::Protocol::Automation::KeyboardInteractionType::KeyPress: + case Inspector::Protocol::Automation::KeyboardInteractionType::KeyRelease: + // 'KeyPress' and 'KeyRelease' are meant for a virtual key and are not supported for a string (sequence of codepoints). + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value."); + + case Inspector::Protocol::Automation::KeyboardInteractionType::InsertByKey: + actionsToPerform.uncheckedAppend([this, page, keySequence] { + platformSimulateKeySequence(*page, keySequence); + }); + break; + } + } + + if (!foundVirtualKey && !foundKeySequence) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(MissingParameter, "An interaction in the 'interactions' parameter is missing both 'key' and 'text'. One must be provided."); + } + + ASSERT(actionsToPerform.size()); + if (!actionsToPerform.size()) + FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InternalError, "No actions to perform."); + + auto& callbackInMap = m_pendingKeyboardEventsFlushedCallbacksPerPage.add(page->pageID(), nullptr).iterator->value; + if (callbackInMap) + callbackInMap->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(Timeout)); + callbackInMap = WTFMove(callback); + + for (auto& action : actionsToPerform) + action(); +#endif // USE(APPKIT) +} + +void WebAutomationSession::takeScreenshot(ErrorString& errorString, const String& handle, Ref<TakeScreenshotCallback>&& callback) +{ + WebPageProxy* page = webPageProxyForHandle(handle); + if (!page) + FAIL_WITH_PREDEFINED_ERROR(WindowNotFound); + + uint64_t callbackID = m_nextScreenshotCallbackID++; + m_screenshotCallbacks.set(callbackID, WTFMove(callback)); + + page->process().send(Messages::WebAutomationSessionProxy::TakeScreenshot(page->pageID(), callbackID), 0); +} + +void WebAutomationSession::didTakeScreenshot(uint64_t callbackID, const ShareableBitmap::Handle& imageDataHandle, const String& errorType) +{ + auto callback = m_screenshotCallbacks.take(callbackID); + if (!callback) + return; + + if (!errorType.isEmpty()) { + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorType)); + return; + } + + std::optional<String> base64EncodedData = platformGetBase64EncodedPNGData(imageDataHandle); + if (!base64EncodedData) { + callback->sendFailure(STRING_FOR_PREDEFINED_ERROR_NAME(InternalError)); + return; + } + + callback->sendSuccess(base64EncodedData.value()); +} + +// Platform-dependent Implementation Stubs. + +#if !PLATFORM(MAC) +void WebAutomationSession::platformSimulateMouseInteraction(WebKit::WebPageProxy&, const WebCore::IntPoint&, Inspector::Protocol::Automation::MouseInteraction, Inspector::Protocol::Automation::MouseButton, WebEvent::Modifiers) +{ +} + +void WebAutomationSession::platformSimulateKeyStroke(WebPageProxy&, Inspector::Protocol::Automation::KeyboardInteractionType, Inspector::Protocol::Automation::VirtualKey) +{ +} + +void WebAutomationSession::platformSimulateKeySequence(WebPageProxy&, const String&) +{ +} +#endif // !PLATFORM(MAC) + +#if !PLATFORM(COCOA) +std::optional<String> WebAutomationSession::platformGetBase64EncodedPNGData(const ShareableBitmap::Handle&) +{ + return String(); +} +#endif // !PLATFORM(COCOA) + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h new file mode 100644 index 000000000..cd2d0b8af --- /dev/null +++ b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2016, 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIObject.h" +#include "AutomationBackendDispatchers.h" +#include "Connection.h" +#include "ShareableBitmap.h" +#include "WebEvent.h" +#include <wtf/Forward.h> + +#if ENABLE(REMOTE_INSPECTOR) +#include <JavaScriptCore/RemoteAutomationTarget.h> +#endif + +namespace API { +class AutomationSessionClient; +} + +namespace Inspector { +class BackendDispatcher; +class FrontendRouter; +} + +namespace WebCore { +class IntPoint; +class IntRect; + +struct Cookie; +} + +#if USE(APPKIT) +OBJC_CLASS NSArray; +OBJC_CLASS NSEvent; +#endif + +namespace WebKit { + +class WebAutomationSessionClient; +class WebFrameProxy; +class WebPageProxy; +class WebProcessPool; + +class WebAutomationSession final : public API::ObjectImpl<API::Object::Type::AutomationSession>, public IPC::MessageReceiver +#if ENABLE(REMOTE_INSPECTOR) + , public Inspector::RemoteAutomationTarget +#endif + , public Inspector::AutomationBackendDispatcherHandler +{ +public: + WebAutomationSession(); + ~WebAutomationSession(); + + void setClient(std::unique_ptr<API::AutomationSessionClient>); + + void setSessionIdentifier(const String& sessionIdentifier) { m_sessionIdentifier = sessionIdentifier; } + String sessionIdentifier() const { return m_sessionIdentifier; } + + WebProcessPool* processPool() const { return m_processPool; } + void setProcessPool(WebProcessPool*); + + void navigationOccurredForPage(const WebPageProxy&); + void inspectorFrontendLoaded(const WebPageProxy&); + void keyboardEventsFlushedForPage(const WebPageProxy&); + +#if ENABLE(REMOTE_INSPECTOR) + // Inspector::RemoteAutomationTarget API + String name() const override { return m_sessionIdentifier; } + void dispatchMessageFromRemote(const String& message) override; + void connect(Inspector::FrontendChannel*, bool isAutomaticConnection = false) override; + void disconnect(Inspector::FrontendChannel*) override; +#endif + void terminate(); + + // Inspector::AutomationBackendDispatcherHandler API + // NOTE: the set of declarations included in this interface depend on the "platform" property in Automation.json + // and the --platform argument passed to the protocol bindings generator. + + // Platform: Generic + void getBrowsingContexts(Inspector::ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Automation::BrowsingContext>>&) override; + void getBrowsingContext(Inspector::ErrorString&, const String&, RefPtr<Inspector::Protocol::Automation::BrowsingContext>&) override; + void createBrowsingContext(Inspector::ErrorString&, String*) override; + void closeBrowsingContext(Inspector::ErrorString&, const String&) override; + void switchToBrowsingContext(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle) override; + void navigateBrowsingContext(Inspector::ErrorString&, const String& handle, const String& url, Ref<NavigateBrowsingContextCallback>&&) override; + void goBackInBrowsingContext(Inspector::ErrorString&, const String&, Ref<GoBackInBrowsingContextCallback>&&) override; + void goForwardInBrowsingContext(Inspector::ErrorString&, const String&, Ref<GoForwardInBrowsingContextCallback>&&) override; + void reloadBrowsingContext(Inspector::ErrorString&, const String&, Ref<ReloadBrowsingContextCallback>&&) override; + void evaluateJavaScriptFunction(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const String& function, const Inspector::InspectorArray& arguments, const bool* optionalExpectsImplicitCallbackArgument, const int* optionalCallbackTimeout, Ref<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>&&) override; + void performMouseInteraction(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& requestedPosition, const String& mouseButton, const String& mouseInteraction, const Inspector::InspectorArray& keyModifiers, RefPtr<Inspector::Protocol::Automation::Point>& updatedPosition) override; + void performKeyboardInteractions(Inspector::ErrorString&, const String& handle, const Inspector::InspectorArray& interactions, Ref<PerformKeyboardInteractionsCallback>&&) override; + void takeScreenshot(Inspector::ErrorString&, const String& handle, Ref<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>&&) override; + void resolveChildFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String* optionalFrameHandle, const int* optionalOrdinal, const String* optionalName, const String* optionalNodeHandle, Ref<ResolveChildFrameHandleCallback>&&) override; + void resolveParentFrameHandle(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, Ref<ResolveParentFrameHandleCallback>&&) override; + void computeElementLayout(Inspector::ErrorString&, const String& browsingContextHandle, const String& frameHandle, const String& nodeHandle, const bool* optionalScrollIntoViewIfNeeded, const bool* useViewportCoordinates, Ref<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>&&) override; + void isShowingJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, bool* result) override; + void dismissCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override; + void acceptCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle) override; + void messageOfCurrentJavaScriptDialog(Inspector::ErrorString&, const String& browsingContextHandle, String* text) override; + void setUserInputForCurrentJavaScriptPrompt(Inspector::ErrorString&, const String& browsingContextHandle, const String& text) override; + void getAllCookies(Inspector::ErrorString&, const String& browsingContextHandle, Ref<GetAllCookiesCallback>&&) override; + void deleteSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const String& cookieName, Ref<DeleteSingleCookieCallback>&&) override; + void addSingleCookie(Inspector::ErrorString&, const String& browsingContextHandle, const Inspector::InspectorObject& cookie, Ref<AddSingleCookieCallback>&&) override; + void deleteAllCookies(Inspector::ErrorString&, const String& browsingContextHandle) override; + + // Platform: macOS +#if PLATFORM(MAC) + void resizeWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& size) override; + void moveWindowOfBrowsingContext(Inspector::ErrorString&, const String& handle, const Inspector::InspectorObject& position) override; + void inspectBrowsingContext(Inspector::ErrorString&, const String&, const bool* optionalEnableAutoCapturing, Ref<InspectBrowsingContextCallback>&&) override; +#endif + + // Event Simulation Support. +#if PLATFORM(MAC) + bool wasEventSynthesizedForAutomation(NSEvent *); + void markEventAsSynthesizedForAutomation(NSEvent *); +#endif + +private: + WebPageProxy* webPageProxyForHandle(const String&); + String handleForWebPageProxy(const WebPageProxy&); + RefPtr<Inspector::Protocol::Automation::BrowsingContext> buildBrowsingContextForPage(WebPageProxy&); + + std::optional<uint64_t> webFrameIDForHandle(const String&); + String handleForWebFrameID(uint64_t frameID); + String handleForWebFrameProxy(const WebFrameProxy&); + + // Implemented in generated WebAutomationSessionMessageReceiver.cpp. + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + + // Called by WebAutomationSession messages. + void didEvaluateJavaScriptFunction(uint64_t callbackID, const String& result, const String& errorType); + void didResolveChildFrame(uint64_t callbackID, uint64_t frameID, const String& errorType); + void didResolveParentFrame(uint64_t callbackID, uint64_t frameID, const String& errorType); + void didComputeElementLayout(uint64_t callbackID, WebCore::IntRect, const String& errorType); + void didTakeScreenshot(uint64_t callbackID, const ShareableBitmap::Handle&, const String& errorType); + void didGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie>, const String& errorType); + void didDeleteCookie(uint64_t callbackID, const String& errorType); + + // Platform-dependent implementations. + void platformSimulateMouseInteraction(WebPageProxy&, const WebCore::IntPoint& viewPosition, Inspector::Protocol::Automation::MouseInteraction, Inspector::Protocol::Automation::MouseButton, WebEvent::Modifiers); + // Simulates a single virtual key being pressed, such as Control, F-keys, Numpad keys, etc. as allowed by the protocol. + void platformSimulateKeyStroke(WebPageProxy&, Inspector::Protocol::Automation::KeyboardInteractionType, Inspector::Protocol::Automation::VirtualKey); + // Simulates key presses to produce the codepoints in a string. One or more code points are delivered atomically at grapheme cluster boundaries. + void platformSimulateKeySequence(WebPageProxy&, const String&); + // Get base64 encoded PNG data from a bitmap. + std::optional<String> platformGetBase64EncodedPNGData(const ShareableBitmap::Handle&); + +#if PLATFORM(MAC) + void sendSynthesizedEventsToPage(WebPageProxy&, NSArray *eventsToSend); +#endif + + WebProcessPool* m_processPool { nullptr }; + + std::unique_ptr<API::AutomationSessionClient> m_client; + String m_sessionIdentifier { ASCIILiteral("Untitled Session") }; + Ref<Inspector::FrontendRouter> m_frontendRouter; + Ref<Inspector::BackendDispatcher> m_backendDispatcher; + Ref<Inspector::AutomationBackendDispatcher> m_domainDispatcher; + + HashMap<uint64_t, String> m_webPageHandleMap; + HashMap<String, uint64_t> m_handleWebPageMap; + String m_activeBrowsingContextHandle; + + HashMap<uint64_t, String> m_webFrameHandleMap; + HashMap<String, uint64_t> m_handleWebFrameMap; + + HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingNavigationInBrowsingContextCallbacksPerPage; + HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingInspectorCallbacksPerPage; + HashMap<uint64_t, RefPtr<Inspector::BackendDispatcher::CallbackBase>> m_pendingKeyboardEventsFlushedCallbacksPerPage; + + uint64_t m_nextEvaluateJavaScriptCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::EvaluateJavaScriptFunctionCallback>> m_evaluateJavaScriptFunctionCallbacks; + + uint64_t m_nextResolveFrameCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::ResolveChildFrameHandleCallback>> m_resolveChildFrameHandleCallbacks; + + uint64_t m_nextResolveParentFrameCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::ResolveParentFrameHandleCallback>> m_resolveParentFrameHandleCallbacks; + + uint64_t m_nextComputeElementLayoutCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::ComputeElementLayoutCallback>> m_computeElementLayoutCallbacks; + + uint64_t m_nextScreenshotCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::TakeScreenshotCallback>> m_screenshotCallbacks; + + uint64_t m_nextGetCookiesCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::GetAllCookiesCallback>> m_getCookieCallbacks; + + uint64_t m_nextDeleteCookieCallbackID { 1 }; + HashMap<uint64_t, RefPtr<Inspector::AutomationBackendDispatcherHandler::DeleteSingleCookieCallback>> m_deleteCookieCallbacks; + +#if ENABLE(REMOTE_INSPECTOR) + Inspector::FrontendChannel* m_remoteChannel { nullptr }; +#endif +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in new file mode 100644 index 000000000..cb4d56288 --- /dev/null +++ b/Source/WebKit2/UIProcess/Automation/WebAutomationSession.messages.in @@ -0,0 +1,35 @@ +# Copyright (C) 2016 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +messages -> WebAutomationSession { + DidEvaluateJavaScriptFunction(uint64_t callbackID, String result, String errorType) + + DidResolveChildFrame(uint64_t callbackID, uint64_t frameID, String errorType) + DidResolveParentFrame(uint64_t callbackID, uint64_t frameID, String errorType) + + DidComputeElementLayout(uint64_t callbackID, WebCore::IntRect rect, String errorType) + + DidTakeScreenshot(uint64_t callbackID, WebKit::ShareableBitmap::Handle imageDataHandle, String errorType) + + DidGetCookiesForFrame(uint64_t callbackID, Vector<WebCore::Cookie> cookies, String errorType) + DidDeleteCookie(uint64_t callbackID, String errorType) +} diff --git a/Source/WebKit2/UIProcess/Automation/WebAutomationSessionMacros.h b/Source/WebKit2/UIProcess/Automation/WebAutomationSessionMacros.h new file mode 100644 index 000000000..d6398769c --- /dev/null +++ b/Source/WebKit2/UIProcess/Automation/WebAutomationSessionMacros.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#define errorNameAndDetailsSeparator ";" + +// Make sure the predefined error name is valid, otherwise use InternalError. +#define VALIDATED_ERROR_MESSAGE(errorString) Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::ErrorMessage>(errorString).value_or(Inspector::Protocol::Automation::ErrorMessage::InternalError) + +// If the error name is incorrect for these macros, it will be a compile-time error. +#define STRING_FOR_PREDEFINED_ERROR_NAME(errorName) Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::errorName) +#define STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(errorName, detailsString) makeString(Inspector::Protocol::AutomationHelpers::getEnumConstantValue(Inspector::Protocol::Automation::ErrorMessage::errorName), errorNameAndDetailsSeparator, detailsString) + +// If the error message is not a predefined error, InternalError will be used instead. +#define STRING_FOR_PREDEFINED_ERROR_MESSAGE(errorMessage) Inspector::Protocol::AutomationHelpers::getEnumConstantValue(VALIDATED_ERROR_MESSAGE(errorMessage)) +#define STRING_FOR_PREDEFINED_ERROR_MESSAGE_AND_DETAILS(errorMessage, detailsString) makeString(Inspector::Protocol::AutomationHelpers::getEnumConstantValue(VALIDATED_ERROR_MESSAGE(errorMessage)), errorNameAndDetailsSeparator, detailsString) + +// Convenience macros for filling in the error string of synchronous commands in bailout branches. +#define FAIL_WITH_PREDEFINED_ERROR(errorName) \ +do { \ + errorString = STRING_FOR_PREDEFINED_ERROR_NAME(errorName); \ + return; \ +} while (false) + +#define FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(errorName, detailsString) \ +do { \ + errorString = STRING_FOR_PREDEFINED_ERROR_NAME_AND_DETAILS(errorName, detailsString); \ + return; \ +} while (false) diff --git a/Source/WebKit2/UIProcess/BackingStore.cpp b/Source/WebKit2/UIProcess/BackingStore.cpp index aae29858c..f90d91cff 100644 --- a/Source/WebKit2/UIProcess/BackingStore.cpp +++ b/Source/WebKit2/UIProcess/BackingStore.cpp @@ -33,7 +33,7 @@ using namespace WebCore; namespace WebKit { -BackingStore::BackingStore(const IntSize& size, float deviceScaleFactor, WebPageProxy* webPageProxy) +BackingStore::BackingStore(const IntSize& size, float deviceScaleFactor, WebPageProxy& webPageProxy) : m_size(size) , m_deviceScaleFactor(deviceScaleFactor) , m_webPageProxy(webPageProxy) diff --git a/Source/WebKit2/UIProcess/BackingStore.h b/Source/WebKit2/UIProcess/BackingStore.h index 0a9fe9a6f..14de1f424 100644 --- a/Source/WebKit2/UIProcess/BackingStore.h +++ b/Source/WebKit2/UIProcess/BackingStore.h @@ -30,8 +30,7 @@ #include <wtf/Noncopyable.h> #if USE(CAIRO) -#include <RefPtrCairo.h> -#include <WebCore/WidgetBackingStore.h> +#include <WebCore/BackingStoreBackendCairo.h> #endif namespace WebKit { @@ -44,7 +43,7 @@ class BackingStore { WTF_MAKE_NONCOPYABLE(BackingStore); public: - BackingStore(const WebCore::IntSize&, float deviceScaleFactor, WebPageProxy*); + BackingStore(const WebCore::IntSize&, float deviceScaleFactor, WebPageProxy&); ~BackingStore(); const WebCore::IntSize& size() const { return m_size; } @@ -61,12 +60,15 @@ private: void incorporateUpdate(ShareableBitmap*, const UpdateInfo&); void scroll(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); +#if USE(CAIRO) + std::unique_ptr<WebCore::BackingStoreBackendCairo> createBackend(); +#endif + WebCore::IntSize m_size; float m_deviceScaleFactor; - WebPageProxy* m_webPageProxy; - + WebPageProxy& m_webPageProxy; #if USE(CAIRO) - OwnPtr<WebCore::WidgetBackingStore> m_backingStore; + std::unique_ptr<WebCore::BackingStoreBackendCairo> m_backend; #endif }; diff --git a/Source/WebKit2/UIProcess/ChildProcessProxy.cpp b/Source/WebKit2/UIProcess/ChildProcessProxy.cpp new file mode 100644 index 000000000..dd8aef550 --- /dev/null +++ b/Source/WebKit2/UIProcess/ChildProcessProxy.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ChildProcessProxy.h" + +#include "ChildProcessMessages.h" +#include <wtf/RunLoop.h> + +namespace WebKit { + +ChildProcessProxy::ChildProcessProxy(bool alwaysRunsAtBackgroundPriority) + : m_alwaysRunsAtBackgroundPriority(alwaysRunsAtBackgroundPriority) +{ +} + +ChildProcessProxy::~ChildProcessProxy() +{ + if (m_connection) + m_connection->invalidate(); + + if (m_processLauncher) { + m_processLauncher->invalidate(); + m_processLauncher = nullptr; + } +} + +void ChildProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) +{ + if (const char* userDirectorySuffix = getenv("DIRHELPER_USER_DIR_SUFFIX")) + launchOptions.extraInitializationData.add(ASCIILiteral("user-directory-suffix"), userDirectorySuffix); + + if (m_alwaysRunsAtBackgroundPriority) + launchOptions.extraInitializationData.add(ASCIILiteral("always-runs-at-background-priority"), "true"); + +#if ENABLE(DEVELOPER_MODE) && PLATFORM(GTK) + const char* varname; + switch (launchOptions.processType) { + case ProcessLauncher::ProcessType::Web: + varname = "WEB_PROCESS_CMD_PREFIX"; + break; +#if ENABLE(NETSCAPE_PLUGIN_API) + case ProcessLauncher::ProcessType::Plugin64: + case ProcessLauncher::ProcessType::Plugin32: + varname = "PLUGIN_PROCESS_CMD_PREFIX"; + break; +#endif + case ProcessLauncher::ProcessType::Network: + varname = "NETWORK_PROCESS_CMD_PREFIX"; + break; +#if ENABLE(DATABASE_PROCESS) + case ProcessLauncher::ProcessType::Database: + varname = "DATABASE_PROCESS_CMD_PREFIX"; + break; +#endif + } + const char* processCmdPrefix = getenv(varname); + if (processCmdPrefix && *processCmdPrefix) + launchOptions.processCmdPrefix = String::fromUTF8(processCmdPrefix); +#endif // ENABLE(DEVELOPER_MODE) && PLATFORM(GTK) +} + +void ChildProcessProxy::connect() +{ + ASSERT(!m_processLauncher); + ProcessLauncher::LaunchOptions launchOptions; + getLaunchOptions(launchOptions); + m_processLauncher = ProcessLauncher::create(this, launchOptions); +} + +void ChildProcessProxy::terminate() +{ +#if PLATFORM(COCOA) + if (m_connection && m_connection->kill()) + return; +#endif + + // FIXME: We should really merge process launching into IPC connection creation and get rid of the process launcher. + if (m_processLauncher) + m_processLauncher->terminateProcess(); +} + +ChildProcessProxy::State ChildProcessProxy::state() const +{ + if (m_processLauncher && m_processLauncher->isLaunching()) + return ChildProcessProxy::State::Launching; + + if (!m_connection) + return ChildProcessProxy::State::Terminated; + + return ChildProcessProxy::State::Running; +} + +bool ChildProcessProxy::sendMessage(std::unique_ptr<IPC::Encoder> encoder, OptionSet<IPC::SendOption> sendOptions) +{ + switch (state()) { + case State::Launching: + // If we're waiting for the child process to launch, we need to stash away the messages so we can send them once we have a connection. + m_pendingMessages.append(std::make_pair(WTFMove(encoder), sendOptions)); + return true; + + case State::Running: + return connection()->sendMessage(WTFMove(encoder), sendOptions); + + case State::Terminated: + return false; + } + + return false; +} + +void ChildProcessProxy::addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver& messageReceiver) +{ + m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver); +} + +void ChildProcessProxy::addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver& messageReceiver) +{ + m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver); +} + +void ChildProcessProxy::removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID) +{ + m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID); +} + +void ChildProcessProxy::removeMessageReceiver(IPC::StringReference messageReceiverName) +{ + m_messageReceiverMap.removeMessageReceiver(messageReceiverName); +} + +bool ChildProcessProxy::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder) +{ + return m_messageReceiverMap.dispatchMessage(connection, decoder); +} + +bool ChildProcessProxy::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) +{ + return m_messageReceiverMap.dispatchSyncMessage(connection, decoder, replyEncoder); +} + +void ChildProcessProxy::didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier connectionIdentifier) +{ + ASSERT(!m_connection); + + if (IPC::Connection::identifierIsNull(connectionIdentifier)) + return; + + m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this); +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 + m_connection->setShouldCloseConnectionOnMachExceptions(); +#endif + + connectionWillOpen(*m_connection); + m_connection->open(); + + for (size_t i = 0; i < m_pendingMessages.size(); ++i) { + std::unique_ptr<IPC::Encoder> message = WTFMove(m_pendingMessages[i].first); + OptionSet<IPC::SendOption> sendOptions = m_pendingMessages[i].second; + m_connection->sendMessage(WTFMove(message), sendOptions); + } + + m_pendingMessages.clear(); +} + +void ChildProcessProxy::shutDownProcess() +{ + switch (state()) { + case State::Launching: + m_processLauncher->invalidate(); + m_processLauncher = nullptr; + break; + case State::Running: +#if PLATFORM(IOS) + // On iOS deploy a watchdog in the UI process, since the child process may be suspended. + // If 30s is insufficient for any outstanding activity to complete cleanly, then it will be killed. + ASSERT(m_connection); + m_connection->terminateSoon(30); +#endif + break; + case State::Terminated: + return; + } + + if (!m_connection) + return; + + processWillShutDown(*m_connection); + + if (canSendMessage()) + send(Messages::ChildProcess::ShutDown(), 0); + + m_connection->invalidate(); + m_connection = nullptr; +} + +void ChildProcessProxy::connectionWillOpen(IPC::Connection&) +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/ChildProcessProxy.h b/Source/WebKit2/UIProcess/ChildProcessProxy.h new file mode 100644 index 000000000..a1f5227e1 --- /dev/null +++ b/Source/WebKit2/UIProcess/ChildProcessProxy.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2012-2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "Connection.h" +#include "MessageReceiverMap.h" +#include "ProcessLauncher.h" + +#include <wtf/ThreadSafeRefCounted.h> + +namespace WebKit { + +class ChildProcessProxy : ProcessLauncher::Client, public IPC::Connection::Client, public ThreadSafeRefCounted<ChildProcessProxy> { + WTF_MAKE_NONCOPYABLE(ChildProcessProxy); + +protected: + explicit ChildProcessProxy(bool alwaysRunsAtBackgroundPriority = false); + +public: + virtual ~ChildProcessProxy(); + + void connect(); + void terminate(); + + template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<IPC::SendOption> sendOptions = { }); + template<typename T> bool sendSync(T&& message, typename T::Reply&&, uint64_t destinationID, Seconds timeout = 1_s, OptionSet<IPC::SendSyncOption> sendSyncOptions = { }); + + IPC::Connection* connection() const + { + ASSERT(m_connection); + return m_connection.get(); + } + + bool hasConnection(const IPC::Connection& connection) const + { + return m_connection == &connection; + } + + void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&); + void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&); + void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID); + void removeMessageReceiver(IPC::StringReference messageReceiverName); + + enum class State { + Launching, + Running, + Terminated, + }; + State state() const; + + pid_t processIdentifier() const { return m_processLauncher ? m_processLauncher->processIdentifier() : 0; } + + bool canSendMessage() const { return state() != State::Terminated;} + bool sendMessage(std::unique_ptr<IPC::Encoder>, OptionSet<IPC::SendOption>); + + void shutDownProcess(); + +protected: + // ProcessLauncher::Client + void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; + + bool dispatchMessage(IPC::Connection&, IPC::Decoder&); + bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); + + virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&); + +private: + virtual void connectionWillOpen(IPC::Connection&); + virtual void processWillShutDown(IPC::Connection&) = 0; + + Vector<std::pair<std::unique_ptr<IPC::Encoder>, OptionSet<IPC::SendOption>>> m_pendingMessages; + RefPtr<ProcessLauncher> m_processLauncher; + RefPtr<IPC::Connection> m_connection; + IPC::MessageReceiverMap m_messageReceiverMap; + bool m_alwaysRunsAtBackgroundPriority { false }; +}; + +template<typename T> +bool ChildProcessProxy::send(T&& message, uint64_t destinationID, OptionSet<IPC::SendOption> sendOptions) +{ + COMPILE_ASSERT(!T::isSync, AsyncMessageExpected); + + auto encoder = std::make_unique<IPC::Encoder>(T::receiverName(), T::name(), destinationID); + encoder->encode(message.arguments()); + + return sendMessage(WTFMove(encoder), sendOptions); +} + +template<typename U> +bool ChildProcessProxy::sendSync(U&& message, typename U::Reply&& reply, uint64_t destinationID, Seconds timeout, OptionSet<IPC::SendSyncOption> sendSyncOptions) +{ + COMPILE_ASSERT(U::isSync, SyncMessageExpected); + + if (!m_connection) + return false; + + return connection()->sendSync(std::forward<U>(message), WTFMove(reply), destinationID, timeout, sendSyncOptions); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp b/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp new file mode 100644 index 000000000..9ed78b3f0 --- /dev/null +++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.cpp @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "PageViewportController.h" + +#include "AcceleratedDrawingAreaProxy.h" +#include "PageViewportControllerClient.h" +#include "WebPageProxy.h" +#include <WebCore/FloatRect.h> +#include <WebCore/FloatSize.h> +#include <wtf/MathExtras.h> + +using namespace WebCore; + +namespace WebKit { + +PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, PageViewportControllerClient& client) + : m_webPageProxy(proxy) + , m_client(client) + , m_allowsUserScaling(false) + , m_minimumScaleToFit(1) + , m_initiallyFitToViewport(true) + , m_hadUserInteraction(false) + , m_pageScaleFactor(1) + , m_pendingPositionChange(false) + , m_pendingScaleChange(false) + , m_layerTreeStateIsFrozen(false) +{ + // Initializing Viewport Raw Attributes to avoid random negative or infinity scale factors + // if there is a race condition between the first layout and setting the viewport attributes for the first time. + m_rawAttributes.minimumScale = 1; + m_rawAttributes.maximumScale = 1; + m_rawAttributes.userScalable = m_allowsUserScaling; + + // The initial scale might be implicit and set to -1, in this case we have to infer it + // using the viewport size and the final layout size. + // To be able to assert for valid scale we initialize it to -1. + m_rawAttributes.initialScale = -1; +} + +float PageViewportController::innerBoundedViewportScale(float viewportScale) const +{ + return clampTo(viewportScale, m_minimumScaleToFit, m_rawAttributes.maximumScale); +} + +float PageViewportController::outerBoundedViewportScale(float viewportScale) const +{ + if (m_allowsUserScaling) { + // Bounded by [0.1, 10.0] like the viewport meta code in WebCore. + float hardMin = std::max<float>(0.1, 0.5 * m_minimumScaleToFit); + float hardMax = std::min<float>(10, 2 * m_rawAttributes.maximumScale); + return clampTo(viewportScale, hardMin, hardMax); + } + return innerBoundedViewportScale(viewportScale); +} + +float PageViewportController::deviceScaleFactor() const +{ + return m_webPageProxy->deviceScaleFactor(); +} + +static inline bool isIntegral(float value) +{ + return static_cast<int>(value) == value; +} + +FloatPoint PageViewportController::pixelAlignedFloatPoint(const FloatPoint& framePosition) +{ + return framePosition; +} + +FloatPoint PageViewportController::boundContentsPositionAtScale(const WebCore::FloatPoint& framePosition, float scale) +{ + // We need to floor the viewport here as to allow aligning the content in device units. If not, + // it might not be possible to scroll the last pixel and that affects fixed position elements. + FloatRect bounds; + bounds.setWidth(std::max(0.f, m_contentsSize.width() - floorf(m_viewportSize.width() / scale))); + bounds.setHeight(std::max(0.f, m_contentsSize.height() - floorf(m_viewportSize.height() / scale))); + + FloatPoint position; + position.setX(clampTo(framePosition.x(), bounds.x(), bounds.width())); + position.setY(clampTo(framePosition.y(), bounds.y(), bounds.height())); + + return position; +} + +FloatPoint PageViewportController::boundContentsPosition(const WebCore::FloatPoint& framePosition) +{ + return boundContentsPositionAtScale(framePosition, m_pageScaleFactor); +} + +void PageViewportController::didCommitLoad() +{ + // Do not count the previous committed page contents as covered. + m_lastFrameCoveredRect = FloatRect(); + + // Do not continue to use the content size of the previous page. + m_contentsSize = IntSize(); + + m_contentsPosition = FloatPoint(); + + m_layerTreeStateIsFrozen = true; + + m_initiallyFitToViewport = true; + + // Reset the position to the top, page/history scroll requests may override this before we re-enable rendering. + applyPositionAfterRenderingContents(FloatPoint()); +} + +void PageViewportController::didChangeContentsSize(const IntSize& newSize) +{ + m_contentsSize = newSize; + + bool minimumScaleUpdated = updateMinimumScaleToFit(false); + + if (m_initiallyFitToViewport) { + // Restrict scale factors to m_minimumScaleToFit. + ASSERT(m_minimumScaleToFit > 0); + m_rawAttributes.initialScale = m_minimumScaleToFit; + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); + } + + if (minimumScaleUpdated) + m_client.didChangeViewportAttributes(); + + // We might have pending position change which is now possible. + syncVisibleContents(); +} + +void PageViewportController::didRenderFrame(const IntSize& contentsSize, const IntRect& coveredRect) +{ + if (m_clientContentsSize != contentsSize) { + m_clientContentsSize = contentsSize; + // Only update the viewport's contents dimensions along with its render if the + // size actually changed since animations on the page trigger DidRenderFrame + // messages without causing dimension changes. + m_client.didChangeContentsSize(contentsSize); + } + + m_lastFrameCoveredRect = coveredRect; + + // Apply any scale or scroll position we locked to be set on the viewport + // only when there is something to display there. The scale goes first to + // avoid offsetting our deferred position by scaling at the viewport center. + // All position and scale changes resulting from a web process event should + // go through here to be applied on the viewport to avoid showing incomplete + // tiles to the user during a few milliseconds. + + if (m_pendingScaleChange) { + m_pendingScaleChange = false; + m_client.setPageScaleFactor(m_pageScaleFactor); + + // The scale changed, we have to re-pixel align. + m_pendingPositionChange = true; + FloatPoint currentDiscretePos = roundedIntPoint(m_contentsPosition); + FloatPoint pixelAlignedPos = pixelAlignedFloatPoint(currentDiscretePos); + m_contentsPosition = boundContentsPosition(pixelAlignedPos); + + m_webPageProxy->scalePage(m_pageScaleFactor, roundedIntPoint(m_contentsPosition)); + } + + // There might be rendered frames not covering our requested position yet, wait for it. + FloatRect endVisibleContentRect(m_contentsPosition, visibleContentsSize()); + if (m_pendingPositionChange && endVisibleContentRect.intersects(coveredRect)) { + m_client.setViewportPosition(m_contentsPosition); + m_pendingPositionChange = false; + } + + m_layerTreeStateIsFrozen = false; +} + +void PageViewportController::pageTransitionViewportReady() +{ + if (!m_rawAttributes.layoutSize.isEmpty() && m_initiallyFitToViewport) { + m_hadUserInteraction = false; + float initialScale = m_initiallyFitToViewport ? m_minimumScaleToFit : m_rawAttributes.initialScale; + applyScaleAfterRenderingContents(innerBoundedViewportScale(initialScale)); + } +} + +void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition) +{ + // Ignore the request if suspended. Can only happen due to delay in event delivery. + if (m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended()) + return; + + FloatPoint boundPosition = boundContentsPosition(FloatPoint(cssPosition)); + FloatPoint alignedPosition = pixelAlignedFloatPoint(boundPosition); + FloatRect endVisibleContentRect(alignedPosition, visibleContentsSize()); + + if (m_lastFrameCoveredRect.intersects(endVisibleContentRect)) + m_client.setViewportPosition(alignedPosition); + else { + // Keep the unbound position in case the contents size is changed later on. + FloatPoint position = pixelAlignedFloatPoint(FloatPoint(cssPosition)); + applyPositionAfterRenderingContents(position); + } +} + +void PageViewportController::didChangeViewportSize(const FloatSize& newSize) +{ + if (newSize.isEmpty()) + return; + + m_viewportSize = newSize; +} + +void PageViewportController::didChangeContentsVisibility(const FloatPoint& position, float scale, const FloatPoint& trajectoryVector) +{ + if (!m_pendingPositionChange) + m_contentsPosition = position; + if (!m_pendingScaleChange) + applyScaleAfterRenderingContents(scale); + + syncVisibleContents(trajectoryVector); +} + +bool PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVector) +{ + auto* drawingArea = static_cast<AcceleratedDrawingAreaProxy*>(m_webPageProxy->drawingArea()); + if (!drawingArea || m_viewportSize.isEmpty() || m_contentsSize.isEmpty()) + return false; + + FloatRect visibleContentsRect(boundContentsPosition(m_contentsPosition), visibleContentsSize()); + visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize)); + drawingArea->coordinatedLayerTreeHostProxy().setVisibleContentsRect(visibleContentsRect, trajectoryVector); + + if (!m_layerTreeStateIsFrozen) + m_client.didChangeVisibleContents(); + + return true; +} + +void PageViewportController::didChangeViewportAttributes(const WebCore::ViewportAttributes& newAttributes) +{ + if (!m_initiallyFitToViewport) + return; + + if (newAttributes.layoutSize.isEmpty()) + return; + + m_rawAttributes = newAttributes; + m_allowsUserScaling = !!m_rawAttributes.userScalable; + m_initiallyFitToViewport = (m_rawAttributes.initialScale < 0); + + if (!m_initiallyFitToViewport) + WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes); + + updateMinimumScaleToFit(true); + + // As the viewport attributes are calculated when loading pages, after load, or after + // viewport resize, it is important that we inform the client of the new scale and + // position, so that the content can be positioned correctly and pixel aligned. + m_pendingPositionChange = true; + m_pendingScaleChange = true; + + m_client.didChangeViewportAttributes(); +} + +FloatSize PageViewportController::visibleContentsSize() const +{ + return FloatSize(m_viewportSize.width() / m_pageScaleFactor, m_viewportSize.height() / m_pageScaleFactor); +} + +void PageViewportController::applyScaleAfterRenderingContents(float scale) +{ + if (m_pageScaleFactor == scale) + return; + + float oldPageScaleFactor = m_pageScaleFactor; + m_pageScaleFactor = scale; + m_pendingScaleChange = true; + if (!syncVisibleContents()) { + m_pageScaleFactor = oldPageScaleFactor; + m_webPageProxy->scalePage(m_pageScaleFactor, roundedIntPoint(m_contentsPosition)); + } +} + +void PageViewportController::applyPositionAfterRenderingContents(const FloatPoint& pos) +{ + if (m_contentsPosition == pos) + return; + + m_contentsPosition = pos; + m_pendingPositionChange = true; + syncVisibleContents(); +} + +bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate) +{ + if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty() || !m_initiallyFitToViewport || m_hadUserInteraction) + return false; + + // FIXME: Why this arbitrary precision? We likely want to omit the third argument so that + // std::numeric_limits<float>::epsilon() is used instead, similarly to Mac / iOS. + bool currentlyScaledToFit = WTF::areEssentiallyEqual(m_pageScaleFactor, m_minimumScaleToFit, 0.0001f); + float minimumScale = WebCore::computeMinimumScaleFactorForContentContained(m_rawAttributes, WebCore::roundedIntSize(m_viewportSize), WebCore::roundedIntSize(m_contentsSize)); + + if (minimumScale <= 0) + return false; + + if (!WTF::areEssentiallyEqual(minimumScale, m_minimumScaleToFit, 0.0001f)) { + m_minimumScaleToFit = minimumScale; + + if (!m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended()) { + if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit)) + applyScaleAfterRenderingContents(m_minimumScaleToFit); + else { + // Ensure the effective scale stays within bounds. + float boundedScale = innerBoundedViewportScale(m_pageScaleFactor); + if (!WTF::areEssentiallyEqual(boundedScale, m_pageScaleFactor, 0.0001f)) + applyScaleAfterRenderingContents(boundedScale); + } + } + + return true; + } + return false; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.h b/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.h new file mode 100644 index 000000000..e02d7671d --- /dev/null +++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/PageViewportController.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef PageViewportController_h +#define PageViewportController_h + +#include <WebCore/FloatPoint.h> +#include <WebCore/FloatRect.h> +#include <WebCore/FloatSize.h> +#include <WebCore/ViewportArguments.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { +class IntPoint; +class IntSize; +} + +namespace WebKit { + +class WebPageProxy; +class PageViewportController; +class PageViewportControllerClient; + +class PageViewportController { + WTF_MAKE_NONCOPYABLE(PageViewportController); + +public: + PageViewportController(WebKit::WebPageProxy*, PageViewportControllerClient&); + virtual ~PageViewportController() { } + + float innerBoundedViewportScale(float) const; + float outerBoundedViewportScale(float) const; + + WebCore::FloatPoint pixelAlignedFloatPoint(const WebCore::FloatPoint&); + + WebCore::FloatPoint boundContentsPosition(const WebCore::FloatPoint&); + WebCore::FloatPoint boundContentsPositionAtScale(const WebCore::FloatPoint&, float scale); + + WebCore::FloatSize visibleContentsSize() const; + + bool hadUserInteraction() const { return m_hadUserInteraction; } + bool allowsUserScaling() const { return m_allowsUserScaling; } + + WebCore::FloatSize contentsLayoutSize() const { return m_rawAttributes.layoutSize; } + float deviceScaleFactor() const; + float minimumScale() const { return m_minimumScaleToFit; } + float maximumScale() const { return m_rawAttributes.maximumScale; } + float currentScale() const { return m_pageScaleFactor; } + + void setHadUserInteraction(bool didUserInteract) { m_hadUserInteraction = didUserInteract; } + void setInitiallyFitToViewport(bool initiallyFit) { m_initiallyFitToViewport = initiallyFit; } + + // Notifications from the viewport. + void didChangeViewportSize(const WebCore::FloatSize& newSize); + void didChangeContentsVisibility(const WebCore::FloatPoint&, float scale, const WebCore::FloatPoint& trajectoryVector = WebCore::FloatPoint::zero()); + + // Notifications from the WebProcess. + void didCommitLoad(); + void didChangeContentsSize(const WebCore::IntSize& newSize); + void didChangeViewportAttributes(const WebCore::ViewportAttributes&); + void didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect); + void pageTransitionViewportReady(); + void pageDidRequestScroll(const WebCore::IntPoint& cssPosition); + +private: + bool syncVisibleContents(const WebCore::FloatPoint &trajectoryVector = WebCore::FloatPoint::zero()); + void applyScaleAfterRenderingContents(float scale); + void applyPositionAfterRenderingContents(const WebCore::FloatPoint& pos); + bool updateMinimumScaleToFit(bool userInitiatedUpdate); + + WebPageProxy* const m_webPageProxy; + PageViewportControllerClient& m_client; + + WebCore::ViewportAttributes m_rawAttributes; + + bool m_allowsUserScaling; + float m_minimumScaleToFit; + bool m_initiallyFitToViewport; + + bool m_hadUserInteraction; + + WebCore::FloatPoint m_contentsPosition; + WebCore::FloatSize m_contentsSize; + WebCore::FloatSize m_viewportSize; + WebCore::IntSize m_clientContentsSize; + float m_pageScaleFactor; + + bool m_pendingPositionChange; + bool m_pendingScaleChange; + bool m_layerTreeStateIsFrozen; + WebCore::FloatRect m_lastFrameCoveredRect; +}; + +} // namespace WebKit + +#endif // PageViewportController_h diff --git a/Source/WebKit2/UIProcess/CoordinatedGraphics/WKCoordinatedSceneAPICast.h b/Source/WebKit2/UIProcess/CoordinatedGraphics/WKCoordinatedSceneAPICast.h new file mode 100644 index 000000000..d33dcdaea --- /dev/null +++ b/Source/WebKit2/UIProcess/CoordinatedGraphics/WKCoordinatedSceneAPICast.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WKCoordinatedSceneAPICast_h +#define WKCoordinatedSceneAPICast_h + +#include <WebKit/WKCoordinatedScene.h> + +namespace WebCore { +class TextureMapperLayer; +} + +namespace WebKit { + +class CoordinatedGraphicsScene; + +inline WebKit::CoordinatedGraphicsScene* toImpl(WKCoordinatedScene scene) +{ + return reinterpret_cast<WebKit::CoordinatedGraphicsScene*>(scene); +} + +inline WKCoordinatedScene toAPI(WebKit::CoordinatedGraphicsScene* scene) +{ + return reinterpret_cast<WKCoordinatedScene>(scene); +} + +inline WebCore::TextureMapperLayer* toImpl(WKCoordinatedSceneLayer layer) +{ + return reinterpret_cast<WebCore::TextureMapperLayer*>(layer); +} + +inline WKCoordinatedSceneLayer toAPI(WebCore::TextureMapperLayer* layer) +{ + return reinterpret_cast<WKCoordinatedSceneLayer>(layer); +} + +} // namespace WebKit + +#endif // WKCoordinatedSceneAPICast_h diff --git a/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.cpp b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.cpp new file mode 100644 index 000000000..262cd26d3 --- /dev/null +++ b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DatabaseProcessProxy.h" + +#include "DatabaseProcessMessages.h" +#include "DatabaseProcessProxyMessages.h" +#include "NetworkProcessMessages.h" +#include "WebProcessPool.h" +#include "WebsiteData.h" +#include <WebCore/NotImplemented.h> + +#if ENABLE(DATABASE_PROCESS) + +using namespace WebCore; + +namespace WebKit { + +static uint64_t generateCallbackID() +{ + static uint64_t callbackID; + + return ++callbackID; +} + +Ref<DatabaseProcessProxy> DatabaseProcessProxy::create(WebProcessPool* processPool) +{ + return adoptRef(*new DatabaseProcessProxy(processPool)); +} + +DatabaseProcessProxy::DatabaseProcessProxy(WebProcessPool* processPool) + : ChildProcessProxy(processPool->alwaysRunsAtBackgroundPriority()) + , m_processPool(processPool) + , m_numPendingConnectionRequests(0) +{ + connect(); +} + +DatabaseProcessProxy::~DatabaseProcessProxy() +{ + ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty()); +} + +void DatabaseProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) +{ + launchOptions.processType = ProcessLauncher::ProcessType::Database; + ChildProcessProxy::getLaunchOptions(launchOptions); +} + +void DatabaseProcessProxy::processWillShutDown(IPC::Connection& connection) +{ + ASSERT_UNUSED(connection, this->connection() == &connection); +} + +void DatabaseProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) +{ + if (decoder.messageReceiverName() == Messages::DatabaseProcessProxy::messageReceiverName()) { + didReceiveDatabaseProcessProxyMessage(connection, decoder); + return; + } +} + +void DatabaseProcessProxy::fetchWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, std::function<void (WebsiteData)> completionHandler) +{ + ASSERT(canSendMessage()); + + uint64_t callbackID = generateCallbackID(); + m_pendingFetchWebsiteDataCallbacks.add(callbackID, WTFMove(completionHandler)); + + send(Messages::DatabaseProcess::FetchWebsiteData(sessionID, dataTypes, callbackID), 0); +} + +void DatabaseProcessProxy::deleteWebsiteData(WebCore::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) +{ + auto callbackID = generateCallbackID(); + + m_pendingDeleteWebsiteDataCallbacks.add(callbackID, WTFMove(completionHandler)); + send(Messages::DatabaseProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0); +} + +void DatabaseProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, const Vector<WebCore::SecurityOriginData>& origins, std::function<void()> completionHandler) +{ + ASSERT(canSendMessage()); + + uint64_t callbackID = generateCallbackID(); + m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, WTFMove(completionHandler)); + + send(Messages::DatabaseProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, callbackID), 0); +} + +void DatabaseProcessProxy::getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&& reply) +{ + m_pendingConnectionReplies.append(WTFMove(reply)); + + if (state() == State::Launching) { + m_numPendingConnectionRequests++; + return; + } + + connection()->send(Messages::DatabaseProcess::CreateDatabaseToWebProcessConnection(), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); +} + +void DatabaseProcessProxy::didClose(IPC::Connection&) +{ + // The database process must have crashed or exited, so send any pending sync replies we might have. + while (!m_pendingConnectionReplies.isEmpty()) { + auto reply = m_pendingConnectionReplies.takeFirst(); + +#if USE(UNIX_DOMAIN_SOCKETS) + reply->send(IPC::Attachment()); +#elif OS(DARWIN) + reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); +#else + notImplemented(); +#endif + } + + for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values()) + callback(WebsiteData()); + m_pendingFetchWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataForOriginsCallbacks.clear(); + + // Tell ProcessPool to forget about this database process. This may cause us to be deleted. + m_processPool->databaseProcessCrashed(this); +} + +void DatabaseProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) +{ +} + +void DatabaseProcessProxy::didCreateDatabaseToWebProcessConnection(const IPC::Attachment& connectionIdentifier) +{ + ASSERT(!m_pendingConnectionReplies.isEmpty()); + + RefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); + +#if USE(UNIX_DOMAIN_SOCKETS) + reply->send(connectionIdentifier); +#elif OS(DARWIN) + reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); +#else + notImplemented(); +#endif +} + +void DatabaseProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData) +{ + auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID); + callback(websiteData); +} + +void DatabaseProcessProxy::didDeleteWebsiteData(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID); + callback(); +} + +void DatabaseProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID); + callback(); +} + +#if ENABLE(SANDBOX_EXTENSIONS) +void DatabaseProcessProxy::getSandboxExtensionsForBlobFiles(uint64_t requestID, const Vector<String>& paths) +{ + SandboxExtension::HandleArray extensions; + extensions.allocate(paths.size()); + for (size_t i = 0; i < paths.size(); ++i) { + // ReadWrite is required for creating hard links, which is something that might be done with these extensions. + SandboxExtension::createHandle(paths[i], SandboxExtension::ReadWrite, extensions[i]); + } + + send(Messages::DatabaseProcess::DidGetSandboxExtensionsForBlobFiles(requestID, extensions), 0); +} +#endif + +void DatabaseProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) +{ + ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); + + if (IPC::Connection::identifierIsNull(connectionIdentifier)) { + // FIXME: Do better cleanup here. + return; + } + + for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i) + connection()->send(Messages::DatabaseProcess::CreateDatabaseToWebProcessConnection(), 0); + + m_numPendingConnectionRequests = 0; +} + +} // namespace WebKit + +#endif // ENABLE(DATABASE_PROCESS) diff --git a/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.h b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.h new file mode 100644 index 000000000..a80d69182 --- /dev/null +++ b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DatabaseProcessProxy_h +#define DatabaseProcessProxy_h + +#if ENABLE(DATABASE_PROCESS) + +#include "ChildProcessProxy.h" +#include "ProcessLauncher.h" +#include "WebProcessProxyMessages.h" +#include <wtf/Deque.h> +#include <wtf/Forward.h> + +namespace WebCore { +class SecurityOrigin; +class SessionID; +struct SecurityOriginData; +} + +namespace WebKit { + +class WebProcessPool; +enum class WebsiteDataType; +struct WebsiteData; + +class DatabaseProcessProxy : public ChildProcessProxy { +public: + static Ref<DatabaseProcessProxy> create(WebProcessPool*); + ~DatabaseProcessProxy(); + + void fetchWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, std::function<void(WebsiteData)> completionHandler); + void deleteWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, std::chrono::system_clock::time_point modifiedSince, std::function<void()> completionHandler); + void deleteWebsiteDataForOrigins(WebCore::SessionID, OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, std::function<void()> completionHandler); + + void getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&&); + +private: + DatabaseProcessProxy(WebProcessPool*); + + // ChildProcessProxy + void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; + void processWillShutDown(IPC::Connection&) override; + + // IPC::Connection::Client + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didClose(IPC::Connection&) override; + void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + + void didReceiveDatabaseProcessProxyMessage(IPC::Connection&, IPC::Decoder&); + + // Message handlers + void didCreateDatabaseToWebProcessConnection(const IPC::Attachment&); + void didFetchWebsiteData(uint64_t callbackID, const WebsiteData&); + void didDeleteWebsiteData(uint64_t callbackID); + void didDeleteWebsiteDataForOrigins(uint64_t callbackID); +#if ENABLE(SANDBOX_EXTENSIONS) + void getSandboxExtensionsForBlobFiles(uint64_t requestID, const Vector<String>& paths); +#endif + + // ProcessLauncher::Client + void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; + + WebProcessPool* m_processPool; + + unsigned m_numPendingConnectionRequests; + Deque<Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>> m_pendingConnectionReplies; + + HashMap<uint64_t, std::function<void (WebsiteData)>> m_pendingFetchWebsiteDataCallbacks; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataCallbacks; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataForOriginsCallbacks; +}; + +} // namespace WebKit + +#endif // ENABLE(DATABASE_PROCESS) + +#endif // DatabaseProcessProxy_h diff --git a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.messages.in b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.messages.in index 3faefa1e2..55f73f73b 100644 --- a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/Databases/DatabaseProcessProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Intel Corporation. All rights reserved. +# Copyright (C) 2013 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,11 +20,18 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(BATTERY_STATUS) +#if ENABLE(DATABASE_PROCESS) -messages -> WebBatteryManagerProxy { - StartUpdating(); - StopUpdating(); -} +messages -> DatabaseProcessProxy LegacyReceiver { + DidCreateDatabaseToWebProcessConnection(IPC::Attachment connectionIdentifier) + + DidFetchWebsiteData(uint64_t callbackID, struct WebKit::WebsiteData websiteData) + DidDeleteWebsiteData(uint64_t callbackID) + DidDeleteWebsiteDataForOrigins(uint64_t callbackID) +#if ENABLE(SANDBOX_EXTENSIONS) + GetSandboxExtensionsForBlobFiles(uint64_t requestID, Vector<String> paths) #endif +} + +#endif // ENABLE(DATABASE_PROCESS) diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp index 01f53bbe8..e2641d7c2 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,19 +27,20 @@ #include "DownloadProxy.h" #include "APIData.h" +#include "APIDownloadClient.h" #include "AuthenticationChallengeProxy.h" #include "DataReference.h" #include "DownloadProxyMap.h" -#include "WebContext.h" +#include "NetworkProcessMessages.h" +#include "NetworkProcessProxy.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" +#include "WebProtectionSpace.h" +#include <WebCore/FileSystem.h> +#include <WebCore/MIMETypeRegistry.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessMessages.h" -#include "NetworkProcessProxy.h" -#endif - using namespace WebCore; namespace WebKit { @@ -50,132 +51,192 @@ static uint64_t generateDownloadID() return ++uniqueDownloadID; } -PassRefPtr<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebContext& webContext) +PassRefPtr<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest) { - return adoptRef(new DownloadProxy(downloadProxyMap, webContext)); + return adoptRef(new DownloadProxy(downloadProxyMap, processPool, resourceRequest)); } -DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebContext& webContext) +DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest) : m_downloadProxyMap(downloadProxyMap) - , m_webContext(&webContext) + , m_processPool(&processPool) , m_downloadID(generateDownloadID()) + , m_request(resourceRequest) { } DownloadProxy::~DownloadProxy() { - ASSERT(!m_webContext); + ASSERT(!m_processPool); } void DownloadProxy::cancel() { - if (!m_webContext) + if (!m_processPool) return; -#if ENABLE(NETWORK_PROCESS) - if (m_webContext->usesNetworkProcess()) { - if (NetworkProcessProxy* networkProcess = m_webContext->networkProcess()) - networkProcess->connection()->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0); - return; - } -#endif - - m_webContext->sendToAllProcesses(Messages::WebProcess::CancelDownload(m_downloadID)); + if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess()) + networkProcess->connection()->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0); } void DownloadProxy::invalidate() { - ASSERT(m_webContext); - m_webContext = 0; + ASSERT(m_processPool); + m_processPool = nullptr; } void DownloadProxy::processDidClose() { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().processDidCrash(m_webContext.get(), this); + m_processPool->downloadClient().processDidCrash(m_processPool.get(), this); } -void DownloadProxy::didStart(const ResourceRequest& request) +void DownloadProxy::didStart(const ResourceRequest& request, const String& suggestedFilename) { m_request = request; + m_suggestedFilename = suggestedFilename; - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didStart(m_webContext.get(), this); + m_processPool->downloadClient().didStart(m_processPool.get(), this); } void DownloadProxy::didReceiveAuthenticationChallenge(const AuthenticationChallenge& authenticationChallenge, uint64_t challengeID) { - if (!m_webContext) + if (!m_processPool) return; - RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_webContext->networkingProcessConnection()); + RefPtr<AuthenticationChallengeProxy> authenticationChallengeProxy = AuthenticationChallengeProxy::create(authenticationChallenge, challengeID, m_processPool->networkingProcessConnection()); + + m_processPool->downloadClient().didReceiveAuthenticationChallenge(m_processPool.get(), this, authenticationChallengeProxy.get()); +} + +#if USE(NETWORK_SESSION) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) +void DownloadProxy::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) +{ + if (!m_processPool) + return; + + auto* networkProcessProxy = m_processPool->networkProcess(); + if (!networkProcessProxy) + return; - m_webContext->downloadClient().didReceiveAuthenticationChallenge(m_webContext.get(), this, authenticationChallengeProxy.get()); + bool result = m_processPool->downloadClient().canAuthenticateAgainstProtectionSpace(getPtr(WebProtectionSpace::create(protectionSpace))); + + networkProcessProxy->connection()->send(Messages::NetworkProcess::ContinueCanAuthenticateAgainstProtectionSpaceDownload(m_downloadID, result), 0); } +#endif + +void DownloadProxy::willSendRequest(const ResourceRequest& proposedRequest, const ResourceResponse& redirectResponse) +{ + if (!m_processPool) + return; + + RefPtr<DownloadProxy> protectedThis(this); + m_processPool->downloadClient().willSendRequest(proposedRequest, redirectResponse, [protectedThis](const ResourceRequest& newRequest) { + if (!protectedThis->m_processPool) + return; + + auto* networkProcessProxy = protectedThis->m_processPool->networkProcess(); + if (!networkProcessProxy) + return; + + networkProcessProxy->connection()->send(Messages::NetworkProcess::ContinueWillSendRequest(protectedThis->m_downloadID, newRequest), 0); + }); +} +#endif void DownloadProxy::didReceiveResponse(const ResourceResponse& response) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didReceiveResponse(m_webContext.get(), this, response); +#if !USE(NETWORK_SESSION) + // As per https://html.spec.whatwg.org/#as-a-download (step 2), the filename from the Content-Disposition header + // should override the suggested filename from the download attribute. + if (!m_suggestedFilename.isNull() && response.isAttachmentWithFilename()) + m_suggestedFilename = String(); +#endif + + m_processPool->downloadClient().didReceiveResponse(m_processPool.get(), this, response); } void DownloadProxy::didReceiveData(uint64_t length) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didReceiveData(m_webContext.get(), this, length); + m_processPool->downloadClient().didReceiveData(m_processPool.get(), this, length); } void DownloadProxy::shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result) { result = false; - if (!m_webContext) + if (!m_processPool) return; - result = m_webContext->downloadClient().shouldDecodeSourceDataOfMIMEType(m_webContext.get(), this, mimeType); + result = m_processPool->downloadClient().shouldDecodeSourceDataOfMIMEType(m_processPool.get(), this, mimeType); } -void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle) +void DownloadProxy::decideDestinationWithSuggestedFilenameAsync(DownloadID downloadID, const String& suggestedFilename) +{ + bool allowOverwrite = false; + + if (!m_processPool) + return; + + String destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite); + + SandboxExtension::Handle sandboxExtensionHandle; + if (!destination.isNull()) + SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle); + + if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess()) + networkProcess->connection()->send(Messages::NetworkProcess::ContinueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle, allowOverwrite), 0); +} + +#if !USE(NETWORK_SESSION) + +void DownloadProxy::decideDestinationWithSuggestedFilename(const String& filename, const String& mimeType, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle) { allowOverwrite = false; - if (!m_webContext) + if (!m_processPool) return; - destination = m_webContext->downloadClient().decideDestinationWithSuggestedFilename(m_webContext.get(), this, filename, allowOverwrite); + String suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(m_suggestedFilename.isNull() ? filename : m_suggestedFilename, mimeType); + destination = m_processPool->downloadClient().decideDestinationWithSuggestedFilename(m_processPool.get(), this, suggestedFilename, allowOverwrite); if (!destination.isNull()) SandboxExtension::createHandle(destination, SandboxExtension::ReadWrite, sandboxExtensionHandle); } +#endif + void DownloadProxy::didCreateDestination(const String& path) { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didCreateDestination(m_webContext.get(), this, path); + m_processPool->downloadClient().didCreateDestination(m_processPool.get(), this, path); } void DownloadProxy::didFinish() { - if (!m_webContext) + if (!m_processPool) return; - m_webContext->downloadClient().didFinish(m_webContext.get(), this); + m_processPool->downloadClient().didFinish(m_processPool.get(), this); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); } -static PassRefPtr<API::Data> createData(const IPC::DataReference& data) +static RefPtr<API::Data> createData(const IPC::DataReference& data) { if (data.isEmpty()) return 0; @@ -185,12 +246,12 @@ static PassRefPtr<API::Data> createData(const IPC::DataReference& data) void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference& resumeData) { - if (!m_webContext) + if (!m_processPool) return; m_resumeData = createData(resumeData); - m_webContext->downloadClient().didFail(m_webContext.get(), this, error); + m_processPool->downloadClient().didFail(m_processPool.get(), this, error); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); @@ -200,7 +261,7 @@ void DownloadProxy::didCancel(const IPC::DataReference& resumeData) { m_resumeData = createData(resumeData); - m_webContext->downloadClient().didCancel(m_webContext.get(), this); + m_processPool->downloadClient().didCancel(m_processPool.get(), this); // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(this); diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h index 6f8536146..1cada8e2a 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,6 +28,7 @@ #include "APIObject.h" #include "Connection.h" +#include "DownloadID.h" #include "SandboxExtension.h" #include <WebCore/ResourceRequest.h> #include <wtf/Forward.h> @@ -38,23 +39,25 @@ class Data; } namespace WebCore { - class AuthenticationChallenge; - class ResourceError; - class ResourceResponse; +class AuthenticationChallenge; +class ProtectionSpace; +class ResourceError; +class ResourceResponse; } namespace WebKit { +class DownloadID; class DownloadProxyMap; -class WebContext; class WebPageProxy; +class WebProcessPool; class DownloadProxy : public API::ObjectImpl<API::Object::Type::Download>, public IPC::MessageReceiver { public: - static PassRefPtr<DownloadProxy> create(DownloadProxyMap&, WebContext&); + static PassRefPtr<DownloadProxy> create(DownloadProxyMap&, WebProcessPool&, const WebCore::ResourceRequest&); ~DownloadProxy(); - uint64_t downloadID() const { return m_downloadID; } + DownloadID downloadID() const { return m_downloadID; } const WebCore::ResourceRequest& request() const { return m_request; } API::Data* resumeData() const { return m_resumeData.get(); } @@ -63,34 +66,43 @@ public: void invalidate(); void processDidClose(); - void didReceiveDownloadProxyMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncDownloadProxyMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + void didReceiveDownloadProxyMessage(IPC::Connection&, IPC::Decoder&); + void didReceiveSyncDownloadProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); private: - explicit DownloadProxy(DownloadProxyMap&, WebContext&); + explicit DownloadProxy(DownloadProxyMap&, WebProcessPool&, const WebCore::ResourceRequest&); // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; // Message handlers. - void didStart(const WebCore::ResourceRequest&); + void didStart(const WebCore::ResourceRequest&, const String& suggestedFilename); void didReceiveAuthenticationChallenge(const WebCore::AuthenticationChallenge&, uint64_t challengeID); void didReceiveResponse(const WebCore::ResourceResponse&); void didReceiveData(uint64_t length); void shouldDecodeSourceDataOfMIMEType(const String& mimeType, bool& result); - void decideDestinationWithSuggestedFilename(const String& filename, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle); void didCreateDestination(const String& path); void didFinish(); void didFail(const WebCore::ResourceError&, const IPC::DataReference& resumeData); void didCancel(const IPC::DataReference& resumeData); +#if USE(NETWORK_SESSION) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&); +#endif + void willSendRequest(const WebCore::ResourceRequest& redirectRequest, const WebCore::ResourceResponse& redirectResponse); +#else + void decideDestinationWithSuggestedFilename(const String& filename, const String& mimeType, String& destination, bool& allowOverwrite, SandboxExtension::Handle& sandboxExtensionHandle); +#endif + void decideDestinationWithSuggestedFilenameAsync(DownloadID, const String& suggestedFilename); DownloadProxyMap& m_downloadProxyMap; - RefPtr<WebContext> m_webContext; - uint64_t m_downloadID; + RefPtr<WebProcessPool> m_processPool; + DownloadID m_downloadID; RefPtr<API::Data> m_resumeData; WebCore::ResourceRequest m_request; + String m_suggestedFilename; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in index 37ef52fd7..c22d099ba 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxy.messages.in @@ -21,13 +21,22 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> DownloadProxy { - DidStart(WebCore::ResourceRequest request) + DidStart(WebCore::ResourceRequest request, AtomicString suggestedFilename) DidReceiveAuthenticationChallenge(WebCore::AuthenticationChallenge challenge, uint64_t challengeID) +#if USE(NETWORK_SESSION) + WillSendRequest(WebCore::ResourceRequest redirectRequest, WebCore::ResourceResponse redirectResponse)) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace) +#endif +#endif + DecideDestinationWithSuggestedFilenameAsync(WebKit::DownloadID downloadID, String suggestedFilename) DidReceiveResponse(WebCore::ResourceResponse response) DidReceiveData(uint64_t length) ShouldDecodeSourceDataOfMIMEType(String mimeType) -> (bool result) - DecideDestinationWithSuggestedFilename(String filename) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#if !USE(NETWORK_SESSION) + DecideDestinationWithSuggestedFilename(String filename, String mimeType) -> (String destination, bool allowOverwrite, WebKit::SandboxExtension::Handle sandboxExtensionHandle) +#endif DidCreateDestination(String path) DidFinish() DidFail(WebCore::ResourceError error, IPC::DataReference resumeData) diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp index e6246b2a3..7509ddedb 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.cpp @@ -44,38 +44,38 @@ DownloadProxyMap::~DownloadProxyMap() ASSERT(m_downloads.isEmpty()); } -DownloadProxy* DownloadProxyMap::createDownloadProxy(WebContext& webContext) +DownloadProxy* DownloadProxyMap::createDownloadProxy(WebProcessPool& processPool, const WebCore::ResourceRequest& resourceRequest) { - RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(*this, webContext); + RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(*this, processPool, resourceRequest); m_downloads.set(downloadProxy->downloadID(), downloadProxy); - m_process->addMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadProxy->downloadID(), *downloadProxy); + m_process->addMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadProxy->downloadID().downloadID(), *downloadProxy); return downloadProxy.get(); } void DownloadProxyMap::downloadFinished(DownloadProxy* downloadProxy) { - uint64_t downloadID = downloadProxy->downloadID(); + auto downloadID = downloadProxy->downloadID(); ASSERT(m_downloads.contains(downloadID)); + m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadID.downloadID()); downloadProxy->invalidate(); m_downloads.remove(downloadID); - - m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), downloadID); } void DownloadProxyMap::processDidClose() { // Invalidate all outstanding downloads. - for (HashMap<uint64_t, RefPtr<DownloadProxy>>::iterator::Values it = m_downloads.begin().values(), end = m_downloads.end().values(); it != end; ++it) { - (*it)->processDidClose(); - (*it)->invalidate(); + for (const auto& download : m_downloads.values()) { + download->processDidClose(); + download->invalidate(); + m_process->removeMessageReceiver(Messages::DownloadProxy::messageReceiverName(), download->downloadID().downloadID()); } m_downloads.clear(); - m_process = 0; + m_process = nullptr; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h index 66f5f41d8..8f89cd6ab 100644 --- a/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h +++ b/Source/WebKit2/UIProcess/Downloads/DownloadProxyMap.h @@ -26,15 +26,19 @@ #ifndef DownloadProxyMap_h #define DownloadProxyMap_h +#include "DownloadID.h" #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> -#include <wtf/PassRefPtr.h> + +namespace WebCore { +class ResourceRequest; +} namespace WebKit { class ChildProcessProxy; class DownloadProxy; -class WebContext; +class WebProcessPool; class DownloadProxyMap { WTF_MAKE_NONCOPYABLE(DownloadProxyMap); @@ -43,7 +47,7 @@ public: explicit DownloadProxyMap(ChildProcessProxy*); ~DownloadProxyMap(); - DownloadProxy* createDownloadProxy(WebContext&); + DownloadProxy* createDownloadProxy(WebProcessPool&, const WebCore::ResourceRequest&); void downloadFinished(DownloadProxy*); bool isEmpty() const { return m_downloads.isEmpty(); } @@ -52,7 +56,7 @@ public: private: ChildProcessProxy* m_process; - HashMap<uint64_t, RefPtr<DownloadProxy>> m_downloads; + HashMap<DownloadID, RefPtr<DownloadProxy>> m_downloads; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp index d15d3e00d..a5f75f0e0 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,68 +31,73 @@ #include "WebPageProxy.h" #include "WebProcessProxy.h" +#if PLATFORM(COCOA) +#include <WebCore/MachSendRight.h> +#endif + using namespace WebCore; namespace WebKit { -DrawingAreaProxy::DrawingAreaProxy(DrawingAreaType type, WebPageProxy* webPageProxy) +DrawingAreaProxy::DrawingAreaProxy(DrawingAreaType type, WebPageProxy& webPageProxy) : m_type(type) , m_webPageProxy(webPageProxy) - , m_size(webPageProxy->viewSize()) + , m_size(webPageProxy.viewSize()) #if PLATFORM(MAC) - , m_exposedRectChangedTimer(this, &DrawingAreaProxy::exposedRectChangedTimerFired) + , m_viewExposedRectChangedTimer(RunLoop::main(), this, &DrawingAreaProxy::viewExposedRectChangedTimerFired) #endif { - m_webPageProxy->process().addMessageReceiver(Messages::DrawingAreaProxy::messageReceiverName(), webPageProxy->pageID(), *this); + m_webPageProxy.process().addMessageReceiver(Messages::DrawingAreaProxy::messageReceiverName(), m_webPageProxy.pageID(), *this); } DrawingAreaProxy::~DrawingAreaProxy() { - m_webPageProxy->process().removeMessageReceiver(Messages::DrawingAreaProxy::messageReceiverName(), m_webPageProxy->pageID()); + m_webPageProxy.process().removeMessageReceiver(Messages::DrawingAreaProxy::messageReceiverName(), m_webPageProxy.pageID()); } -void DrawingAreaProxy::setSize(const IntSize& size, const IntSize& layerPosition, const IntSize& scrollOffset) +bool DrawingAreaProxy::setSize(const IntSize& size, const IntSize& layerPosition, const IntSize& scrollOffset) { if (m_size == size && m_layerPosition == layerPosition && scrollOffset.isZero()) - return; + return false; m_size = size; m_layerPosition = layerPosition; m_scrollOffset += scrollOffset; sizeDidChange(); + return true; } -#if PLATFORM(MAC) -void DrawingAreaProxy::setExposedRect(const FloatRect& exposedRect) +#if PLATFORM(COCOA) +MachSendRight DrawingAreaProxy::createFence() { - if (!m_webPageProxy->isValid()) - return; - - m_exposedRect = exposedRect; - - if (!m_exposedRectChangedTimer.isActive()) - m_exposedRectChangedTimer.startOneShot(0); + ASSERT_NOT_REACHED(); + return MachSendRight(); } +#endif -void DrawingAreaProxy::exposedRectChangedTimerFired(Timer<DrawingAreaProxy>*) +#if PLATFORM(MAC) +void DrawingAreaProxy::setViewExposedRect(std::optional<WebCore::FloatRect> viewExposedRect) { - if (!m_webPageProxy->isValid()) + if (!m_webPageProxy.isValid()) return; - if (m_exposedRect == m_lastSentExposedRect) - return; + m_viewExposedRect = viewExposedRect; - m_webPageProxy->process().send(Messages::DrawingArea::SetExposedRect(m_exposedRect), m_webPageProxy->pageID()); - m_lastSentExposedRect = m_exposedRect; + if (!m_viewExposedRectChangedTimer.isActive()) + m_viewExposedRectChangedTimer.startOneShot(0); } -void DrawingAreaProxy::setCustomFixedPositionRect(const FloatRect& fixedPositionRect) +void DrawingAreaProxy::viewExposedRectChangedTimerFired() { - if (!m_webPageProxy->isValid()) + if (!m_webPageProxy.isValid()) return; - m_webPageProxy->process().send(Messages::DrawingArea::SetCustomFixedPositionRect(fixedPositionRect), m_webPageProxy->pageID()); + if (m_viewExposedRect == m_lastSentViewExposedRect) + return; + + m_webPageProxy.process().send(Messages::DrawingArea::SetViewExposedRect(m_viewExposedRect), m_webPageProxy.pageID()); + m_lastSentViewExposedRect = m_viewExposedRect; } -#endif +#endif // PLATFORM(MAC) } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.h b/Source/WebKit2/UIProcess/DrawingAreaProxy.h index 81cf05990..ee97f0c85 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.h +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.h @@ -28,19 +28,26 @@ #define DrawingAreaProxy_h #include "DrawingAreaInfo.h" +#include "GenericCallback.h" #include "MessageReceiver.h" #include <WebCore/FloatRect.h> #include <WebCore/IntRect.h> #include <WebCore/IntSize.h> -#include <WebCore/Timer.h> #include <chrono> #include <stdint.h> #include <wtf/Noncopyable.h> +#include <wtf/RunLoop.h> +#include <wtf/TypeCasts.h> + +#if PLATFORM(COCOA) +namespace WebCore { +class MachSendRight; +} +#endif namespace WebKit { class LayerTreeContext; -class CoordinatedLayerTreeHostProxy; class UpdateInfo; class WebPageProxy; @@ -60,12 +67,12 @@ public: virtual void waitForBackingStoreUpdateOnNextPaint() { } const WebCore::IntSize& size() const { return m_size; } - void setSize(const WebCore::IntSize&, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset); + bool setSize(const WebCore::IntSize&, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset); // The timeout we use when waiting for a DidUpdateGeometry message. - static constexpr std::chrono::milliseconds didUpdateBackingStoreStateTimeout() { return std::chrono::milliseconds(500); } + static constexpr Seconds didUpdateBackingStoreStateTimeout() { return Seconds::fromMilliseconds(500); } - virtual void waitForPossibleGeometryUpdate(std::chrono::milliseconds = didUpdateBackingStoreStateTimeout()) { } + virtual void waitForPossibleGeometryUpdate(Seconds = didUpdateBackingStoreStateTimeout()) { } virtual void colorSpaceDidChange() { } virtual void minimumLayoutSizeDidChange() { } @@ -74,25 +81,45 @@ public: virtual void commitTransientZoom(double, WebCore::FloatPoint) { } #if PLATFORM(MAC) - void setExposedRect(const WebCore::FloatRect&); - WebCore::FloatRect exposedRect() const { return m_exposedRect; } - void exposedRectChangedTimerFired(WebCore::Timer<DrawingAreaProxy>*); + virtual void setViewExposedRect(std::optional<WebCore::FloatRect>); + std::optional<WebCore::FloatRect> viewExposedRect() const { return m_viewExposedRect; } + void viewExposedRectChangedTimerFired(); +#endif + + virtual void updateDebugIndicator() { } + + virtual void waitForDidUpdateActivityState() { } - void setCustomFixedPositionRect(const WebCore::FloatRect&); + virtual void dispatchAfterEnsuringDrawing(std::function<void (CallbackBase::Error)>) { ASSERT_NOT_REACHED(); } + + // Hide the content until the currently pending update arrives. + virtual void hideContentUntilPendingUpdate() { ASSERT_NOT_REACHED(); } + + // Hide the content until any update arrives. + virtual void hideContentUntilAnyUpdate() { ASSERT_NOT_REACHED(); } + + virtual bool hasVisibleContent() const { return true; } + + virtual void willSendUpdateGeometry() { } + + virtual void prepareForAppSuspension() { } + +#if PLATFORM(COCOA) + virtual WebCore::MachSendRight createFence(); #endif protected: - explicit DrawingAreaProxy(DrawingAreaType, WebPageProxy*); + explicit DrawingAreaProxy(DrawingAreaType, WebPageProxy&); DrawingAreaType m_type; - WebPageProxy* m_webPageProxy; + WebPageProxy& m_webPageProxy; WebCore::IntSize m_size; WebCore::IntSize m_layerPosition; WebCore::IntSize m_scrollOffset; // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; private: virtual void sizeDidChange() = 0; @@ -101,21 +128,26 @@ private: // FIXME: These should be pure virtual. virtual void update(uint64_t /* backingStoreStateID */, const UpdateInfo&) { } virtual void didUpdateBackingStoreState(uint64_t /* backingStoreStateID */, const UpdateInfo&, const LayerTreeContext&) { } -#if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, const LayerTreeContext&) { } virtual void exitAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, const UpdateInfo&) { } virtual void updateAcceleratedCompositingMode(uint64_t /* backingStoreStateID */, const LayerTreeContext&) { } -#endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) virtual void didUpdateGeometry() { } - virtual void intrinsicContentSizeDidChange(const WebCore::IntSize& newIntrinsicContentSize) { } + virtual void intrinsicContentSizeDidChange(const WebCore::IntSize&) { } - WebCore::Timer<DrawingAreaProxy> m_exposedRectChangedTimer; - WebCore::FloatRect m_exposedRect; - WebCore::FloatRect m_lastSentExposedRect; +#if PLATFORM(MAC) + RunLoop::Timer<DrawingAreaProxy> m_viewExposedRectChangedTimer; + std::optional<WebCore::FloatRect> m_viewExposedRect; + std::optional<WebCore::FloatRect> m_lastSentViewExposedRect; +#endif // PLATFORM(MAC) #endif }; } // namespace WebKit +#define SPECIALIZE_TYPE_TRAITS_DRAWING_AREA_PROXY(ToValueTypeName, ProxyType) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebKit::ToValueTypeName) \ + static bool isType(const WebKit::DrawingAreaProxy& proxy) { return proxy.type() == WebKit::ProxyType; } \ +SPECIALIZE_TYPE_TRAITS_END() + #endif // DrawingAreaProxy_h diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in b/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in index a272cb59d..47360e37d 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in @@ -23,13 +23,11 @@ messages -> DrawingAreaProxy { Update(uint64_t stateID, WebKit::UpdateInfo updateInfo) DidUpdateBackingStoreState(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo, WebKit::LayerTreeContext context) -#if USE(ACCELERATED_COMPOSITING) EnterAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::LayerTreeContext context) ExitAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo) UpdateAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::LayerTreeContext context) -#endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Used by TiledCoreAnimationDrawingAreaProxy. DidUpdateGeometry() IntrinsicContentSizeDidChange(WebCore::IntSize newIntrinsicContentSize) diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp index e8c45a709..1445354d7 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp @@ -36,28 +36,22 @@ #include "WebProcessProxy.h" #include <WebCore/Region.h> +#if PLATFORM(GTK) +#include <gtk/gtk.h> +#endif + using namespace WebCore; namespace WebKit { -DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy* webPageProxy) - : DrawingAreaProxy(DrawingAreaTypeImpl, webPageProxy) - , m_currentBackingStoreStateID(0) - , m_nextBackingStoreStateID(0) - , m_isWaitingForDidUpdateBackingStoreState(false) - , m_hasReceivedFirstUpdate(false) - , m_isBackingStoreDiscardable(true) +DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy& webPageProxy) + : AcceleratedDrawingAreaProxy(webPageProxy) , m_discardBackingStoreTimer(RunLoop::current(), this, &DrawingAreaProxyImpl::discardBackingStore) { } DrawingAreaProxyImpl::~DrawingAreaProxyImpl() { -#if USE(ACCELERATED_COMPOSITING) - // Make sure to exit accelerated compositing mode. - if (isInAcceleratedCompositingMode()) - exitAcceleratedCompositingMode(); -#endif } void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, const IntRect& rect, Region& unpaintedRegion) @@ -75,8 +69,8 @@ void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, // If we haven't yet received our first bits from the WebProcess then don't paint anything. if (!m_hasReceivedFirstUpdate) - return; - + return; + if (m_isWaitingForDidUpdateBackingStoreState) { // Wait for a DidUpdateBackingStoreState message that contains the new bits before we paint // what's currently in the backing store. @@ -103,16 +97,6 @@ void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, discardBackingStoreSoon(); } -void DrawingAreaProxyImpl::sizeDidChange() -{ - backingStoreStateDidChange(RespondImmediately); -} - -void DrawingAreaProxyImpl::deviceScaleFactorDidChange() -{ - backingStoreStateDidChange(RespondImmediately); -} - void DrawingAreaProxyImpl::setBackingStoreIsDiscardable(bool isBackingStoreDiscardable) { if (m_isBackingStoreDiscardable == isBackingStoreDiscardable) @@ -125,11 +109,6 @@ void DrawingAreaProxyImpl::setBackingStoreIsDiscardable(bool isBackingStoreDisca m_discardBackingStoreTimer.stop(); } -void DrawingAreaProxyImpl::waitForBackingStoreUpdateOnNextPaint() -{ - m_hasReceivedFirstUpdate = true; -} - void DrawingAreaProxyImpl::update(uint64_t backingStoreStateID, const UpdateInfo& updateInfo) { ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); @@ -139,47 +118,16 @@ void DrawingAreaProxyImpl::update(uint64_t backingStoreStateID, const UpdateInfo // FIXME: Handle the case where the view is hidden. incorporateUpdate(updateInfo); - m_webPageProxy->process().send(Messages::DrawingArea::DidUpdate(), m_webPageProxy->pageID()); + m_webPageProxy.process().send(Messages::DrawingArea::DidUpdate(), m_webPageProxy.pageID()); } void DrawingAreaProxyImpl::didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo& updateInfo, const LayerTreeContext& layerTreeContext) { - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_nextBackingStoreStateID); - ASSERT_ARG(backingStoreStateID, backingStoreStateID > m_currentBackingStoreStateID); - m_currentBackingStoreStateID = backingStoreStateID; - - m_isWaitingForDidUpdateBackingStoreState = false; - - // Stop the responsiveness timer that was started in sendUpdateBackingStoreState. - m_webPageProxy->process().responsivenessTimer()->stop(); - -#if USE(ACCELERATED_COMPOSITING) - if (layerTreeContext != m_layerTreeContext) { - if (!m_layerTreeContext.isEmpty()) { - exitAcceleratedCompositingMode(); - ASSERT(m_layerTreeContext.isEmpty()); - } - - if (!layerTreeContext.isEmpty()) { - enterAcceleratedCompositingMode(layerTreeContext); - ASSERT(layerTreeContext == m_layerTreeContext); - } - } -#endif - - if (m_nextBackingStoreStateID != m_currentBackingStoreStateID) - sendUpdateBackingStoreState(RespondImmediately); - else - m_hasReceivedFirstUpdate = true; - -#if USE(ACCELERATED_COMPOSITING) + AcceleratedDrawingAreaProxy::didUpdateBackingStoreState(backingStoreStateID, updateInfo, layerTreeContext); if (isInAcceleratedCompositingMode()) { ASSERT(!m_backingStore); return; } -#else - UNUSED_PARAM(layerTreeContext); -#endif // If we have a backing store the right size, reuse it. if (m_backingStore && (m_backingStore->size() != updateInfo.viewSize || m_backingStore->deviceScaleFactor() != updateInfo.deviceScaleFactor)) @@ -187,45 +135,17 @@ void DrawingAreaProxyImpl::didUpdateBackingStoreState(uint64_t backingStoreState incorporateUpdate(updateInfo); } -void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) -{ - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); - if (backingStoreStateID < m_currentBackingStoreStateID) - return; - -#if USE(ACCELERATED_COMPOSITING) - enterAcceleratedCompositingMode(layerTreeContext); -#else - UNUSED_PARAM(layerTreeContext); -#endif -} - void DrawingAreaProxyImpl::exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo& updateInfo) { ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); if (backingStoreStateID < m_currentBackingStoreStateID) return; -#if USE(ACCELERATED_COMPOSITING) - exitAcceleratedCompositingMode(); -#endif + AcceleratedDrawingAreaProxy::exitAcceleratedCompositingMode(); incorporateUpdate(updateInfo); } -void DrawingAreaProxyImpl::updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) -{ - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); - if (backingStoreStateID < m_currentBackingStoreStateID) - return; - -#if USE(ACCELERATED_COMPOSITING) - updateAcceleratedCompositingMode(layerTreeContext); -#else - UNUSED_PARAM(layerTreeContext); -#endif -} - void DrawingAreaProxyImpl::incorporateUpdate(const UpdateInfo& updateInfo) { ASSERT(!isInAcceleratedCompositingMode()); @@ -238,124 +158,105 @@ void DrawingAreaProxyImpl::incorporateUpdate(const UpdateInfo& updateInfo) m_backingStore->incorporateUpdate(updateInfo); - bool shouldScroll = !updateInfo.scrollRect.isEmpty(); - - if (shouldScroll) - m_webPageProxy->scrollView(updateInfo.scrollRect, updateInfo.scrollOffset); - - if (shouldScroll && !m_webPageProxy->canScrollView()) - m_webPageProxy->setViewNeedsDisplay(IntRect(IntPoint(), m_webPageProxy->viewSize())); - else { - for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) - m_webPageProxy->setViewNeedsDisplay(updateInfo.updateRects[i]); - } - - if (shouldScroll) - m_webPageProxy->displayView(); + Region damageRegion; + if (updateInfo.scrollRect.isEmpty()) { + for (const auto& rect : updateInfo.updateRects) + damageRegion.unite(rect); + } else + damageRegion = IntRect(IntPoint(), m_webPageProxy.viewSize()); + m_webPageProxy.setViewNeedsDisplay(damageRegion); } -void DrawingAreaProxyImpl::backingStoreStateDidChange(RespondImmediatelyOrNot respondImmediatelyOrNot) +void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - ++m_nextBackingStoreStateID; - sendUpdateBackingStoreState(respondImmediatelyOrNot); + m_backingStore = nullptr; + AcceleratedDrawingAreaProxy::enterAcceleratedCompositingMode(layerTreeContext); } -void DrawingAreaProxyImpl::sendUpdateBackingStoreState(RespondImmediatelyOrNot respondImmediatelyOrNot) +void DrawingAreaProxyImpl::discardBackingStoreSoon() { - ASSERT(m_currentBackingStoreStateID < m_nextBackingStoreStateID); - - if (!m_webPageProxy->isValid()) - return; - - if (m_isWaitingForDidUpdateBackingStoreState) + if (!m_backingStore || !m_isBackingStoreDiscardable || m_discardBackingStoreTimer.isActive()) return; - if (m_webPageProxy->viewSize().isEmpty() && !m_webPageProxy->useFixedLayout()) - return; - - m_isWaitingForDidUpdateBackingStoreState = respondImmediatelyOrNot == RespondImmediately; - - m_webPageProxy->process().send(Messages::DrawingArea::UpdateBackingStoreState(m_nextBackingStoreStateID, respondImmediatelyOrNot == RespondImmediately, m_webPageProxy->deviceScaleFactor(), m_size, m_scrollOffset), m_webPageProxy->pageID()); - m_scrollOffset = IntSize(); - - if (m_isWaitingForDidUpdateBackingStoreState) { - // Start the responsiveness timer. We will stop it when we hear back from the WebProcess - // in didUpdateBackingStoreState. - m_webPageProxy->process().responsivenessTimer()->start(); - } + // We'll wait this many seconds after the last paint before throwing away our backing store to save memory. + // FIXME: It would be smarter to make this delay based on how expensive painting is. See <http://webkit.org/b/55733>. + static const double discardBackingStoreDelay = 2; -#if USE(ACCELERATED_COMPOSITING) - if (m_isWaitingForDidUpdateBackingStoreState && !m_layerTreeContext.isEmpty()) { - // Wait for the DidUpdateBackingStoreState message. Normally we do this in DrawingAreaProxyImpl::paint, but that - // function is never called when in accelerated compositing mode. - waitForAndDispatchDidUpdateBackingStoreState(); - } -#endif + m_discardBackingStoreTimer.startOneShot(discardBackingStoreDelay); } -void DrawingAreaProxyImpl::waitForAndDispatchDidUpdateBackingStoreState() +void DrawingAreaProxyImpl::discardBackingStore() { - ASSERT(m_isWaitingForDidUpdateBackingStoreState); - - if (!m_webPageProxy->isValid()) - return; - if (m_webPageProxy->process().isLaunching()) + if (!m_backingStore) return; - -#if USE(ACCELERATED_COMPOSITING) - // FIXME: waitForAndDispatchImmediately will always return the oldest DidUpdateBackingStoreState message that - // hasn't yet been processed. But it might be better to skip ahead to some other DidUpdateBackingStoreState - // message, if multiple DidUpdateBackingStoreState messages are waiting to be processed. For instance, we could - // choose the most recent one, or the one that is closest to our current size. - - // The timeout we use when waiting for a DidUpdateBackingStoreState message when we're asked to paint is 500 milliseconds. - m_webPageProxy->process().connection()->waitForAndDispatchImmediately<Messages::DrawingAreaProxy::DidUpdateBackingStoreState>(m_webPageProxy->pageID(), std::chrono::milliseconds(500)); -#endif + m_backingStore = nullptr; + backingStoreStateDidChange(DoNotRespondImmediately); } -#if USE(ACCELERATED_COMPOSITING) -void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor(WebPageProxy& webPage) + : m_webPage(webPage) + , m_timer(RunLoop::main(), this, &DrawingMonitor::stop) { - ASSERT(!isInAcceleratedCompositingMode()); - - m_backingStore = nullptr; - m_layerTreeContext = layerTreeContext; - m_webPageProxy->enterAcceleratedCompositingMode(layerTreeContext); } -void DrawingAreaProxyImpl::exitAcceleratedCompositingMode() +DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor() { - ASSERT(isInAcceleratedCompositingMode()); - - m_layerTreeContext = LayerTreeContext(); - m_webPageProxy->exitAcceleratedCompositingMode(); + m_callback = nullptr; + stop(); } -void DrawingAreaProxyImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +int DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback(DrawingAreaProxyImpl::DrawingMonitor* monitor) { - ASSERT(isInAcceleratedCompositingMode()); - - m_layerTreeContext = layerTreeContext; - m_webPageProxy->updateAcceleratedCompositingMode(layerTreeContext); + monitor->didDraw(); + return FALSE; } -#endif -void DrawingAreaProxyImpl::discardBackingStoreSoon() +void DrawingAreaProxyImpl::DrawingMonitor::start(std::function<void (CallbackBase::Error)> callback) { - if (!m_isBackingStoreDiscardable || m_discardBackingStoreTimer.isActive()) - return; + m_startTime = monotonicallyIncreasingTimeMS(); + m_callback = callback; +#if PLATFORM(GTK) + g_signal_connect_swapped(m_webPage.viewWidget(), "draw", reinterpret_cast<GCallback>(webViewDrawCallback), this); + m_timer.startOneShot(1); +#else + m_timer.startOneShot(0); +#endif +} - // We'll wait this many seconds after the last paint before throwing away our backing store to save memory. - // FIXME: It would be smarter to make this delay based on how expensive painting is. See <http://webkit.org/b/55733>. - static const double discardBackingStoreDelay = 2; +void DrawingAreaProxyImpl::DrawingMonitor::stop() +{ + m_timer.stop(); +#if PLATFORM(GTK) + g_signal_handlers_disconnect_by_func(m_webPage.viewWidget(), reinterpret_cast<gpointer>(webViewDrawCallback), this); +#endif + m_startTime = 0; + if (m_callback) { + m_callback(CallbackBase::Error::None); + m_callback = nullptr; + } +} - m_discardBackingStoreTimer.startOneShot(discardBackingStoreDelay); +void DrawingAreaProxyImpl::DrawingMonitor::didDraw() +{ + // We wait up to 1 second for draw events. If there are several draw events queued quickly, + // we want to wait until all of them have been processed, so after receiving a draw, we wait + // up to 100ms for the next one or stop. + if (monotonicallyIncreasingTimeMS() - m_startTime > 1000) + stop(); + else + m_timer.startOneShot(0.100); } -void DrawingAreaProxyImpl::discardBackingStore() +void DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)> callbackFunction) { - m_backingStore = nullptr; - backingStoreStateDidChange(DoNotRespondImmediately); + if (!m_webPageProxy.isValid()) { + callbackFunction(CallbackBase::Error::OwnerWasInvalidated); + return; + } + + if (!m_drawingMonitor) + m_drawingMonitor = std::make_unique<DrawingAreaProxyImpl::DrawingMonitor>(m_webPageProxy); + m_drawingMonitor->start(callbackFunction); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h index 224ea9109..89c713fc8 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h @@ -26,10 +26,9 @@ #ifndef DrawingAreaProxyImpl_h #define DrawingAreaProxyImpl_h +#include "AcceleratedDrawingAreaProxy.h" #include "BackingStore.h" #include "DrawingAreaProxy.h" -#include "LayerTreeContext.h" -#include <wtf/OwnPtr.h> #include <wtf/RunLoop.h> namespace WebCore { @@ -38,77 +37,55 @@ class Region; namespace WebKit { -class DrawingAreaProxyImpl : public DrawingAreaProxy { +class DrawingAreaProxyImpl final : public AcceleratedDrawingAreaProxy { public: - explicit DrawingAreaProxyImpl(WebPageProxy*); + explicit DrawingAreaProxyImpl(WebPageProxy&); virtual ~DrawingAreaProxyImpl(); void paint(BackingStore::PlatformGraphicsContext, const WebCore::IntRect&, WebCore::Region& unpaintedRegion); -#if USE(ACCELERATED_COMPOSITING) - bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); } -#endif - - bool hasReceivedFirstUpdate() const { return m_hasReceivedFirstUpdate; } - private: // DrawingAreaProxy - virtual void sizeDidChange(); - virtual void deviceScaleFactorDidChange(); - - virtual void setBackingStoreIsDiscardable(bool); - virtual void waitForBackingStoreUpdateOnNextPaint(); + void setBackingStoreIsDiscardable(bool) override; // IPC message handlers - virtual void update(uint64_t backingStoreStateID, const UpdateInfo&); - virtual void didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo&, const LayerTreeContext&); - virtual void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&); - virtual void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&); - virtual void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&); + void update(uint64_t backingStoreStateID, const UpdateInfo&) override; + void didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo&, const LayerTreeContext&) override; + void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) override; void incorporateUpdate(const UpdateInfo&); - enum RespondImmediatelyOrNot { DoNotRespondImmediately, RespondImmediately }; - void backingStoreStateDidChange(RespondImmediatelyOrNot); - void sendUpdateBackingStoreState(RespondImmediatelyOrNot); - void waitForAndDispatchDidUpdateBackingStoreState(); - -#if USE(ACCELERATED_COMPOSITING) - void enterAcceleratedCompositingMode(const LayerTreeContext&); - void exitAcceleratedCompositingMode(); - void updateAcceleratedCompositingMode(const LayerTreeContext&); -#else - bool isInAcceleratedCompositingMode() const { return false; } -#endif + void enterAcceleratedCompositingMode(const LayerTreeContext&) override; void discardBackingStoreSoon(); void discardBackingStore(); - // The state ID corresponding to our current backing store. Updated whenever we allocate - // a new backing store. Any messages received that correspond to an earlier state are ignored, - // as they don't apply to our current backing store. - uint64_t m_currentBackingStoreStateID; + void dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)>) override; - // The next backing store state ID we will request the web process update to. Incremented - // whenever our state changes in a way that will require a new backing store to be allocated. - uint64_t m_nextBackingStoreStateID; + class DrawingMonitor { + WTF_MAKE_NONCOPYABLE(DrawingMonitor); WTF_MAKE_FAST_ALLOCATED; + public: + DrawingMonitor(WebPageProxy&); + ~DrawingMonitor(); -#if USE(ACCELERATED_COMPOSITING) - // The current layer tree context. - LayerTreeContext m_layerTreeContext; -#endif + void start(std::function<void (CallbackBase::Error)>); - // Whether we've sent a UpdateBackingStoreState message and are now waiting for a DidUpdateBackingStoreState message. - // Used to throttle UpdateBackingStoreState messages so we don't send them faster than the Web process can handle. - bool m_isWaitingForDidUpdateBackingStoreState; - - // For a new Drawing Area don't draw anything until the WebProcess has sent over the first content. - bool m_hasReceivedFirstUpdate; + private: + static int webViewDrawCallback(DrawingMonitor*); - bool m_isBackingStoreDiscardable; - std::unique_ptr<BackingStore> m_backingStore; + void stop(); + void didDraw(); + + WebPageProxy& m_webPage; + double m_startTime { 0 }; + std::function<void (CallbackBase::Error)> m_callback; + RunLoop::Timer<DrawingMonitor> m_timer; + }; + bool m_isBackingStoreDiscardable { true }; + std::unique_ptr<BackingStore> m_backingStore; RunLoop::Timer<DrawingAreaProxyImpl> m_discardBackingStoreTimer; + std::unique_ptr<DrawingMonitor> m_drawingMonitor; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/FindIndicator.cpp b/Source/WebKit2/UIProcess/FindIndicator.cpp deleted file mode 100644 index 2ad193f1b..000000000 --- a/Source/WebKit2/UIProcess/FindIndicator.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "FindIndicator.h" - -#include "ShareableBitmap.h" -#include <WebCore/Gradient.h> -#include <WebCore/GraphicsContext.h> -#include <WebCore/IntRect.h> -#include <WebCore/Path.h> - -using namespace WebCore; - -static const float cornerRadius = 3.0; - -static const float shadowOffsetX = 0.0; -static const float shadowOffsetY = 1.0; -static const float shadowBlurRadius = 3.0; - -static const int shadowRed = 0; -static const int shadowGreen = 0; -static const int shadowBlue = 0; -static const int shadowAlpha = 204; - -static const float lightBorderThickness = 1.0; -static const float horizontalPaddingInsideLightBorder = 3.0; -static const float verticalPaddingInsideLightBorder = 1.0; - -static const float horizontalBorderInsideShadow = lightBorderThickness + horizontalPaddingInsideLightBorder; -static const float verticalBorderInsideShadow = lightBorderThickness + verticalPaddingInsideLightBorder; - -static const float leftBorderThickness = horizontalBorderInsideShadow + shadowOffsetX + shadowBlurRadius / 2.0; -static const float topBorderThickness = verticalBorderInsideShadow - shadowOffsetY + shadowBlurRadius / 2.0; -static const float rightBorderThickness = horizontalBorderInsideShadow - shadowOffsetX + shadowBlurRadius / 2.0; -static const float bottomBorderThickness = verticalBorderInsideShadow + shadowOffsetY + shadowBlurRadius / 2.0; - -static const float horizontalOutsetToCenterOfLightBorder = horizontalBorderInsideShadow - lightBorderThickness / 2.0; -static const float verticalOutsetToCenterOfLightBorder = verticalBorderInsideShadow - lightBorderThickness / 2.0; - -static const int lightBorderRed = 245; -static const int lightBorderGreen = 230; -static const int lightBorderBlue = 0; -static const int lightBorderAlpha = 255; - -static const int gradientDarkRed = 237; -static const int gradientDarkGreen = 204; -static const int gradientDarkBlue = 0; -static const int gradientDarkAlpha = 255; - -static const int gradientLightRed = 242; -static const int gradientLightGreen = 239; -static const int gradientLightBlue = 0; -static const int gradientLightAlpha = 255; - -namespace WebKit { - -PassRefPtr<FindIndicator> FindIndicator::create(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle) -{ - RefPtr<ShareableBitmap> contentImage = ShareableBitmap::create(contentImageHandle); - if (!contentImage) - return 0; - ASSERT(contentImageScaleFactor != 1 || contentImage->size() == enclosingIntRect(selectionRectInWindowCoordinates).size()); - - return adoptRef(new FindIndicator(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImage.release())); -} - -static bool findIndicatorsForTextRectsOverlap(const Vector<FloatRect>& textRects) -{ - size_t count = textRects.size(); - if (count <= 1) - return false; - - Vector<FloatRect> indicatorRects; - indicatorRects.reserveInitialCapacity(count); - - for (size_t i = 0; i < count; ++i) { - FloatRect indicatorRect = textRects[i]; - indicatorRect.move(-leftBorderThickness, -topBorderThickness); - indicatorRect.expand(leftBorderThickness + rightBorderThickness, topBorderThickness + bottomBorderThickness); - - for (size_t j = indicatorRects.size(); j; ) { - --j; - if (indicatorRect.intersects(indicatorRects[j])) - return true; - } - - indicatorRects.uncheckedAppend(indicatorRect); - } - - return false; -} - -FindIndicator::FindIndicator(const WebCore::FloatRect& selectionRectInWindowCoordinates, const Vector<WebCore::FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, PassRefPtr<ShareableBitmap> contentImage) - : m_selectionRectInWindowCoordinates(selectionRectInWindowCoordinates) - , m_textRectsInSelectionRectCoordinates(textRectsInSelectionRectCoordinates) - , m_contentImageScaleFactor(contentImageScaleFactor) - , m_contentImage(contentImage) -{ - if (findIndicatorsForTextRectsOverlap(m_textRectsInSelectionRectCoordinates)) { - m_textRectsInSelectionRectCoordinates[0] = unionRect(m_textRectsInSelectionRectCoordinates); - m_textRectsInSelectionRectCoordinates.shrink(1); - } -} - -FindIndicator::~FindIndicator() -{ -} - -static FloatRect inflateRect(const FloatRect& rect, float inflateX, float inflateY) -{ - FloatRect inflatedRect = rect; - inflatedRect.inflateX(inflateX); - inflatedRect.inflateY(inflateY); - - return inflatedRect; -} - -FloatRect FindIndicator::frameRect() const -{ - return FloatRect(m_selectionRectInWindowCoordinates.x() - leftBorderThickness, m_selectionRectInWindowCoordinates.y() - topBorderThickness, - m_selectionRectInWindowCoordinates.width() + rightBorderThickness + leftBorderThickness, - m_selectionRectInWindowCoordinates.height() + topBorderThickness + bottomBorderThickness); -} - -static Color lightBorderColor() -{ - return Color(lightBorderRed, lightBorderGreen, lightBorderBlue, lightBorderAlpha); -} - -static Color shadowColor() -{ - return Color(shadowRed, shadowGreen, shadowBlue, shadowAlpha); -} - -static Color gradientLightColor() -{ - return Color(gradientLightRed, gradientLightGreen, gradientLightBlue, gradientLightAlpha); -} - -static Color gradientDarkColor() -{ - return Color(gradientDarkRed, gradientDarkGreen, gradientDarkBlue, gradientDarkAlpha); -} - -static Path pathWithRoundedRect(const FloatRect& pathRect, float radius) -{ - Path path; - path.addRoundedRect(pathRect, FloatSize(radius, radius)); - - return path; -} - -void FindIndicator::draw(GraphicsContext& graphicsContext, const IntRect& /*dirtyRect*/) -{ - for (size_t i = 0; i < m_textRectsInSelectionRectCoordinates.size(); ++i) { - FloatRect textRect = m_textRectsInSelectionRectCoordinates[i]; - textRect.move(leftBorderThickness, topBorderThickness); - - FloatRect outerPathRect = inflateRect(textRect, horizontalOutsetToCenterOfLightBorder, verticalOutsetToCenterOfLightBorder); - FloatRect innerPathRect = inflateRect(textRect, horizontalPaddingInsideLightBorder, verticalPaddingInsideLightBorder); - - { - GraphicsContextStateSaver stateSaver(graphicsContext); - graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, shadowColor(), ColorSpaceSRGB); - graphicsContext.setFillColor(lightBorderColor(), ColorSpaceDeviceRGB); - graphicsContext.fillPath(pathWithRoundedRect(outerPathRect, cornerRadius)); - } - - { - GraphicsContextStateSaver stateSaver(graphicsContext); - graphicsContext.clip(pathWithRoundedRect(innerPathRect, cornerRadius)); - RefPtr<Gradient> gradient = Gradient::create(FloatPoint(innerPathRect.x(), innerPathRect.y()), FloatPoint(innerPathRect.x(), innerPathRect.maxY())); - gradient->addColorStop(0, gradientLightColor()); - gradient->addColorStop(1, gradientDarkColor()); - graphicsContext.setFillGradient(gradient); - graphicsContext.fillRect(outerPathRect); - } - - { - GraphicsContextStateSaver stateSaver(graphicsContext); - graphicsContext.translate(FloatSize(roundf(leftBorderThickness), roundf(topBorderThickness))); - - IntRect contentImageRect = enclosingIntRect(m_textRectsInSelectionRectCoordinates[i]); - m_contentImage->paint(graphicsContext, m_contentImageScaleFactor, contentImageRect.location(), contentImageRect); - } - } -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/FindIndicator.h b/Source/WebKit2/UIProcess/FindIndicator.h deleted file mode 100644 index a34973b84..000000000 --- a/Source/WebKit2/UIProcess/FindIndicator.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FindIndicator_h -#define FindIndicator_h - -#include "ShareableBitmap.h" -#include <WebCore/FloatRect.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> - -namespace WebCore { - class GraphicsContext; -} - -namespace WebKit { - -class FindIndicator : public RefCounted<FindIndicator> { -public: - static PassRefPtr<FindIndicator> create(const WebCore::FloatRect& selectionRectInWindowCoordinates, const Vector<WebCore::FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle); - ~FindIndicator(); - - WebCore::FloatRect selectionRectInWindowCoordinates() const { return m_selectionRectInWindowCoordinates; } - WebCore::FloatRect frameRect() const; - - ShareableBitmap* contentImage() const { return m_contentImage.get(); } - - void draw(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect); - -private: - FindIndicator(const WebCore::FloatRect& selectionRect, const Vector<WebCore::FloatRect>& textRects, float contentImageScaleFactor, PassRefPtr<ShareableBitmap> contentImage); - - WebCore::FloatRect m_selectionRectInWindowCoordinates; - Vector<WebCore::FloatRect> m_textRectsInSelectionRectCoordinates; - float m_contentImageScaleFactor; - RefPtr<ShareableBitmap> m_contentImage; -}; - -} // namespace WebKit - -#endif // FindIndicator_h diff --git a/Source/WebKit2/UIProcess/FrameLoadState.h b/Source/WebKit2/UIProcess/FrameLoadState.h index 547811e9b..2d359b8d1 100644 --- a/Source/WebKit2/UIProcess/FrameLoadState.h +++ b/Source/WebKit2/UIProcess/FrameLoadState.h @@ -51,10 +51,14 @@ public: void didSameDocumentNotification(const String&); + State state() const { return m_state; } + const String& url() const { return m_url; } + const String& provisionalURL() const { return m_provisionalURL; } + void setUnreachableURL(const String&); + const String& unreachableURL() const { return m_unreachableURL; } - // FIXME: These should all be private, and FrameLoadState should - // provide state transition member functions. +private: State m_state; String m_url; String m_provisionalURL; diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp new file mode 100644 index 000000000..5c0b320f8 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UIGamepad.h" + +#if ENABLE(GAMEPAD) + +#include "GamepadData.h" +#include <WebCore/PlatformGamepad.h> + +using namespace WebCore; + +namespace WebKit { + +UIGamepad::UIGamepad(WebCore::PlatformGamepad& platformGamepad) + : m_index(platformGamepad.index()) + , m_id(platformGamepad.id()) + , m_lastUpdateTime(platformGamepad.lastUpdateTime()) +{ + m_axisValues.resize(platformGamepad.axisValues().size()); + m_buttonValues.resize(platformGamepad.buttonValues().size()); + + updateFromPlatformGamepad(platformGamepad); +} + +void UIGamepad::updateFromPlatformGamepad(WebCore::PlatformGamepad& platformGamepad) +{ + ASSERT(m_index == platformGamepad.index()); + ASSERT(m_axisValues.size() == platformGamepad.axisValues().size()); + ASSERT(m_buttonValues.size() == platformGamepad.buttonValues().size()); + + m_axisValues = platformGamepad.axisValues(); + m_buttonValues = platformGamepad.buttonValues(); + m_lastUpdateTime = platformGamepad.lastUpdateTime(); +} + +GamepadData UIGamepad::condensedGamepadData() const +{ + return { m_index, m_axisValues, m_buttonValues, m_lastUpdateTime }; +} + +GamepadData UIGamepad::fullGamepadData() const +{ + return { m_index, m_id, m_axisValues, m_buttonValues, m_lastUpdateTime }; +} + + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h new file mode 100644 index 000000000..0c47e8561 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class PlatformGamepad; +} + +namespace WebKit { + +class GamepadData; + +class UIGamepad { +public: + UIGamepad(WebCore::PlatformGamepad&); + + unsigned index() const { return m_index; } + + GamepadData condensedGamepadData() const; + GamepadData fullGamepadData() const; + + void updateFromPlatformGamepad(WebCore::PlatformGamepad&); + +private: + unsigned m_index; + String m_id; + Vector<double> m_axisValues; + Vector<double> m_buttonValues; + double m_lastUpdateTime; +}; + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp new file mode 100644 index 000000000..657c416f9 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UIGamepadProvider.h" + +#if ENABLE(GAMEPAD) + +#include "GamepadData.h" +#include "UIGamepad.h" +#include "WebProcessPool.h" +#include <WebCore/MockGamepadProvider.h> +#include <WebCore/PlatformGamepad.h> +#include <wtf/NeverDestroyed.h> + +using namespace WebCore; + +namespace WebKit { + +static const double maximumGamepadUpdateInterval = 1 / 120.0; + +UIGamepadProvider& UIGamepadProvider::singleton() +{ + static NeverDestroyed<UIGamepadProvider> sharedProvider; + return sharedProvider; +} + +UIGamepadProvider::UIGamepadProvider() + : m_gamepadSyncTimer(RunLoop::main(), this, &UIGamepadProvider::gamepadSyncTimerFired) +{ + platformSetDefaultGamepadProvider(); +} + +UIGamepadProvider::~UIGamepadProvider() +{ + if (!m_processPoolsUsingGamepads.isEmpty()) + GamepadProvider::singleton().stopMonitoringGamepads(*this); +} + +void UIGamepadProvider::gamepadSyncTimerFired() +{ + auto webPageProxy = platformWebPageProxyForGamepadInput(); + if (!webPageProxy || !m_processPoolsUsingGamepads.contains(&webPageProxy->process().processPool())) + return; + + webPageProxy->gamepadActivity(snapshotGamepads(), m_shouldMakeGamepadsVisibleOnSync); + m_shouldMakeGamepadsVisibleOnSync = false; +} + +void UIGamepadProvider::scheduleGamepadStateSync() +{ + if (!m_isMonitoringGamepads || m_gamepadSyncTimer.isActive()) + return; + + if (m_gamepads.isEmpty() || m_processPoolsUsingGamepads.isEmpty()) { + m_gamepadSyncTimer.stop(); + return; + } + + m_gamepadSyncTimer.startOneShot(maximumGamepadUpdateInterval); +} + +void UIGamepadProvider::setInitialConnectedGamepads(const Vector<PlatformGamepad*>& initialGamepads) +{ + ASSERT(!m_hasInitialGamepads); + + m_gamepads.resize(initialGamepads.size()); + + for (auto* gamepad : initialGamepads) { + if (!gamepad) + continue; + m_gamepads[gamepad->index()] = std::make_unique<UIGamepad>(*gamepad); + } + + for (auto& pool : m_processPoolsUsingGamepads) + pool->setInitialConnectedGamepads(m_gamepads); + + m_hasInitialGamepads = true; +} + +void UIGamepadProvider::platformGamepadConnected(PlatformGamepad& gamepad) +{ + if (m_gamepads.size() <= gamepad.index()) + m_gamepads.resize(gamepad.index() + 1); + + ASSERT(!m_gamepads[gamepad.index()]); + m_gamepads[gamepad.index()] = std::make_unique<UIGamepad>(gamepad); + + scheduleGamepadStateSync(); + + for (auto& pool : m_processPoolsUsingGamepads) + pool->gamepadConnected(*m_gamepads[gamepad.index()]); +} + +void UIGamepadProvider::platformGamepadDisconnected(PlatformGamepad& gamepad) +{ + ASSERT(gamepad.index() < m_gamepads.size()); + ASSERT(m_gamepads[gamepad.index()]); + + std::unique_ptr<UIGamepad> disconnectedGamepad = WTFMove(m_gamepads[gamepad.index()]); + + scheduleGamepadStateSync(); + + for (auto& pool : m_processPoolsUsingGamepads) + pool->gamepadDisconnected(*disconnectedGamepad); +} + +void UIGamepadProvider::platformGamepadInputActivity(bool shouldMakeGamepadsVisible) +{ + auto platformGamepads = GamepadProvider::singleton().platformGamepads(); + ASSERT(platformGamepads.size() == m_gamepads.size()); + + for (size_t i = 0; i < platformGamepads.size(); ++i) { + if (!platformGamepads[i]) { + ASSERT(!m_gamepads[i]); + continue; + } + + ASSERT(m_gamepads[i]); + m_gamepads[i]->updateFromPlatformGamepad(*platformGamepads[i]); + } + + if (shouldMakeGamepadsVisible) + m_shouldMakeGamepadsVisibleOnSync = true; + + scheduleGamepadStateSync(); +} + +void UIGamepadProvider::processPoolStartedUsingGamepads(WebProcessPool& pool) +{ + ASSERT(!m_processPoolsUsingGamepads.contains(&pool)); + m_processPoolsUsingGamepads.add(&pool); + + if (!m_isMonitoringGamepads && platformWebPageProxyForGamepadInput()) + startMonitoringGamepads(); +} + +void UIGamepadProvider::processPoolStoppedUsingGamepads(WebProcessPool& pool) +{ + ASSERT(m_processPoolsUsingGamepads.contains(&pool)); + m_processPoolsUsingGamepads.remove(&pool); + + if (m_isMonitoringGamepads && !platformWebPageProxyForGamepadInput()) + platformStopMonitoringInput(); +} + +void UIGamepadProvider::viewBecameActive(WebPageProxy& page) +{ + if (!m_processPoolsUsingGamepads.contains(&page.process().processPool())) + return; + + if (!m_isMonitoringGamepads) + startMonitoringGamepads(); + + if (platformWebPageProxyForGamepadInput()) + platformStartMonitoringInput(); +} + +void UIGamepadProvider::viewBecameInactive(WebPageProxy& page) +{ + auto pageForGamepadInput = platformWebPageProxyForGamepadInput(); + if (pageForGamepadInput == &page) + platformStopMonitoringInput(); +} + +void UIGamepadProvider::startMonitoringGamepads() +{ + if (m_isMonitoringGamepads) + return; + + m_isMonitoringGamepads = true; + ASSERT(!m_processPoolsUsingGamepads.isEmpty()); + GamepadProvider::singleton().startMonitoringGamepads(*this); +} + +void UIGamepadProvider::stopMonitoringGamepads() +{ + if (!m_isMonitoringGamepads) + return; + + m_isMonitoringGamepads = false; + + ASSERT(m_processPoolsUsingGamepads.isEmpty()); + GamepadProvider::singleton().stopMonitoringGamepads(*this); + + m_gamepads.clear(); +} + +Vector<GamepadData> UIGamepadProvider::snapshotGamepads() +{ + Vector<GamepadData> gamepadDatas; + gamepadDatas.reserveInitialCapacity(m_gamepads.size()); + + for (auto& gamepad : m_gamepads) { + if (gamepad) + gamepadDatas.uncheckedAppend(gamepad->condensedGamepadData()); + else + gamepadDatas.uncheckedAppend({ }); + } + + return gamepadDatas; +} + +#if !PLATFORM(COCOA) + +void UIGamepadProvider::platformSetDefaultGamepadProvider() +{ + // FIXME: Implement for other platforms +} + +WebPageProxy* UIGamepadProvider::platformWebPageProxyForGamepadInput() +{ + // FIXME: Implement for other platforms + return nullptr; +} + +void UIGamepadProvider::platformStopMonitoringInput() +{ +} + +void UIGamepadProvider::platformStartMonitoringInput() +{ +} + +#endif // !PLATFORM(MAC) + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h new file mode 100644 index 000000000..e076c2f33 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <WebCore/GamepadProviderClient.h> +#include <wtf/HashSet.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/RunLoop.h> +#include <wtf/Vector.h> + +namespace WebKit { + +class UIGamepad; +class WebPageProxy; +class WebProcessPool; +class GamepadData; + +class UIGamepadProvider : public WebCore::GamepadProviderClient { +public: + static UIGamepadProvider& singleton(); + + void processPoolStartedUsingGamepads(WebProcessPool&); + void processPoolStoppedUsingGamepads(WebProcessPool&); + + void viewBecameActive(WebPageProxy&); + void viewBecameInactive(WebPageProxy&); + + Vector<GamepadData> gamepadStates() const; + +#if PLATFORM(COCOA) + static void setUsesGameControllerFramework(); +#endif + + Vector<GamepadData> snapshotGamepads(); + +private: + friend NeverDestroyed<UIGamepadProvider>; + UIGamepadProvider(); + ~UIGamepadProvider() final; + + void startMonitoringGamepads(); + void stopMonitoringGamepads(); + + void platformSetDefaultGamepadProvider(); + WebPageProxy* platformWebPageProxyForGamepadInput(); + void platformStopMonitoringInput(); + void platformStartMonitoringInput(); + + void setInitialConnectedGamepads(const Vector<WebCore::PlatformGamepad*>&) final; + void platformGamepadConnected(WebCore::PlatformGamepad&) final; + void platformGamepadDisconnected(WebCore::PlatformGamepad&) final; + void platformGamepadInputActivity(bool shouldMakeGamepadsVisible) final; + + void scheduleGamepadStateSync(); + void gamepadSyncTimerFired(); + + HashSet<WebProcessPool*> m_processPoolsUsingGamepads; + + Vector<std::unique_ptr<UIGamepad>> m_gamepads; + + RunLoop::Timer<UIGamepadProvider> m_gamepadSyncTimer; + + bool m_isMonitoringGamepads { false }; + bool m_hasInitialGamepads { false }; + bool m_shouldMakeGamepadsVisibleOnSync { false }; +}; + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/GenericCallback.h b/Source/WebKit2/UIProcess/GenericCallback.h index 907e61589..1b67e9384 100644 --- a/Source/WebKit2/UIProcess/GenericCallback.h +++ b/Source/WebKit2/UIProcess/GenericCallback.h @@ -27,231 +27,195 @@ #define GenericCallback_h #include "APIError.h" +#include "APISerializedScriptValue.h" +#include "ProcessThrottler.h" #include "ShareableBitmap.h" #include "WKAPICast.h" +#include <functional> #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/RunLoop.h> namespace WebKit { class CallbackBase : public RefCounted<CallbackBase> { public: + enum class Error { + None, + Unknown, + ProcessExited, + OwnerWasInvalidated, + }; + virtual ~CallbackBase() { } uint64_t callbackID() const { return m_callbackID; } + template<class T> + T* as() + { + if (T::type() == m_type) + return static_cast<T*>(this); + + return nullptr; + } + + virtual void invalidate(Error) = 0; + protected: - explicit CallbackBase(void* context) - : m_context(context) + struct TypeTag { }; + typedef const TypeTag* Type; + + explicit CallbackBase(Type type, const ProcessThrottler::BackgroundActivityToken& activityToken) + : m_type(type) , m_callbackID(generateCallbackID()) + , m_activityToken(activityToken) { } - void* context() const { return m_context; } - private: static uint64_t generateCallbackID() { + ASSERT(RunLoop::isMain()); static uint64_t uniqueCallbackID = 1; return uniqueCallbackID++; } - void* m_context; + Type m_type; uint64_t m_callbackID; + ProcessThrottler::BackgroundActivityToken m_activityToken; }; -class VoidCallback : public CallbackBase { +template<typename... T> +class GenericCallback : public CallbackBase { public: - typedef void (*CallbackFunction)(WKErrorRef, void*); + typedef std::function<void (T..., Error)> CallbackFunction; - static PassRefPtr<VoidCallback> create(void* context, CallbackFunction callback) + static PassRefPtr<GenericCallback> create(CallbackFunction callback, const ProcessThrottler::BackgroundActivityToken& activityToken = nullptr) { - return adoptRef(new VoidCallback(context, callback)); + return adoptRef(new GenericCallback(callback, activityToken)); } - virtual ~VoidCallback() + virtual ~GenericCallback() { ASSERT(!m_callback); } - void performCallback() + void performCallbackWithReturnValue(T... returnValue) { if (!m_callback) return; - m_callback(0, context()); + m_callback(returnValue..., Error::None); - m_callback = 0; - } - - void invalidate() - { - if (!m_callback) - return; - - RefPtr<API::Error> error = API::Error::create(); - m_callback(toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - VoidCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { + m_callback = nullptr; } - CallbackFunction m_callback; -}; - -template<typename APIReturnValueType, typename InternalReturnValueType = typename APITypeInfo<APIReturnValueType>::ImplType> -class GenericCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(APIReturnValueType, WKErrorRef, void*); - - static PassRefPtr<GenericCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new GenericCallback(context, callback)); - } - - virtual ~GenericCallback() + void performCallback() { - ASSERT(!m_callback); + performCallbackWithReturnValue(); } - void performCallbackWithReturnValue(InternalReturnValueType returnValue) + void invalidate(Error error = Error::Unknown) final { - ASSERT(m_callback); - - m_callback(toAPI(returnValue), 0, context()); + if (!m_callback) + return; - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); + m_callback(typename std::remove_reference<T>::type()..., error); - RefPtr<API::Error> error = API::Error::create(); - m_callback(0, toAPI(error.get()), context()); - - m_callback = 0; + m_callback = nullptr; } private: - GenericCallback(void* context, CallbackFunction callback) - : CallbackBase(context) + GenericCallback(CallbackFunction callback, const ProcessThrottler::BackgroundActivityToken& activityToken) + : CallbackBase(type(), activityToken) , m_callback(callback) { } - CallbackFunction m_callback; -}; - -// FIXME: Make a version of CallbackBase with two arguments, and define ComputedPagesCallback as a specialization. -class ComputedPagesCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const Vector<WebCore::IntRect>&, double, WKErrorRef, void*); - - static PassRefPtr<ComputedPagesCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new ComputedPagesCallback(context, callback)); - } - - virtual ~ComputedPagesCallback() + friend class CallbackBase; + static Type type() { - ASSERT(!m_callback); + static TypeTag tag; + return &tag; } - void performCallbackWithReturnValue(const Vector<WebCore::IntRect>& returnValue1, double returnValue2) - { - ASSERT(m_callback); + CallbackFunction m_callback; +}; - m_callback(returnValue1, returnValue2, 0, context()); +template<typename APIReturnValueType, typename InternalReturnValueType = typename APITypeInfo<APIReturnValueType>::ImplType*> +static typename GenericCallback<InternalReturnValueType>::CallbackFunction toGenericCallbackFunction(void* context, void (*callback)(APIReturnValueType, WKErrorRef, void*)) +{ + return [context, callback](InternalReturnValueType returnValue, CallbackBase::Error error) { + callback(toAPI(returnValue), error != CallbackBase::Error::None ? toAPI(API::Error::create().ptr()) : 0, context); + }; +} - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); +typedef GenericCallback<> VoidCallback; +typedef GenericCallback<const Vector<WebCore::IntRect>&, double> ComputedPagesCallback; +typedef GenericCallback<const ShareableBitmap::Handle&> ImageCallback; - RefPtr<API::Error> error = API::Error::create(); - m_callback(Vector<WebCore::IntRect>(), 0, toAPI(error.get()), context()); - - m_callback = 0; - } +template<typename T> +void invalidateCallbackMap(HashMap<uint64_t, T>& callbackMap, CallbackBase::Error error) +{ + Vector<T> callbacks; + copyValuesToVector(callbackMap, callbacks); + for (auto& callback : callbacks) + callback->invalidate(error); -private: + callbackMap.clear(); +} - ComputedPagesCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) +class CallbackMap { +public: + uint64_t put(PassRefPtr<CallbackBase> callback) { - } + ASSERT(!m_map.contains(callback->callbackID())); - CallbackFunction m_callback; -}; + uint64_t callbackID = callback->callbackID(); + m_map.set(callbackID, callback); + return callbackID; + } -class ImageCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const ShareableBitmap::Handle&, WKErrorRef, void*); + template<unsigned I, typename T, typename... U> + struct GenericCallbackType { + typedef typename GenericCallbackType<I - 1, U..., T>::type type; + }; - static PassRefPtr<ImageCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new ImageCallback(context, callback)); - } + template<typename... U> + struct GenericCallbackType<1, CallbackBase::Error, U...> { + typedef GenericCallback<U...> type; + }; - virtual ~ImageCallback() + template<typename... T> + uint64_t put(std::function<void (T...)> function, const ProcessThrottler::BackgroundActivityToken& activityToken) { - ASSERT(!m_callback); + auto callback = GenericCallbackType<sizeof...(T), T...>::type::create(WTFMove(function), activityToken); + return put(callback); } - void performCallbackWithReturnValue(const ShareableBitmap::Handle& returnValue1) + template<class T> + RefPtr<T> take(uint64_t callbackID) { - ASSERT(m_callback); + auto base = m_map.take(callbackID); + if (!base) + return nullptr; - m_callback(returnValue1, 0, context()); - - m_callback = 0; + return adoptRef(base.leakRef()->as<T>()); } - void invalidate() + void invalidate(CallbackBase::Error error) { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - ShareableBitmap::Handle handle; - m_callback(handle, toAPI(error.get()), context()); - - m_callback = 0; + invalidateCallbackMap(m_map, error); } private: - - ImageCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - } - - CallbackFunction m_callback; + HashMap<uint64_t, RefPtr<CallbackBase>> m_map; }; -template<typename T> -void invalidateCallbackMap(HashMap<uint64_t, T>& map) -{ - Vector<T> callbacksVector; - copyValuesToVector(map, callbacksVector); - for (size_t i = 0, size = callbacksVector.size(); i < size; ++i) - callbacksVector[i]->invalidate(); - map.clear(); -} - } // namespace WebKit #endif // GenericCallback_h diff --git a/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp b/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp index 71047f302..0cf704511 100644 --- a/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp @@ -39,7 +39,7 @@ GeolocationPermissionRequestManagerProxy::GeolocationPermissionRequestManagerPro void GeolocationPermissionRequestManagerProxy::invalidateRequests() { - for (auto request : m_pendingRequests.values()) + for (auto& request : m_pendingRequests.values()) request->invalidate(); m_pendingRequests.clear(); @@ -47,9 +47,9 @@ void GeolocationPermissionRequestManagerProxy::invalidateRequests() PassRefPtr<GeolocationPermissionRequestProxy> GeolocationPermissionRequestManagerProxy::createRequest(uint64_t geolocationID) { - RefPtr<GeolocationPermissionRequestProxy> request = GeolocationPermissionRequestProxy::create(this, geolocationID); - m_pendingRequests.add(geolocationID, request.get()); - return request.release(); + auto request = GeolocationPermissionRequestProxy::create(this, geolocationID); + m_pendingRequests.add(geolocationID, request.ptr()); + return WTFMove(request); } void GeolocationPermissionRequestManagerProxy::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed) diff --git a/Source/WebKit2/UIProcess/GeolocationPermissionRequestProxy.h b/Source/WebKit2/UIProcess/GeolocationPermissionRequestProxy.h index ef718fe2a..27c5569e8 100644 --- a/Source/WebKit2/UIProcess/GeolocationPermissionRequestProxy.h +++ b/Source/WebKit2/UIProcess/GeolocationPermissionRequestProxy.h @@ -27,7 +27,6 @@ #define GeolocationPermissionRequestProxy_h #include "APIObject.h" -#include <wtf/PassRefPtr.h> namespace WebKit { @@ -35,9 +34,9 @@ class GeolocationPermissionRequestManagerProxy; class GeolocationPermissionRequestProxy : public API::ObjectImpl<API::Object::Type::GeolocationPermissionRequest> { public: - static PassRefPtr<GeolocationPermissionRequestProxy> create(GeolocationPermissionRequestManagerProxy* manager, uint64_t geolocationID) + static Ref<GeolocationPermissionRequestProxy> create(GeolocationPermissionRequestManagerProxy* manager, uint64_t geolocationID) { - return adoptRef(new GeolocationPermissionRequestProxy(manager, geolocationID)); + return adoptRef(*new GeolocationPermissionRequestProxy(manager, geolocationID)); } void allow(); diff --git a/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.cpp b/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.cpp new file mode 100644 index 000000000..859895077 --- /dev/null +++ b/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "HighPerformanceGraphicsUsageSampler.h" + +#include "WebProcessPool.h" +#include <WebCore/DiagnosticLoggingKeys.h> + +namespace WebKit { + +using namespace WebCore; + +static const std::chrono::minutes samplingInterval { 10 }; + +HighPerformanceGraphicsUsageSampler::HighPerformanceGraphicsUsageSampler(WebProcessPool& webProcessPool) + : m_webProcessPool(webProcessPool) + , m_timer(RunLoop::main(), this, &HighPerformanceGraphicsUsageSampler::timerFired) +{ + m_timer.startRepeating(samplingInterval); +} + +void HighPerformanceGraphicsUsageSampler::timerFired() +{ + bool isUsingHighPerformanceWebGL = false; + bool isUsingHighPerformanceWebGLInVisibleView = false; + + WebPageProxy* firstPage = nullptr; + for (auto& webProcess : m_webProcessPool.processes()) { + for (auto& page : webProcess->pages()) { + if (!firstPage) + firstPage = page; + + if (page->isUsingHighPerformanceWebGL()) { + isUsingHighPerformanceWebGL = true; + if (page->isViewVisible()) { + isUsingHighPerformanceWebGLInVisibleView = true; + break; + } + } + } + } + + if (!firstPage) + return; + + String state = DiagnosticLoggingKeys::inactiveKey(); + if (isUsingHighPerformanceWebGLInVisibleView) + state = DiagnosticLoggingKeys::activeInForegroundTabKey(); + else if (isUsingHighPerformanceWebGL) + state = DiagnosticLoggingKeys::activeInBackgroundTabOnlyKey(); + + firstPage->logDiagnosticMessage(DiagnosticLoggingKeys::webGLStateKey(), state, ShouldSample::No); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.h b/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.h new file mode 100644 index 000000000..7d56b0a24 --- /dev/null +++ b/Source/WebKit2/UIProcess/HighPerformanceGraphicsUsageSampler.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <wtf/RunLoop.h> + +namespace WebKit { + +class WebProcessPool; + +class HighPerformanceGraphicsUsageSampler { +public: + explicit HighPerformanceGraphicsUsageSampler(WebProcessPool&); + +private: + void timerFired(); + + WebProcessPool& m_webProcessPool; + RunLoop::Timer<HighPerformanceGraphicsUsageSampler> m_timer; +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.cpp b/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.cpp index c026d7744..a88f4e027 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.cpp @@ -27,6 +27,7 @@ #include "HTTPRequest.h" #include <wtf/text/CString.h> +#include <wtf/text/StringView.h> using namespace WebCore; @@ -82,7 +83,7 @@ size_t HTTPRequest::parseHeaders(const char* data, size_t length, String& failur { const char* p = data; const char* end = data + length; - AtomicString name; + StringView name; String value; for (; p < data + length; p++) { size_t consumedLength = parseHTTPHeader(p, end - p, failureReason, name, value); @@ -91,7 +92,7 @@ size_t HTTPRequest::parseHeaders(const char* data, size_t length, String& failur p += consumedLength; if (name.isEmpty()) break; - m_headerFields.add(name, value); + m_headerFields.add(name.toString(), value); } // If we got here and "name" is empty, it means the headers are valid and ended with a diff --git a/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.h b/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.h index ecda14e99..ffb317ec8 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.h +++ b/Source/WebKit2/UIProcess/InspectorServer/HTTPRequest.h @@ -43,8 +43,8 @@ namespace WebKit { class HTTPRequest : public RefCounted<HTTPRequest> { public: - static PassRefPtr<HTTPRequest> create() { return adoptRef(new HTTPRequest()); } - static PassRefPtr<HTTPRequest> create(const String& requestMethod, const WebCore::URL& url, WebCore::HTTPVersion version) { return adoptRef(new HTTPRequest(requestMethod, url, version)); } + static Ref<HTTPRequest> create() { return adoptRef(*new HTTPRequest()); } + static Ref<HTTPRequest> create(const String& requestMethod, const WebCore::URL& url, WebCore::HTTPVersion version) { return adoptRef(*new HTTPRequest(requestMethod, url, version)); } static PassRefPtr<HTTPRequest> parseHTTPRequestFromBuffer(const char* data, size_t length, String& failureReason); virtual ~HTTPRequest(); diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp index 8f689ac67..663877485 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.cpp @@ -30,6 +30,7 @@ #include "WebInspectorServer.h" +#include "HTTPHeaderNames.h" #include "HTTPRequest.h" #include "WebInspectorProxy.h" #include "WebSocketServerConnection.h" @@ -50,7 +51,7 @@ static unsigned pageIdFromRequestPath(const String& path) return number; } -WebInspectorServer& WebInspectorServer::shared() +WebInspectorServer& WebInspectorServer::singleton() { static WebInspectorServer& server = *new WebInspectorServer; return server; @@ -124,10 +125,10 @@ void WebInspectorServer::didReceiveUnrecognizedHTTPRequest(WebSocketServerConnec bool found = platformResourceForPath(path, body, contentType); HTTPHeaderMap headerFields; - headerFields.set("Connection", "close"); - headerFields.set("Content-Length", String::number(body.size())); + headerFields.set(HTTPHeaderName::Connection, "close"); + headerFields.set(HTTPHeaderName::ContentLength, String::number(body.size())); if (found) - headerFields.set("Content-Type", contentType); + headerFields.set(HTTPHeaderName::ContentType, contentType); // Send when ready and close immediately afterwards. connection->sendHTTPResponseHeader(found ? 200 : 404, found ? "OK" : "Not Found", headerFields); @@ -140,7 +141,7 @@ bool WebInspectorServer::didReceiveWebSocketUpgradeHTTPRequest(WebSocketServerCo String path = request->url(); // NOTE: Keep this in sync with WebCore/inspector/front-end/inspector.js. - DEFINE_STATIC_LOCAL(const String, inspectorWebSocketConnectionPathPrefix, (ASCIILiteral("/devtools/page/"))); + DEPRECATED_DEFINE_STATIC_LOCAL(const String, inspectorWebSocketConnectionPathPrefix, (ASCIILiteral("/devtools/page/"))); // Unknown path requested. if (!path.startsWith(inspectorWebSocketConnectionPathPrefix)) diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h index 19675b2b9..939a7e21b 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h +++ b/Source/WebKit2/UIProcess/InspectorServer/WebInspectorServer.h @@ -24,8 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebInspectorServer_h -#define WebInspectorServer_h +#pragma once #if ENABLE(INSPECTOR_SERVER) @@ -38,10 +37,10 @@ namespace WebKit { class WebInspectorProxy; -class WebInspectorServer : public WebSocketServer, public WebSocketServerClient { +class WebInspectorServer final : public WebSocketServer, public WebSocketServerClient { public: typedef HashMap<unsigned, WebInspectorProxy*> ClientMap; - static WebInspectorServer& shared(); + static WebInspectorServer& singleton(); // Page registry to manage known pages. int registerPage(WebInspectorProxy* client); @@ -54,14 +53,14 @@ private: ~WebInspectorServer(); // WebSocketServerClient implementation. Events coming from remote connections. - virtual void didReceiveUnrecognizedHTTPRequest(WebSocketServerConnection*, PassRefPtr<HTTPRequest>); - virtual bool didReceiveWebSocketUpgradeHTTPRequest(WebSocketServerConnection*, PassRefPtr<HTTPRequest>); - virtual void didEstablishWebSocketConnection(WebSocketServerConnection*, PassRefPtr<HTTPRequest>); - virtual void didReceiveWebSocketMessage(WebSocketServerConnection*, const String& message); - virtual void didCloseWebSocketConnection(WebSocketServerConnection*); + void didReceiveUnrecognizedHTTPRequest(WebSocketServerConnection*, PassRefPtr<HTTPRequest>) final; + bool didReceiveWebSocketUpgradeHTTPRequest(WebSocketServerConnection*, PassRefPtr<HTTPRequest>) final; + void didEstablishWebSocketConnection(WebSocketServerConnection*, PassRefPtr<HTTPRequest>) final; + void didReceiveWebSocketMessage(WebSocketServerConnection*, const String& message) final; + void didCloseWebSocketConnection(WebSocketServerConnection*) final; bool platformResourceForPath(const String& path, Vector<char>& data, String& contentType); -#if PLATFORM(GTK) || PLATFORM(EFL) +#if PLATFORM(GTK) void buildPageList(Vector<char>& data, String& contentType); #endif @@ -75,5 +74,3 @@ private: } #endif // ENABLE(INSPECTOR_SERVER) - -#endif // WebInspectorServer_h diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp index a78835d38..c534b4fcb 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp @@ -32,7 +32,6 @@ #include "WebSocketServerConnection.h" #include <WebCore/SocketStreamHandle.h> -#include <wtf/PassOwnPtr.h> using namespace WebCore; @@ -78,20 +77,20 @@ void WebSocketServer::close() m_bindAddress = String(); } -void WebSocketServer::didAcceptConnection(PassOwnPtr<WebSocketServerConnection> connection) +void WebSocketServer::didAcceptConnection(std::unique_ptr<WebSocketServerConnection> connection) { - m_connections.append(connection); + m_connections.append(WTFMove(connection)); } void WebSocketServer::didCloseWebSocketServerConnection(WebSocketServerConnection* connection) { - Deque<OwnPtr<WebSocketServerConnection> >::iterator end = m_connections.end(); - for (Deque<OwnPtr<WebSocketServerConnection> >::iterator it = m_connections.begin(); it != end; ++it) { + for (auto it = m_connections.begin(), end = m_connections.end(); it != end; ++it) { if (it->get() == connection) { m_connections.remove(it); return; } } + ASSERT_NOT_REACHED(); } diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h index a331dda3f..2e227ef00 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h @@ -29,13 +29,13 @@ #if ENABLE(INSPECTOR_SERVER) +#include <memory> #include <wtf/Deque.h> -#include <wtf/OwnPtr.h> #include <wtf/text/WTFString.h> #if USE(SOUP) #include <gio/gio.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/glib/GRefPtr.h> #endif namespace WebCore { @@ -61,7 +61,7 @@ public: void close(); WebSocketServerClient* client() const { return m_client; } - void didAcceptConnection(PassOwnPtr<WebSocketServerConnection>); + void didAcceptConnection(std::unique_ptr<WebSocketServerConnection>); private: void didCloseWebSocketServerConnection(WebSocketServerConnection*); @@ -71,7 +71,7 @@ private: void platformClose(); ServerState m_state; - Deque<OwnPtr<WebSocketServerConnection> > m_connections; + Deque<std::unique_ptr<WebSocketServerConnection>> m_connections; WebSocketServerClient* m_client; String m_bindAddress; unsigned short m_port; diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp index a33855546..7af854217 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp @@ -30,6 +30,7 @@ #include "WebSocketServerConnection.h" +#include "HTTPHeaderNames.h" #include "HTTPRequest.h" #include "WebSocketServer.h" #include "WebSocketServerClient.h" @@ -46,11 +47,8 @@ using namespace WebCore; namespace WebKit { WebSocketServerConnection::WebSocketServerConnection(WebSocketServerClient* client, WebSocketServer* server) - : m_identifier(0) - , m_mode(HTTP) - , m_server(server) + : m_server(server) , m_client(client) - , m_shutdownAfterSend(false) { } @@ -59,17 +57,17 @@ WebSocketServerConnection::~WebSocketServerConnection() shutdownNow(); } -void WebSocketServerConnection::setSocketHandle(PassRefPtr<WebCore::SocketStreamHandle> socket) +void WebSocketServerConnection::setSocketHandle(Ref<SocketStreamHandle>&& socket) { ASSERT(!m_socket); - m_socket = socket; + m_socket = WTFMove(socket); } void WebSocketServerConnection::shutdownNow() { if (!m_socket) return; - RefPtr<SocketStreamHandle> socket = m_socket.release(); + auto socket = WTFMove(m_socket); socket->close(); m_shutdownAfterSend = false; } @@ -122,10 +120,10 @@ void WebSocketServerConnection::sendRawData(const char* data, size_t length) m_socket->send(data, length); } -void WebSocketServerConnection::didCloseSocketStream(SocketStreamHandle*) +void WebSocketServerConnection::didCloseSocketStream(SocketStreamHandle&) { // Destroy the SocketStreamHandle now to prevent closing an already closed socket later. - m_socket.clear(); + m_socket = nullptr; // Web Socket Mode. if (m_mode == WebSocket) @@ -135,11 +133,12 @@ void WebSocketServerConnection::didCloseSocketStream(SocketStreamHandle*) m_server->didCloseWebSocketServerConnection(this); } -void WebSocketServerConnection::didReceiveSocketStreamData(SocketStreamHandle*, const char* data, int length) +void WebSocketServerConnection::didReceiveSocketStreamData(SocketStreamHandle&, const char* data, std::optional<size_t> length) { // Each didReceiveData call adds more data to our buffer. // We clear the buffer when we have handled data from it. - m_bufferedData.append(data, length); + if (length) + m_bufferedData.append(data, length.value()); switch (m_mode) { case HTTP: @@ -154,17 +153,12 @@ void WebSocketServerConnection::didReceiveSocketStreamData(SocketStreamHandle*, } } -void WebSocketServerConnection::didUpdateBufferedAmount(WebCore::SocketStreamHandle*, size_t) +void WebSocketServerConnection::didUpdateBufferedAmount(SocketStreamHandle&, size_t) { if (m_shutdownAfterSend && !m_socket->bufferedAmount()) shutdownNow(); } -void WebSocketServerConnection::didFailSocketStream(SocketStreamHandle*, const SocketStreamError&) -{ - // Possible read or write error. -} - void WebSocketServerConnection::readHTTPMessage() { String failureReason; @@ -177,7 +171,7 @@ void WebSocketServerConnection::readHTTPMessage() // If this is a WebSocket request, perform the WebSocket Handshake. const HTTPHeaderMap& headers = request->headerFields(); - String upgradeHeaderValue = headers.get("Upgrade"); + String upgradeHeaderValue = headers.get(HTTPHeaderName::Upgrade); if (upgradeHeaderValue == "websocket") { upgradeToWebSocketServerConnection(request); return; @@ -206,10 +200,10 @@ void WebSocketServerConnection::upgradeToWebSocketServerConnection(PassRefPtr<HT // Build and send the WebSocket handshake response. const HTTPHeaderMap& requestHeaders = protectedRequest->headerFields(); - String accept = WebSocketHandshake::getExpectedWebSocketAccept(requestHeaders.get("Sec-WebSocket-Key")); + String accept = WebSocketHandshake::getExpectedWebSocketAccept(requestHeaders.get(HTTPHeaderName::SecWebSocketKey)); HTTPHeaderMap responseHeaders; - responseHeaders.add("Upgrade", requestHeaders.get("Upgrade")); - responseHeaders.add("Connection", requestHeaders.get("Connection")); + responseHeaders.add("Upgrade", requestHeaders.get(HTTPHeaderName::Upgrade)); + responseHeaders.add("Connection", requestHeaders.get(HTTPHeaderName::Connection)); responseHeaders.add("Sec-WebSocket-Accept", accept); sendHTTPResponseHeader(101, "WebSocket Protocol Handshake", responseHeaders); diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h index 13c551644..1ead501a9 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h +++ b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h @@ -24,8 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebSocketServerConnection_h -#define WebSocketServerConnection_h +#pragma once #if ENABLE(INSPECTOR_SERVER) @@ -37,6 +36,7 @@ namespace WebCore { class HTTPHeaderMap; +class SocketStreamError; class SocketStreamHandle; } @@ -46,7 +46,7 @@ class HTTPRequest; class WebSocketServer; class WebSocketServerClient; -class WebSocketServerConnection : public WebCore::SocketStreamHandleClient { +class WebSocketServerConnection final : public WebCore::SocketStreamHandleClient { public: enum WebSocketServerMode { HTTP, WebSocket }; WebSocketServerConnection(WebSocketServerClient*, WebSocketServer*); @@ -54,7 +54,7 @@ public: unsigned identifier() const { return m_identifier; } void setIdentifier(unsigned id) { m_identifier = id; } - void setSocketHandle(PassRefPtr<WebCore::SocketStreamHandle>); + void setSocketHandle(Ref<WebCore::SocketStreamHandle>&&); // Sending data over the connection. void sendWebSocketMessage(const String& message); @@ -65,13 +65,14 @@ public: void shutdownNow(); void shutdownAfterSendOrNow(); +private: // SocketStreamHandleClient implementation. - virtual void didCloseSocketStream(WebCore::SocketStreamHandle*); - virtual void didReceiveSocketStreamData(WebCore::SocketStreamHandle*, const char* data, int length); - virtual void didUpdateBufferedAmount(WebCore::SocketStreamHandle*, size_t bufferedAmount); - virtual void didFailSocketStream(WebCore::SocketStreamHandle*, const WebCore::SocketStreamError&); + void didOpenSocketStream(WebCore::SocketStreamHandle&) final { } + void didCloseSocketStream(WebCore::SocketStreamHandle&) final; + void didReceiveSocketStreamData(WebCore::SocketStreamHandle&, const char* data, std::optional<size_t> length) final; + void didUpdateBufferedAmount(WebCore::SocketStreamHandle&, size_t bufferedAmount) final; + void didFailSocketStream(WebCore::SocketStreamHandle&, const WebCore::SocketStreamError&) final { } -private: // HTTP Mode. void readHTTPMessage(); @@ -80,18 +81,15 @@ private: void readWebSocketFrames(); bool readWebSocketFrame(); -protected: - unsigned m_identifier; + unsigned m_identifier { 0 }; Vector<char> m_bufferedData; - WebSocketServerMode m_mode; + WebSocketServerMode m_mode { HTTP }; RefPtr<WebCore::SocketStreamHandle> m_socket; - WebSocketServer* m_server; - WebSocketServerClient* m_client; - bool m_shutdownAfterSend; + WebSocketServer* m_server { nullptr }; + WebSocketServerClient* m_client { nullptr }; + bool m_shutdownAfterSend { false }; }; } #endif // ENABLE(INSPECTOR_SERVER) - -#endif // WebSocketServerConnection_h diff --git a/Source/WebKit2/UIProcess/InspectorServer/gtk/WebInspectorServerGtk.cpp b/Source/WebKit2/UIProcess/InspectorServer/gtk/WebInspectorServerGtk.cpp index 5011666b3..c5393a47d 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/gtk/WebInspectorServerGtk.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/gtk/WebInspectorServerGtk.cpp @@ -33,7 +33,7 @@ #include <WebCore/MIMETypeRegistry.h> #include <gio/gio.h> #include <glib.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> #include <wtf/text/StringBuilder.h> #include <wtf/text/StringConcatenate.h> @@ -94,7 +94,7 @@ void WebInspectorServer::buildPageList(Vector<char>& data, String& contentType) builder.appendLiteral("[ "); ClientMap::iterator end = m_clientMap.end(); for (ClientMap::iterator it = m_clientMap.begin(); it != end; ++it) { - WebPageProxy* webPage = it->value->page(); + WebPageProxy* webPage = it->value->inspectedPage(); if (it != m_clientMap.begin()) builder.appendLiteral(", "); builder.appendLiteral("{ \"id\": "); diff --git a/Source/WebKit2/UIProcess/InspectorServer/soup/WebSocketServerSoup.cpp b/Source/WebKit2/UIProcess/InspectorServer/soup/WebSocketServerSoup.cpp index f3ad13ac2..bf3e019e6 100644 --- a/Source/WebKit2/UIProcess/InspectorServer/soup/WebSocketServerSoup.cpp +++ b/Source/WebKit2/UIProcess/InspectorServer/soup/WebSocketServerSoup.cpp @@ -28,11 +28,10 @@ #include "Logging.h" #include "WebSocketServerConnection.h" -#include <WebCore/SocketStreamHandle.h> +#include <WebCore/SocketStreamHandleImpl.h> #include <gio/gio.h> #include <glib.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebCore; @@ -47,9 +46,9 @@ static gboolean connectionCallback(GSocketService* /*service*/, GSocketConnectio LOG(InspectorServer, "New Connection from %s:%d.", addressString.get(), g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(socketAddress.get()))); #endif - OwnPtr<WebSocketServerConnection> webSocketConnection = adoptPtr(new WebSocketServerConnection(server->client(), server)); - webSocketConnection->setSocketHandle(SocketStreamHandle::create(connection, webSocketConnection.get())); - server->didAcceptConnection(webSocketConnection.release()); + auto webSocketConnection = std::make_unique<WebSocketServerConnection>(server->client(), server); + webSocketConnection->setSocketHandle(SocketStreamHandleImpl::create(connection, *webSocketConnection)); + server->didAcceptConnection(WTFMove(webSocketConnection)); return TRUE; } diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp index f20c19c5a..089c17c33 100644 --- a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp +++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.cpp @@ -26,42 +26,32 @@ #include "config.h" #include "ProcessLauncher.h" -#include "WorkQueue.h" #include <wtf/StdLibExtras.h> +#include <wtf/WorkQueue.h> namespace WebKit { -static WorkQueue* processLauncherWorkQueue() -{ - static WorkQueue* processLauncherWorkQueue = WorkQueue::create("com.apple.WebKit.ProcessLauncher").leakRef(); - return processLauncherWorkQueue; -} - ProcessLauncher::ProcessLauncher(Client* client, const LaunchOptions& launchOptions) : m_client(client) + , m_weakPtrFactory(this) , m_launchOptions(launchOptions) , m_processIdentifier(0) { - // Launch the process. m_isLaunching = true; - processLauncherWorkQueue()->dispatch(bind(&ProcessLauncher::launchProcess, this)); + launchProcess(); } -void ProcessLauncher::didFinishLaunchingProcess(PlatformProcessIdentifier processIdentifier, IPC::Connection::Identifier identifier) +void ProcessLauncher::didFinishLaunchingProcess(pid_t processIdentifier, IPC::Connection::Identifier identifier) { m_processIdentifier = processIdentifier; m_isLaunching = false; if (!m_client) { // FIXME: Make Identifier a move-only object and release port rights/connections in the destructor. -#if PLATFORM(MAC) +#if OS(DARWIN) && !PLATFORM(GTK) + // FIXME: Should really be something like USE(MACH) if (identifier.port) mach_port_mod_refs(mach_task_self(), identifier.port, MACH_PORT_RIGHT_RECEIVE, -1); - - if (identifier.xpcConnection) { - xpc_release(identifier.xpcConnection); - identifier.xpcConnection = 0; - } #endif return; } @@ -75,57 +65,4 @@ void ProcessLauncher::invalidate() platformInvalidate(); } -const char* ProcessLauncher::processTypeAsString(ProcessType processType) -{ - switch (processType) { - case WebProcess: - return "webprocess"; -#if ENABLE(NETSCAPE_PLUGIN_API) - case PluginProcess: - return "pluginprocess"; -#endif -#if ENABLE(NETWORK_PROCESS) - case NetworkProcess: - return "networkprocess"; -#endif -#if ENABLE(DATABASE_PROCESS) - case DatabaseProcess: - return "databaseprocess"; -#endif - } - - ASSERT_NOT_REACHED(); - return 0; -} - -bool ProcessLauncher::getProcessTypeFromString(const char* string, ProcessType& processType) -{ - if (!strcmp(string, "webprocess")) { - processType = WebProcess; - return true; - } - -#if ENABLE(NETSCAPE_PLUGIN_API) - if (!strcmp(string, "pluginprocess")) { - processType = PluginProcess; - return true; - } -#endif - -#if ENABLE(NETWORK_PROCESS) - if (!strcmp(string, "networkprocess")) { - processType = NetworkProcess; - return true; - } -#endif - -#if ENABLE(DATABASE_PROCESS) - if (!strcmp(string, "databaseprocess")) { - processType = DatabaseProcess; - return true; - } -#endif - return false; -} - } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h index 6996bfe64..399506948 100644 --- a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h +++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h @@ -23,14 +23,13 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebProcessLauncher_h -#define WebProcessLauncher_h +#pragma once #include "Connection.h" -#include "PlatformProcessIdentifier.h" #include <wtf/HashMap.h> #include <wtf/RefPtr.h> #include <wtf/Threading.h> +#include <wtf/WeakPtr.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> @@ -45,64 +44,56 @@ public: virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) = 0; }; - enum ProcessType { - WebProcess, + enum class ProcessType { + Web, #if ENABLE(NETSCAPE_PLUGIN_API) - PluginProcess, -#endif -#if ENABLE(NETWORK_PROCESS) - NetworkProcess, + Plugin32, + Plugin64, #endif + Network, #if ENABLE(DATABASE_PROCESS) - DatabaseProcess, + Database, #endif }; struct LaunchOptions { ProcessType processType; HashMap<String, String> extraInitializationData; -#if PLATFORM(MAC) - static const cpu_type_t MatchCurrentArchitecture = 0; - cpu_type_t architecture; - bool executableHeap; - bool useXPC; -#endif -#if PLATFORM(EFL) || PLATFORM(GTK) -#ifndef NDEBUG + +#if ENABLE(DEVELOPER_MODE) && PLATFORM(GTK) String processCmdPrefix; #endif -#endif }; - static PassRefPtr<ProcessLauncher> create(Client* client, const LaunchOptions& launchOptions) + static Ref<ProcessLauncher> create(Client* client, const LaunchOptions& launchOptions) { - return adoptRef(new ProcessLauncher(client, launchOptions)); + return adoptRef(*new ProcessLauncher(client, launchOptions)); } bool isLaunching() const { return m_isLaunching; } - PlatformProcessIdentifier processIdentifier() const { return m_processIdentifier; } + pid_t processIdentifier() const { return m_processIdentifier; } void terminateProcess(); void invalidate(); - static bool getProcessTypeFromString(const char*, ProcessType&); - static const char* processTypeAsString(ProcessType); - private: ProcessLauncher(Client*, const LaunchOptions& launchOptions); void launchProcess(); - void didFinishLaunchingProcess(PlatformProcessIdentifier, IPC::Connection::Identifier); + void didFinishLaunchingProcess(pid_t, IPC::Connection::Identifier); void platformInvalidate(); Client* m_client; +#if PLATFORM(COCOA) + OSObjectPtr<xpc_connection_t> m_xpcConnection; +#endif + + WeakPtrFactory<ProcessLauncher> m_weakPtrFactory; const LaunchOptions m_launchOptions; bool m_isLaunching; - PlatformProcessIdentifier m_processIdentifier; + pid_t m_processIdentifier; }; } // namespace WebKit - -#endif // WebProcessLauncher_h diff --git a/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp b/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp index 89d367c77..add147995 100644 --- a/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp +++ b/Source/WebKit2/UIProcess/Launcher/gtk/ProcessLauncherGtk.cpp @@ -38,10 +38,11 @@ #include <glib.h> #include <locale.h> #include <wtf/RunLoop.h> +#include <wtf/UniStdExtras.h> +#include <wtf/glib/GLibUtilities.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> -#include <wtf/gobject/GUniquePtr.h> -#include <wtf/gobject/GlibUtilities.h> using namespace WebCore; @@ -62,18 +63,28 @@ void ProcessLauncher::launchProcess() String executablePath, pluginPath; CString realExecutablePath, realPluginPath; switch (m_launchOptions.processType) { - case WebProcess: + case ProcessLauncher::ProcessType::Web: executablePath = executablePathOfWebProcess(); break; - case PluginProcess: +#if ENABLE(NETSCAPE_PLUGIN_API) + case ProcessLauncher::ProcessType::Plugin64: + case ProcessLauncher::ProcessType::Plugin32: executablePath = executablePathOfPluginProcess(); +#if ENABLE(PLUGIN_PROCESS_GTK2) + if (m_launchOptions.extraInitializationData.contains("requires-gtk2")) + executablePath.append('2'); +#endif pluginPath = m_launchOptions.extraInitializationData.get("plugin-path"); realPluginPath = fileSystemRepresentation(pluginPath); break; -#if ENABLE(NETWORK_PROCESS) - case NetworkProcess: +#endif + case ProcessLauncher::ProcessType::Network: executablePath = executablePathOfNetworkProcess(); break; +#if ENABLE(DATABASE_PROCESS) + case ProcessLauncher::ProcessType::Database: + executablePath = executablePathOfDatabaseProcess(); + break; #endif default: ASSERT_NOT_REACHED(); @@ -85,7 +96,7 @@ void ProcessLauncher::launchProcess() unsigned nargs = 4; // size of the argv array for g_spawn_async() -#ifndef NDEBUG +#if ENABLE(DEVELOPER_MODE) Vector<CString> prefixArgs; if (!m_launchOptions.processCmdPrefix.isNull()) { Vector<String> splitArgs; @@ -98,7 +109,7 @@ void ProcessLauncher::launchProcess() char** argv = g_newa(char*, nargs); unsigned i = 0; -#ifndef NDEBUG +#if ENABLE(DEVELOPER_MODE) // If there's a prefix command, put it before the rest of the args. for (auto it = prefixArgs.begin(); it != prefixArgs.end(); it++) argv[i++] = const_cast<char*>(it->data()); @@ -115,14 +126,18 @@ void ProcessLauncher::launchProcess() } // Don't expose the parent socket to potential future children. - while (fcntl(socketPair.client, F_SETFD, FD_CLOEXEC) == -1) - RELEASE_ASSERT(errno != EINTR); + if (!setCloseOnExec(socketPair.client)) + RELEASE_ASSERT_NOT_REACHED(); close(socketPair.client); m_processIdentifier = pid; // We've finished launching the process, message back to the main run loop. - RunLoop::main()->dispatch(bind(&ProcessLauncher::didFinishLaunchingProcess, this, m_processIdentifier, socketPair.server)); + RefPtr<ProcessLauncher> protector(this); + IPC::Connection::Identifier serverSocket = socketPair.server; + RunLoop::main().dispatch([protector, pid, serverSocket] { + protector->didFinishLaunchingProcess(pid, serverSocket); + }); } void ProcessLauncher::terminateProcess() diff --git a/Source/WebKit2/UIProcess/LegacySessionStateCoding.h b/Source/WebKit2/UIProcess/LegacySessionStateCoding.h new file mode 100644 index 000000000..2321a2ecd --- /dev/null +++ b/Source/WebKit2/UIProcess/LegacySessionStateCoding.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LegacySessionStateCoding_h +#define LegacySessionStateCoding_h + +#include <wtf/Forward.h> + +namespace API { +class Data; +} + +namespace WebKit { + +struct FrameState; +struct SessionState; + +RefPtr<API::Data> encodeLegacySessionState(const SessionState&); +bool decodeLegacySessionState(const uint8_t* data, size_t, SessionState&); + +} // namespace WebKit + +#endif // LegacySessionStateCoding_h diff --git a/Source/WebKit2/UIProcess/LegacySessionStateCodingNone.cpp b/Source/WebKit2/UIProcess/LegacySessionStateCodingNone.cpp new file mode 100644 index 000000000..9e98b7d10 --- /dev/null +++ b/Source/WebKit2/UIProcess/LegacySessionStateCodingNone.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "LegacySessionStateCoding.h" + +#include "APIData.h" +#include "DataReference.h" +#include "Decoder.h" +#include "Encoder.h" +#include "SessionState.h" +#include "WebCoreArgumentCoders.h" + +namespace WebKit { + +RefPtr<API::Data> encodeLegacySessionState(const SessionState& sessionState) +{ + // FIXME: I'm not sure whether these are the proper arguments for the encoder. + IPC::Encoder encoder("IPC", "LegacySessionState", 0); + encoder << sessionState.backForwardListState; + encoder << sessionState.renderTreeSize; + encoder << sessionState.provisionalURL; + return API::Data::create(encoder.buffer(), encoder.bufferSize()); +} + +bool decodeLegacySessionState(const uint8_t* data, size_t dataSize, SessionState& sessionState) +{ + IPC::Decoder decoder(data, dataSize, nullptr, Vector<IPC::Attachment>()); + if (!decoder.decode(sessionState.backForwardListState)) + return false; + if (!decoder.decode(sessionState.renderTreeSize)) + return false; + if (!decoder.decode(sessionState.provisionalURL)) + return false; + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.cpp b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.cpp new file mode 100644 index 000000000..452f3a858 --- /dev/null +++ b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2013 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "CustomProtocolManagerProxy.h" + +#include "APICustomProtocolManagerClient.h" +#include "ChildProcessProxy.h" +#include "CustomProtocolManagerMessages.h" +#include "CustomProtocolManagerProxyMessages.h" +#include "WebProcessPool.h" +#include <WebCore/ResourceRequest.h> + +namespace WebKit { + +CustomProtocolManagerProxy::CustomProtocolManagerProxy(ChildProcessProxy* childProcessProxy, WebProcessPool& processPool) + : m_childProcessProxy(childProcessProxy) + , m_processPool(processPool) +{ + ASSERT(m_childProcessProxy); + m_childProcessProxy->addMessageReceiver(Messages::CustomProtocolManagerProxy::messageReceiverName(), *this); +} + +CustomProtocolManagerProxy::~CustomProtocolManagerProxy() +{ + m_childProcessProxy->removeMessageReceiver(Messages::CustomProtocolManagerProxy::messageReceiverName()); +} + +void CustomProtocolManagerProxy::startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest& request) +{ + m_processPool.customProtocolManagerClient().startLoading(*this, customProtocolID, request); +} + +void CustomProtocolManagerProxy::stopLoading(uint64_t customProtocolID) +{ + m_processPool.customProtocolManagerClient().stopLoading(*this, customProtocolID); +} + +void CustomProtocolManagerProxy::processDidClose() +{ + m_processPool.customProtocolManagerClient().invalidate(*this); +} + +void CustomProtocolManagerProxy::wasRedirectedToRequest(uint64_t customProtocolID, const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& redirectResponse) +{ + m_childProcessProxy->send(Messages::CustomProtocolManager::WasRedirectedToRequest(customProtocolID, request, redirectResponse), 0); +} + +void CustomProtocolManagerProxy::didReceiveResponse(uint64_t customProtocolID, const WebCore::ResourceResponse& response, uint32_t cacheStoragePolicy) +{ + m_childProcessProxy->send(Messages::CustomProtocolManager::DidReceiveResponse(customProtocolID, response, cacheStoragePolicy), 0); +} + +void CustomProtocolManagerProxy::didLoadData(uint64_t customProtocolID, const IPC::DataReference& data) +{ + m_childProcessProxy->send(Messages::CustomProtocolManager::DidLoadData(customProtocolID, data), 0); +} + +void CustomProtocolManagerProxy::didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError& error) +{ + m_childProcessProxy->send(Messages::CustomProtocolManager::DidFailWithError(customProtocolID, error), 0); +} + +void CustomProtocolManagerProxy::didFinishLoading(uint64_t customProtocolID) +{ + m_childProcessProxy->send(Messages::CustomProtocolManager::DidFinishLoading(customProtocolID), 0); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.h b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.h index 9615a510b..ffe99cbe1 100644 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.h +++ b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.h @@ -26,40 +26,53 @@ #ifndef CustomProtocolManagerProxy_h #define CustomProtocolManagerProxy_h -#if ENABLE(CUSTOM_PROTOCOLS) - #include "MessageReceiver.h" -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> OBJC_CLASS WKCustomProtocolLoader; #endif +namespace IPC { +class DataReference; +} + namespace WebCore { +class ResourceError; class ResourceRequest; +class ResourceResponse; } // namespace WebCore namespace WebKit { class ChildProcessProxy; -class WebContext; +class WebProcessPool; class CustomProtocolManagerProxy : public IPC::MessageReceiver { public: - explicit CustomProtocolManagerProxy(ChildProcessProxy*, WebContext&); + CustomProtocolManagerProxy(ChildProcessProxy*, WebProcessPool&); + ~CustomProtocolManagerProxy(); void startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest&); void stopLoading(uint64_t customProtocolID); + void processDidClose(); + + void wasRedirectedToRequest(uint64_t customProtocolID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&); + void didReceiveResponse(uint64_t customProtocolID, const WebCore::ResourceResponse&, uint32_t cacheStoragePolicy); + void didLoadData(uint64_t customProtocolID, const IPC::DataReference&); + void didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError&); + void didFinishLoading(uint64_t customProtocolID); + private: // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; ChildProcessProxy* m_childProcessProxy; - WebContext& m_webContext; + WebProcessPool& m_processPool; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) typedef HashMap<uint64_t, RetainPtr<WKCustomProtocolLoader>> LoaderMap; LoaderMap m_loaderMap; #endif @@ -67,6 +80,4 @@ private: } // namespace WebKit -#endif // ENABLE(CUSTOM_PROTOCOLS) - #endif // CustomProtocolManagerProxy_h diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.messages.in b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.messages.in index 7aef0e0e7..93c0ad435 100644 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/Network/CustomProtocols/CustomProtocolManagerProxy.messages.in @@ -20,11 +20,7 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(CUSTOM_PROTOCOLS) - messages -> CustomProtocolManagerProxy { StartLoading(uint64_t customProtocolID, WebCore::ResourceRequest request) StopLoading(uint64_t customProtocolID) } - -#endif // ENABLE(CUSTOM_PROTOCOLS) diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/CustomProtocolManagerProxySoup.cpp b/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/CustomProtocolManagerProxySoup.cpp deleted file mode 100644 index a6b437d04..000000000 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/CustomProtocolManagerProxySoup.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "CustomProtocolManagerProxy.h" - -#if ENABLE(CUSTOM_PROTOCOLS) - -#include "ChildProcessProxy.h" -#include "CustomProtocolManagerMessages.h" -#include "CustomProtocolManagerProxyMessages.h" -#include "WebContext.h" -#include "WebSoupCustomProtocolRequestManager.h" -#include <WebCore/ResourceRequest.h> - -namespace WebKit { - -CustomProtocolManagerProxy::CustomProtocolManagerProxy(ChildProcessProxy* childProcessProxy, WebContext& webContext) - : m_childProcessProxy(childProcessProxy) - , m_webContext(webContext) -{ - ASSERT(m_childProcessProxy); - m_childProcessProxy->addMessageReceiver(Messages::CustomProtocolManagerProxy::messageReceiverName(), *this); -} - -void CustomProtocolManagerProxy::startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest& request) -{ - m_webContext.supplement<WebSoupCustomProtocolRequestManager>()->startLoading(customProtocolID, request); -} - -void CustomProtocolManagerProxy::stopLoading(uint64_t customProtocolID) -{ - m_webContext.supplement<WebSoupCustomProtocolRequestManager>()->stopLoading(customProtocolID); -} - -} // namespace WebKit - -#endif // ENABLE(CUSTOM_PROTOCOLS) diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp b/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp deleted file mode 100644 index ad73ad494..000000000 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebSoupCustomProtocolRequestManager.h" - -#if ENABLE(CUSTOM_PROTOCOLS) - -#include "APIData.h" -#include "CustomProtocolManagerMessages.h" -#include "WebContext.h" -#include <WebCore/ResourceError.h> -#include <WebCore/ResourceRequest.h> -#include <WebCore/ResourceResponse.h> - -#if PLATFORM(GTK) -#include <WebCore/ErrorsGtk.h> -#endif - -namespace WebKit { - -const char* WebSoupCustomProtocolRequestManager::supplementName() -{ - return "WebSoupCustomProtocolRequestManager"; -} - -PassRefPtr<WebSoupCustomProtocolRequestManager> WebSoupCustomProtocolRequestManager::create(WebContext* context) -{ - return adoptRef(new WebSoupCustomProtocolRequestManager(context)); -} - -WebSoupCustomProtocolRequestManager::WebSoupCustomProtocolRequestManager(WebContext* context) - : WebContextSupplement(context) -{ -} - -WebSoupCustomProtocolRequestManager::~WebSoupCustomProtocolRequestManager() -{ -} - -void WebSoupCustomProtocolRequestManager::initializeClient(const WKSoupCustomProtocolRequestManagerClientBase* client) -{ - m_client.initialize(client); -} - -// WebContextSupplement -void WebSoupCustomProtocolRequestManager::contextDestroyed() -{ -} - -void WebSoupCustomProtocolRequestManager::processDidClose(WebProcessProxy*) -{ -} - -void WebSoupCustomProtocolRequestManager::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebSoupCustomProtocolRequestManager::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebSoupCustomProtocolRequestManager::registerSchemeForCustomProtocol(const String& scheme) -{ - if (!context()) - return; - - context()->registerSchemeForCustomProtocol(scheme); - - ASSERT(!m_registeredSchemes.contains(scheme)); - m_registeredSchemes.append(scheme); -} - -void WebSoupCustomProtocolRequestManager::unregisterSchemeForCustomProtocol(const String& scheme) -{ - if (!context()) - return; - - context()->unregisterSchemeForCustomProtocol(scheme); - - ASSERT(m_registeredSchemes.contains(scheme)); - m_registeredSchemes.remove(m_registeredSchemes.find(scheme)); -} - -void WebSoupCustomProtocolRequestManager::startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest& request) -{ - if (!m_client.startLoading(this, customProtocolID, request)) - didFailWithError(customProtocolID, WebCore::cannotShowURLError(request)); -} - -void WebSoupCustomProtocolRequestManager::stopLoading(uint64_t customProtocolID) -{ - m_client.stopLoading(this, customProtocolID); -} - -void WebSoupCustomProtocolRequestManager::didReceiveResponse(uint64_t customProtocolID, const WebCore::ResourceResponse& response) -{ - if (!context()) - return; - - context()->networkingProcessConnection()->send(Messages::CustomProtocolManager::DidReceiveResponse(customProtocolID, response, 0), 0); -} - -void WebSoupCustomProtocolRequestManager::didLoadData(uint64_t customProtocolID, const API::Data* data) -{ - if (!context()) - return; - - context()->networkingProcessConnection()->send(Messages::CustomProtocolManager::DidLoadData(customProtocolID, data->dataReference()), 0); -} - -void WebSoupCustomProtocolRequestManager::didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError& error) -{ - if (!context()) - return; - - context()->networkingProcessConnection()->send(Messages::CustomProtocolManager::DidFailWithError(customProtocolID, error), 0); -} - -void WebSoupCustomProtocolRequestManager::didFinishLoading(uint64_t customProtocolID) -{ - if (!context()) - return; - - context()->networkingProcessConnection()->send(Messages::CustomProtocolManager::DidFinishLoading(customProtocolID), 0); -} - -} // namespace WebKit - -#endif // ENABLE(CUSTOM_PROTOCOLS) diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.h b/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.h deleted file mode 100644 index a140925d1..000000000 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManager.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebSoupCustomProtocolRequestManager_h -#define WebSoupCustomProtocolRequestManager_h - -#if ENABLE(CUSTOM_PROTOCOLS) - -#include "APIObject.h" -#include "WebContextSupplement.h" -#include "WebSoupCustomProtocolRequestManagerClient.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/text/WTFString.h> - -namespace API { -class Data; -} - -namespace WebCore { -class ResourceError; -class ResourceRequest; -class ResourceResponse; -} - -namespace WebKit { - -class WebContext; - -class WebSoupCustomProtocolRequestManager : public API::ObjectImpl<API::Object::Type::SoupCustomProtocolRequestManager>, public WebContextSupplement { -public: - static const char* supplementName(); - - static PassRefPtr<WebSoupCustomProtocolRequestManager> create(WebContext*); - virtual ~WebSoupCustomProtocolRequestManager(); - - void initializeClient(const WKSoupCustomProtocolRequestManagerClientBase*); - - void registerSchemeForCustomProtocol(const String& scheme); - void unregisterSchemeForCustomProtocol(const String& scheme); - - void startLoading(uint64_t customProtocolID, const WebCore::ResourceRequest&); - void stopLoading(uint64_t customProtocolID); - - void didReceiveResponse(uint64_t customProtocolID, const WebCore::ResourceResponse&); - void didLoadData(uint64_t customProtocolID, const API::Data*); - void didFailWithError(uint64_t customProtocolID, const WebCore::ResourceError&); - void didFinishLoading(uint64_t customProtocolID); - - const Vector<String>& registeredSchemesForCustomProtocols() const { return m_registeredSchemes; } - - using API::Object::ref; - using API::Object::deref; - -private: - WebSoupCustomProtocolRequestManager(WebContext*); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - WebSoupCustomProtocolRequestManagerClient m_client; - Vector<String> m_registeredSchemes; -}; - -} // namespace WebKit - -#endif // ENABLE(CUSTOM_PROTOCOLS) - -#endif // WebSoupCustomProtocolRequestManager_h diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp b/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp deleted file mode 100644 index 80d43c5a3..000000000 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WebSoupCustomProtocolRequestManagerClient.h" - -#if ENABLE(CUSTOM_PROTOCOLS) - -namespace WebKit { - -bool WebSoupCustomProtocolRequestManagerClient::startLoading(WebSoupCustomProtocolRequestManager* soupRequestManager, uint64_t customProtocolID, const WebCore::ResourceRequest& request) -{ - if (!m_client.startLoading) - return false; - - RefPtr<API::URLRequest> urlRequest = API::URLRequest::create(request); - m_client.startLoading(toAPI(soupRequestManager), customProtocolID, toAPI(urlRequest.get()), m_client.base.clientInfo); - return true; -} - -void WebSoupCustomProtocolRequestManagerClient::stopLoading(WebSoupCustomProtocolRequestManager* soupRequestManager, uint64_t customProtocolID) -{ - if (m_client.stopLoading) - m_client.stopLoading(toAPI(soupRequestManager), customProtocolID, m_client.base.clientInfo); -} - -} // namespace WebKit - -#endif // ENABLE(CUSTOM_PROTOCOLS) diff --git a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.h b/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.h deleted file mode 100644 index e14332141..000000000 --- a/Source/WebKit2/UIProcess/Network/CustomProtocols/soup/WebSoupCustomProtocolRequestManagerClient.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2013 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef WebSoupCustomProtocolRequestManagerClient_h -#define WebSoupCustomProtocolRequestManagerClient_h - -#if ENABLE(CUSTOM_PROTOCOLS) - -#include "APIClient.h" -#include "WKAPICast.h" -#include "WKSoupCustomProtocolRequestManager.h" - -namespace API { - -template<> struct ClientTraits<WKSoupCustomProtocolRequestManagerClientBase> { - typedef std::tuple<WKSoupCustomProtocolRequestManagerClientV0> Versions; -}; -} - -namespace WebCore { -class ResourceRequest; -} - -namespace WebKit { - -class WebSoupCustomProtocolRequestManager; - -class WebSoupCustomProtocolRequestManagerClient : public API::Client<WKSoupCustomProtocolRequestManagerClientBase> { -public: - bool startLoading(WebSoupCustomProtocolRequestManager*, uint64_t customProtocolID, const WebCore::ResourceRequest&); - void stopLoading(WebSoupCustomProtocolRequestManager*, uint64_t customProtocolID); -}; - -} // namespace WebKit - -#endif // ENABLE(CUSTOM_PROTOCOLS) - -#endif // WebSoupCustomProtocolRequestManagerClient_h diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp index e9b4e7964..8c0e96689 100644 --- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,114 +26,189 @@ #include "config.h" #include "NetworkProcessProxy.h" -#if ENABLE(NETWORK_PROCESS) - #include "AuthenticationChallengeProxy.h" #include "CustomProtocolManagerProxyMessages.h" +#include "DatabaseProcessMessages.h" #include "DownloadProxyMessages.h" +#include "Logging.h" #include "NetworkProcessCreationParameters.h" #include "NetworkProcessMessages.h" -#include "WebContext.h" +#include "SandboxExtension.h" #include "WebProcessMessages.h" -#include <wtf/RunLoop.h> +#include "WebProcessPool.h" +#include "WebsiteData.h" #if ENABLE(SEC_ITEM_SHIM) #include "SecItemShimProxy.h" #endif +#if PLATFORM(IOS) +#include <wtf/spi/darwin/XPCSPI.h> +#endif + #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection()) using namespace WebCore; namespace WebKit { -PassRefPtr<NetworkProcessProxy> NetworkProcessProxy::create(WebContext& webContext) +static uint64_t generateCallbackID() +{ + static uint64_t callbackID; + + return ++callbackID; +} + +Ref<NetworkProcessProxy> NetworkProcessProxy::create(WebProcessPool& processPool) { - return adoptRef(new NetworkProcessProxy(webContext)); + return adoptRef(*new NetworkProcessProxy(processPool)); } -NetworkProcessProxy::NetworkProcessProxy(WebContext& webContext) - : m_webContext(webContext) +NetworkProcessProxy::NetworkProcessProxy(WebProcessPool& processPool) + : ChildProcessProxy(processPool.alwaysRunsAtBackgroundPriority()) + , m_processPool(processPool) , m_numPendingConnectionRequests(0) -#if ENABLE(CUSTOM_PROTOCOLS) - , m_customProtocolManagerProxy(this, webContext) -#endif + , m_customProtocolManagerProxy(this, processPool) + , m_throttler(*this) { connect(); } NetworkProcessProxy::~NetworkProcessProxy() { + ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty()); } void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) { - launchOptions.processType = ProcessLauncher::NetworkProcess; - platformGetLaunchOptions(launchOptions); + launchOptions.processType = ProcessLauncher::ProcessType::Network; + ChildProcessProxy::getLaunchOptions(launchOptions); } -void NetworkProcessProxy::connectionWillOpen(IPC::Connection* connection) +void NetworkProcessProxy::connectionWillOpen(IPC::Connection& connection) { #if ENABLE(SEC_ITEM_SHIM) - SecItemShimProxy::shared().initializeConnection(connection); + SecItemShimProxy::singleton().initializeConnection(connection); +#else + UNUSED_PARAM(connection); #endif } -void NetworkProcessProxy::connectionWillClose(IPC::Connection*) +void NetworkProcessProxy::processWillShutDown(IPC::Connection& connection) { + ASSERT_UNUSED(connection, this->connection() == &connection); } -void NetworkProcessProxy::getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply) +void NetworkProcessProxy::getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&& reply) { - m_pendingConnectionReplies.append(reply); + m_pendingConnectionReplies.append(WTFMove(reply)); - if (isLaunching()) { + if (state() == State::Launching) { m_numPendingConnectionRequests++; return; } - connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0, IPC::DispatchMessageEvenWhenWaitingForSyncReply); + connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); } -DownloadProxy* NetworkProcessProxy::createDownloadProxy() +DownloadProxy* NetworkProcessProxy::createDownloadProxy(const ResourceRequest& resourceRequest) { if (!m_downloadProxyMap) - m_downloadProxyMap = adoptPtr(new DownloadProxyMap(this)); + m_downloadProxyMap = std::make_unique<DownloadProxyMap>(this); + + return m_downloadProxyMap->createDownloadProxy(m_processPool, resourceRequest); +} + +void NetworkProcessProxy::fetchWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, std::function<void (WebsiteData)> completionHandler) +{ + ASSERT(canSendMessage()); - return m_downloadProxyMap->createDownloadProxy(m_webContext); + uint64_t callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is fetching Website data", this); + + m_pendingFetchWebsiteDataCallbacks.add(callbackID, [this, token, completionHandler, sessionID](WebsiteData websiteData) { + completionHandler(WTFMove(websiteData)); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done fetching Website data", this); + }); + + send(Messages::NetworkProcess::FetchWebsiteData(sessionID, dataTypes, fetchOptions, callbackID), 0); +} + +void NetworkProcessProxy::deleteWebsiteData(WebCore::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) +{ + auto callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is deleting Website data", this); + + m_pendingDeleteWebsiteDataCallbacks.add(callbackID, [this, token, completionHandler, sessionID] { + completionHandler(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done deleting Website data", this); + }); + send(Messages::NetworkProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0); +} + +void NetworkProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, const Vector<WebCore::SecurityOriginData>& origins, const Vector<String>& cookieHostNames, std::function<void()> completionHandler) +{ + ASSERT(canSendMessage()); + + uint64_t callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is deleting Website data for several origins", this); + + m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, [this, token, completionHandler, sessionID] { + completionHandler(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done deleting Website data for several origins", this); + }); + + send(Messages::NetworkProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, cookieHostNames, callbackID), 0); } void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch() { // The network process must have crashed or exited, send any pending sync replies we might have. while (!m_pendingConnectionReplies.isEmpty()) { - RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); + Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); -#elif USE(UNIX_DOMAIN_SOCKETS) +#if USE(UNIX_DOMAIN_SOCKETS) reply->send(IPC::Attachment()); +#elif OS(DARWIN) + reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); #else notImplemented(); #endif } + for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values()) + callback(WebsiteData()); + m_pendingFetchWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataForOriginsCallbacks.clear(); + // Tell the network process manager to forget about this network process proxy. This may cause us to be deleted. - m_webContext.networkProcessCrashed(this); + m_processPool.networkProcessCrashed(this); } -void NetworkProcessProxy::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) +void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) { if (dispatchMessage(connection, decoder)) return; - if (m_webContext.dispatchMessage(connection, decoder)) + if (m_processPool.dispatchMessage(connection, decoder)) return; didReceiveNetworkProcessProxyMessage(connection, decoder); } -void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) +void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) { if (dispatchSyncMessage(connection, decoder, replyEncoder)) return; @@ -141,16 +216,19 @@ void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection* connection, IPC ASSERT_NOT_REACHED(); } -void NetworkProcessProxy::didClose(IPC::Connection*) +void NetworkProcessProxy::didClose(IPC::Connection&) { if (m_downloadProxyMap) m_downloadProxyMap->processDidClose(); + m_customProtocolManagerProxy.processDidClose(); + + m_tokenForHoldingLockedFiles = nullptr; // This may cause us to be deleted. networkProcessCrashedOrFailedToLaunch(); } -void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) +void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } @@ -161,10 +239,10 @@ void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const IPC::Atta // Grab the first pending connection reply. RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); -#elif USE(UNIX_DOMAIN_SOCKETS) +#if USE(UNIX_DOMAIN_SOCKETS) reply->send(connectionIdentifier); +#elif OS(DARWIN) + reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); #else notImplemented(); #endif @@ -175,8 +253,43 @@ void NetworkProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageID, uin WebPageProxy* page = WebProcessProxy::webPage(pageID); MESSAGE_CHECK(page); - RefPtr<AuthenticationChallengeProxy> authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, connection()); - page->didReceiveAuthenticationChallengeProxy(frameID, authenticationChallenge.release()); + auto authenticationChallenge = AuthenticationChallengeProxy::create(coreChallenge, challengeID, connection()); + page->didReceiveAuthenticationChallengeProxy(frameID, WTFMove(authenticationChallenge)); +} + +void NetworkProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData) +{ + auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID); + callback(websiteData); +} + +void NetworkProcessProxy::didDeleteWebsiteData(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID); + callback(); +} + +void NetworkProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID); + callback(); +} + +void NetworkProcessProxy::grantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, const Vector<String>& paths) +{ +#if ENABLE(DATABASE_PROCESS) +#if ENABLE(SANDBOX_EXTENSIONS) + SandboxExtension::HandleArray extensions; + extensions.allocate(paths.size()); + for (size_t i = 0; i < paths.size(); ++i) { + // ReadWrite is required for creating hard links as well as deleting the temporary file, which the DatabaseProcess will do. + SandboxExtension::createHandle(paths[i], SandboxExtension::ReadWrite, extensions[i]); + } + + m_processPool.sendToDatabaseProcessRelaunchingIfNecessary(Messages::DatabaseProcess::GrantSandboxExtensionsForBlobs(paths, extensions)); +#endif + connection()->send(Messages::NetworkProcess::DidGrantSandboxExtensionsToDatabaseProcessForBlobs(requestID), 0); +#endif } void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) @@ -184,7 +297,7 @@ void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Con ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); if (IPC::Connection::identifierIsNull(connectionIdentifier)) { - // FIXME: Do better cleanup here. + networkProcessCrashedOrFailedToLaunch(); return; } @@ -193,12 +306,108 @@ void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Con m_numPendingConnectionRequests = 0; -#if PLATFORM(MAC) - if (m_webContext.processSuppressionEnabled()) +#if PLATFORM(COCOA) + if (m_processPool.processSuppressionEnabled()) setProcessSuppressionEnabled(true); #endif + +#if PLATFORM(IOS) + if (xpc_connection_t connection = this->connection()->xpcConnection()) + m_throttler.didConnectToProcess(xpc_connection_get_pid(connection)); +#endif } -} // namespace WebKit +void NetworkProcessProxy::logDiagnosticMessage(uint64_t pageID, const String& message, const String& description, WebCore::ShouldSample shouldSample) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logDiagnosticMessage(message, description, shouldSample); +} + +void NetworkProcessProxy::logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logDiagnosticMessageWithResult(message, description, result, shouldSample); +} + +void NetworkProcessProxy::logDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample); +} -#endif // ENABLE(NETWORK_PROCESS) +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) +void NetworkProcessProxy::canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, const WebCore::ProtectionSpace& protectionSpace) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + if (!page) + return; + + page->canAuthenticateAgainstProtectionSpace(loaderID, frameID, protectionSpace); +} +#endif + +void NetworkProcessProxy::sendProcessWillSuspendImminently() +{ + if (!canSendMessage()) + return; + + bool handled = false; + sendSync(Messages::NetworkProcess::ProcessWillSuspendImminently(), Messages::NetworkProcess::ProcessWillSuspendImminently::Reply(handled), 0, 1_s); +} + +void NetworkProcessProxy::sendPrepareToSuspend() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::PrepareToSuspend(), 0); +} + +void NetworkProcessProxy::sendCancelPrepareToSuspend() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::CancelPrepareToSuspend(), 0); +} + +void NetworkProcessProxy::sendProcessDidResume() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::ProcessDidResume(), 0); +} + +void NetworkProcessProxy::processReadyToSuspend() +{ + m_throttler.processReadyToSuspend(); +} + +void NetworkProcessProxy::didSetAssertionState(AssertionState) +{ +} + +void NetworkProcessProxy::setIsHoldingLockedFiles(bool isHoldingLockedFiles) +{ + if (!isHoldingLockedFiles) { + RELEASE_LOG(ProcessSuspension, "UIProcess is releasing a background assertion because the Network process is no longer holding locked files"); + m_tokenForHoldingLockedFiles = nullptr; + return; + } + if (!m_tokenForHoldingLockedFiles) { + RELEASE_LOG(ProcessSuspension, "UIProcess is taking a background assertion because the Network process is holding locked files"); + m_tokenForHoldingLockedFiles = m_throttler.backgroundActivityToken(); + } +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h index ad13c702c..772840825 100644 --- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h +++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.h @@ -26,80 +26,114 @@ #ifndef NetworkProcessProxy_h #define NetworkProcessProxy_h -#if ENABLE(NETWORK_PROCESS) - #include "ChildProcessProxy.h" +#include "CustomProtocolManagerProxy.h" #include "ProcessLauncher.h" +#include "ProcessThrottler.h" +#include "ProcessThrottlerClient.h" #include "WebProcessProxyMessages.h" +#include <memory> #include <wtf/Deque.h> -#if ENABLE(CUSTOM_PROTOCOLS) -#include "CustomProtocolManagerProxy.h" -#endif - namespace WebCore { class AuthenticationChallenge; +class ProtectionSpace; +class ResourceRequest; +enum class ShouldSample; +class SecurityOrigin; +struct SecurityOriginData; +class SessionID; } namespace WebKit { class DownloadProxy; class DownloadProxyMap; -class WebContext; +class WebProcessPool; +enum class WebsiteDataFetchOption; +enum class WebsiteDataType; struct NetworkProcessCreationParameters; +struct WebsiteData; -class NetworkProcessProxy : public ChildProcessProxy { +class NetworkProcessProxy : public ChildProcessProxy, private ProcessThrottlerClient { public: - static PassRefPtr<NetworkProcessProxy> create(WebContext&); + static Ref<NetworkProcessProxy> create(WebProcessPool&); ~NetworkProcessProxy(); - void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>); + void getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&&); + + DownloadProxy* createDownloadProxy(const WebCore::ResourceRequest&); - DownloadProxy* createDownloadProxy(); + void fetchWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, std::function<void(WebsiteData)> completionHandler); + void deleteWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, std::chrono::system_clock::time_point modifiedSince, std::function<void()> completionHandler); + void deleteWebsiteDataForOrigins(WebCore::SessionID, OptionSet<WebKit::WebsiteDataType>, const Vector<WebCore::SecurityOriginData>& origins, const Vector<String>& cookieHostNames, std::function<void()> completionHandler); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void setProcessSuppressionEnabled(bool); #endif + void processReadyToSuspend(); + + void setIsHoldingLockedFiles(bool); + + ProcessThrottler& throttler() { return m_throttler; } + private: - NetworkProcessProxy(WebContext&); + NetworkProcessProxy(WebProcessPool&); // ChildProcessProxy - virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; - virtual void connectionWillOpen(IPC::Connection*) override; - virtual void connectionWillClose(IPC::Connection*) override; + void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; + void connectionWillOpen(IPC::Connection&) override; + void processWillShutDown(IPC::Connection&) override; - void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&); void networkProcessCrashedOrFailedToLaunch(); + // ProcessThrottlerClient + void sendProcessWillSuspendImminently() override; + void sendPrepareToSuspend() override; + void sendCancelPrepareToSuspend() override; + void sendProcessDidResume() override; + void didSetAssertionState(AssertionState) override; + // IPC::Connection::Client - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; - virtual void didClose(IPC::Connection*) override; - virtual void didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + void didClose(IPC::Connection&) override; + void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; // Message handlers - void didReceiveNetworkProcessProxyMessage(IPC::Connection*, IPC::MessageDecoder&); + void didReceiveNetworkProcessProxyMessage(IPC::Connection&, IPC::Decoder&); void didCreateNetworkConnectionToWebProcess(const IPC::Attachment&); void didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, const WebCore::AuthenticationChallenge&, uint64_t challengeID); + void didFetchWebsiteData(uint64_t callbackID, const WebsiteData&); + void didDeleteWebsiteData(uint64_t callbackID); + void didDeleteWebsiteDataForOrigins(uint64_t callbackID); + void grantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, const Vector<String>& paths); + void logDiagnosticMessage(uint64_t pageID, const String& message, const String& description, WebCore::ShouldSample); + void logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample); + void logDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample); +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + void canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, const WebCore::ProtectionSpace&); +#endif // ProcessLauncher::Client - virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier); + void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; - WebContext& m_webContext; + WebProcessPool& m_processPool; unsigned m_numPendingConnectionRequests; - Deque<RefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> m_pendingConnectionReplies; + Deque<Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> m_pendingConnectionReplies; - OwnPtr<DownloadProxyMap> m_downloadProxyMap; + HashMap<uint64_t, std::function<void (WebsiteData)>> m_pendingFetchWebsiteDataCallbacks; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataCallbacks; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataForOriginsCallbacks; -#if ENABLE(CUSTOM_PROTOCOLS) + std::unique_ptr<DownloadProxyMap> m_downloadProxyMap; CustomProtocolManagerProxy m_customProtocolManagerProxy; -#endif + ProcessThrottler m_throttler; + ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles; }; } // namespace WebKit -#endif // ENABLE(NETWORK_PROCESS) - #endif // NetworkProcessProxy_h diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in index 3b41a540a..0c902ed7a 100644 --- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in +++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.messages.in @@ -20,12 +20,26 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(NETWORK_PROCESS) - messages -> NetworkProcessProxy LegacyReceiver { DidCreateNetworkConnectionToWebProcess(IPC::Attachment connectionIdentifier) DidReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, WebCore::AuthenticationChallenge challenge, uint64_t challengeID) -} -#endif // ENABLE(NETWORK_PROCESS) + DidFetchWebsiteData(uint64_t callbackID, struct WebKit::WebsiteData websiteData) + DidDeleteWebsiteData(uint64_t callbackID) + DidDeleteWebsiteDataForOrigins(uint64_t callbackID) + + GrantSandboxExtensionsToDatabaseProcessForBlobs(uint64_t requestID, Vector<String> paths) + + ProcessReadyToSuspend() + SetIsHoldingLockedFiles(bool isHoldingLockedFiles) + + # Diagnostic messages logging + LogDiagnosticMessage(uint64_t pageID, String message, String description, enum WebCore::ShouldSample shouldSample) + LogDiagnosticMessageWithResult(uint64_t pageID, String message, String description, uint32_t result, enum WebCore::ShouldSample shouldSample) + LogDiagnosticMessageWithValue(uint64_t pageID, String message, String description, double value, unsigned significantFigures, enum WebCore::ShouldSample shouldSample) + +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) + CanAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t pageID, uint64_t frameID, WebCore::ProtectionSpace protectionSpace) +#endif +} diff --git a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.cpp b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.cpp index 25d37da4b..2128627c5 100644 --- a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.cpp +++ b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.cpp @@ -30,9 +30,9 @@ namespace WebKit { -PassRefPtr<NotificationPermissionRequest> NotificationPermissionRequest::create(WebKit::NotificationPermissionRequestManagerProxy *manager, uint64_t notificationID) +Ref<NotificationPermissionRequest> NotificationPermissionRequest::create(WebKit::NotificationPermissionRequestManagerProxy *manager, uint64_t notificationID) { - return adoptRef(new NotificationPermissionRequest(manager, notificationID)); + return adoptRef(*new NotificationPermissionRequest(manager, notificationID)); } NotificationPermissionRequest::NotificationPermissionRequest(NotificationPermissionRequestManagerProxy* manager, uint64_t notificationID) diff --git a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.h b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.h index fdc5294ec..e34199792 100644 --- a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.h +++ b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequest.h @@ -27,7 +27,6 @@ #define NotificationPermissionRequest_h #include "APIObject.h" -#include <wtf/PassRefPtr.h> namespace WebKit { @@ -35,7 +34,7 @@ class NotificationPermissionRequestManagerProxy; class NotificationPermissionRequest : public API::ObjectImpl<API::Object::Type::NotificationPermissionRequest> { public: - static PassRefPtr<NotificationPermissionRequest> create(NotificationPermissionRequestManagerProxy*, uint64_t notificationID); + static Ref<NotificationPermissionRequest> create(NotificationPermissionRequestManagerProxy*, uint64_t notificationID); void allow(); void deny(); diff --git a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequestManagerProxy.cpp b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequestManagerProxy.cpp index e9b8d8ceb..818a52541 100644 --- a/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequestManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/Notifications/NotificationPermissionRequestManagerProxy.cpp @@ -40,7 +40,7 @@ NotificationPermissionRequestManagerProxy::NotificationPermissionRequestManagerP void NotificationPermissionRequestManagerProxy::invalidateRequests() { - for (auto request : m_pendingRequests.values()) + for (auto& request : m_pendingRequests.values()) request->invalidate(); m_pendingRequests.clear(); @@ -48,9 +48,9 @@ void NotificationPermissionRequestManagerProxy::invalidateRequests() PassRefPtr<NotificationPermissionRequest> NotificationPermissionRequestManagerProxy::createRequest(uint64_t notificationID) { - RefPtr<NotificationPermissionRequest> request = NotificationPermissionRequest::create(this, notificationID); - m_pendingRequests.add(notificationID, request.get()); - return request.release(); + auto request = NotificationPermissionRequest::create(this, notificationID); + m_pendingRequests.add(notificationID, request.ptr()); + return WTFMove(request); } void NotificationPermissionRequestManagerProxy::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allow) diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp b/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp index 3705fb064..0a6736aa3 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp +++ b/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp @@ -26,11 +26,6 @@ #include "config.h" #include "WebNotification.h" -#include "ArgumentCoders.h" -#include "ArgumentDecoder.h" -#include "ArgumentEncoder.h" -#include "Arguments.h" - namespace WebKit { WebNotification::WebNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID) @@ -40,7 +35,7 @@ WebNotification::WebNotification(const String& title, const String& body, const , m_tag(tag) , m_lang(lang) , m_dir(dir) - , m_origin(WebSecurityOrigin::createFromString(originString)) + , m_origin(API::SecurityOrigin::createFromString(originString)) , m_notificationID(notificationID) { } diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotification.h b/Source/WebKit2/UIProcess/Notifications/WebNotification.h index 3682b4f9d..fa4c494d1 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotification.h +++ b/Source/WebKit2/UIProcess/Notifications/WebNotification.h @@ -27,25 +27,17 @@ #define WebNotification_h #include "APIObject.h" -#include "WebSecurityOrigin.h" -#include <wtf/PassRefPtr.h> +#include "APISecurityOrigin.h" #include <wtf/RefPtr.h> #include <wtf/text/WTFString.h> -namespace IPC { - -class ArgumentDecoder; -class ArgumentEncoder; - -} // namespace IPC - namespace WebKit { class WebNotification : public API::ObjectImpl<API::Object::Type::Notification> { public: - static PassRefPtr<WebNotification> create(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID) + static Ref<WebNotification> create(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID) { - return adoptRef(new WebNotification(title, body, iconURL, tag, lang, dir, originString, notificationID)); + return adoptRef(*new WebNotification(title, body, iconURL, tag, lang, dir, originString, notificationID)); } const String& title() const { return m_title; } @@ -54,7 +46,7 @@ public: const String& tag() const { return m_tag; } const String& lang() const { return m_lang; } const String& dir() const { return m_dir; } - WebSecurityOrigin* origin() const { return m_origin.get(); } + API::SecurityOrigin* origin() const { return m_origin.get(); } uint64_t notificationID() const { return m_notificationID; } @@ -67,7 +59,7 @@ private: String m_tag; String m_lang; String m_dir; - RefPtr<WebSecurityOrigin> m_origin; + RefPtr<API::SecurityOrigin> m_origin; uint64_t m_notificationID; }; diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp index 39809fd50..a034007d7 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp @@ -27,16 +27,14 @@ #include "WebNotificationManagerProxy.h" #include "APIArray.h" -#include "ImmutableDictionary.h" -#include "WebContext.h" +#include "APIDictionary.h" +#include "APISecurityOrigin.h" #include "WebNotification.h" #include "WebNotificationManagerMessages.h" #include "WebPageProxy.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" -#include "WebSecurityOrigin.h" -using namespace std; -using namespace WTF; using namespace WebCore; namespace WebKit { @@ -52,13 +50,13 @@ const char* WebNotificationManagerProxy::supplementName() return "WebNotificationManagerProxy"; } -PassRefPtr<WebNotificationManagerProxy> WebNotificationManagerProxy::create(WebContext* context) +Ref<WebNotificationManagerProxy> WebNotificationManagerProxy::create(WebProcessPool* processPool) { - return adoptRef(new WebNotificationManagerProxy(context)); + return adoptRef(*new WebNotificationManagerProxy(processPool)); } -WebNotificationManagerProxy::WebNotificationManagerProxy(WebContext* context) - : WebContextSupplement(context) +WebNotificationManagerProxy::WebNotificationManagerProxy(WebProcessPool* processPool) + : WebContextSupplement(processPool) { } @@ -70,7 +68,7 @@ void WebNotificationManagerProxy::initializeProvider(const WKNotificationProvide // WebContextSupplement -void WebNotificationManagerProxy::contextDestroyed() +void WebNotificationManagerProxy::processPoolDestroyed() { m_provider.removeNotificationManager(this); } @@ -87,13 +85,13 @@ void WebNotificationManagerProxy::derefWebContextSupplement() void WebNotificationManagerProxy::populateCopyOfNotificationPermissions(HashMap<String, bool>& permissions) { - RefPtr<ImmutableDictionary> knownPermissions = m_provider.notificationPermissions(); + RefPtr<API::Dictionary> knownPermissions = m_provider.notificationPermissions(); if (!knownPermissions) return; permissions.clear(); - RefPtr<API::Array> knownOrigins = knownPermissions->keys(); + Ref<API::Array> knownOrigins = knownPermissions->keys(); for (size_t i = 0; i < knownOrigins->size(); ++i) { API::String* origin = knownOrigins->at<API::String>(i); permissions.set(origin->string(), knownPermissions->get<API::Boolean>(origin->string())->value()); @@ -217,7 +215,7 @@ void WebNotificationManagerProxy::providerDidCloseNotifications(API::Array* glob if (pageIt == pageNotificationIDs.end()) { Vector<uint64_t> newVector; newVector.reserveInitialCapacity(size); - pageIt = pageNotificationIDs.add(webPage, newVector).iterator; + pageIt = pageNotificationIDs.add(webPage, WTFMove(newVector)).iterator; } uint64_t pageNotificationID = it->value.second; @@ -232,17 +230,17 @@ void WebNotificationManagerProxy::providerDidCloseNotifications(API::Array* glob it->key->process().send(Messages::WebNotificationManager::DidCloseNotifications(it->value), 0); } -void WebNotificationManagerProxy::providerDidUpdateNotificationPolicy(const WebSecurityOrigin* origin, bool allowed) +void WebNotificationManagerProxy::providerDidUpdateNotificationPolicy(const API::SecurityOrigin* origin, bool allowed) { - if (!context()) + if (!processPool()) return; - context()->sendToAllProcesses(Messages::WebNotificationManager::DidUpdateNotificationDecision(origin->toString(), allowed)); + processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidUpdateNotificationDecision(origin->securityOrigin().toString(), allowed)); } void WebNotificationManagerProxy::providerDidRemoveNotificationPolicies(API::Array* origins) { - if (!context()) + if (!processPool()) return; size_t size = origins->size(); @@ -253,9 +251,21 @@ void WebNotificationManagerProxy::providerDidRemoveNotificationPolicies(API::Arr originStrings.reserveInitialCapacity(size); for (size_t i = 0; i < size; ++i) - originStrings.append(origins->at<WebSecurityOrigin>(i)->toString()); + originStrings.append(origins->at<API::SecurityOrigin>(i)->securityOrigin().toString()); - context()->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(originStrings)); + processPool()->sendToAllProcesses(Messages::WebNotificationManager::DidRemoveNotificationDecisions(originStrings)); +} + +uint64_t WebNotificationManagerProxy::notificationLocalIDForTesting(WebNotification* notification) +{ + if (!notification) + return 0; + + auto it = m_globalNotificationMap.find(notification->notificationID()); + if (it == m_globalNotificationMap.end()) + return 0; + + return it->value.second; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h index 591df5b1d..edca5ccf8 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h @@ -32,26 +32,24 @@ #include "WebNotificationProvider.h" #include <WebCore/NotificationClient.h> #include <wtf/HashMap.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> #include <wtf/text/StringHash.h> namespace API { class Array; +class SecurityOrigin; } namespace WebKit { -class WebContext; class WebPageProxy; -class WebSecurityOrigin; +class WebProcessPool; class WebNotificationManagerProxy : public API::ObjectImpl<API::Object::Type::NotificationManager>, public WebContextSupplement { public: static const char* supplementName(); - static PassRefPtr<WebNotificationManagerProxy> create(WebContext*); + static Ref<WebNotificationManagerProxy> create(WebProcessPool*); void initializeProvider(const WKNotificationProviderBase*); void populateCopyOfNotificationPermissions(HashMap<String, bool>&); @@ -65,22 +63,24 @@ public: void providerDidShowNotification(uint64_t notificationID); void providerDidClickNotification(uint64_t notificationID); void providerDidCloseNotifications(API::Array* notificationIDs); - void providerDidUpdateNotificationPolicy(const WebSecurityOrigin*, bool allowed); + void providerDidUpdateNotificationPolicy(const API::SecurityOrigin*, bool allowed); void providerDidRemoveNotificationPolicies(API::Array* origins); + uint64_t notificationLocalIDForTesting(WebNotification*); + using API::Object::ref; using API::Object::deref; private: - explicit WebNotificationManagerProxy(WebContext*); + explicit WebNotificationManagerProxy(WebProcessPool*); typedef bool (*NotificationFilterFunction)(uint64_t pageID, uint64_t pageNotificationID, uint64_t desiredPageID, const Vector<uint64_t>& desiredPageNotificationIDs); void clearNotifications(WebPageProxy*, const Vector<uint64_t>& pageNotificationIDs, NotificationFilterFunction); // WebContextSupplement - virtual void contextDestroyed() override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; + void processPoolDestroyed() override; + void refWebContextSupplement() override; + void derefWebContextSupplement() override; WebNotificationProvider m_provider; // Pair comprised of web page ID and the web process's notification ID diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.cpp b/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.cpp index 545e4153d..a2a83ada0 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.cpp +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.cpp @@ -27,12 +27,13 @@ #include "WebNotificationProvider.h" #include "APIArray.h" +#include "APIDictionary.h" #include "APINumber.h" -#include "ImmutableDictionary.h" +#include "APISecurityOrigin.h" #include "WKAPICast.h" #include "WebNotification.h" #include "WebNotificationManagerProxy.h" -#include "WebSecurityOrigin.h" +#include "WebPageProxy.h" namespace WebKit { @@ -71,7 +72,7 @@ void WebNotificationProvider::clearNotifications(const Vector<uint64_t>& notific for (const auto& notificationID : notificationIDs) arrayIDs.uncheckedAppend(API::UInt64::create(notificationID)); - m_client.clearNotifications(toAPI(API::Array::create(std::move(arrayIDs)).get()), m_client.base.clientInfo); + m_client.clearNotifications(toAPI(API::Array::create(WTFMove(arrayIDs)).ptr()), m_client.base.clientInfo); } void WebNotificationProvider::addNotificationManager(WebNotificationManagerProxy* manager) @@ -90,10 +91,10 @@ void WebNotificationProvider::removeNotificationManager(WebNotificationManagerPr m_client.removeNotificationManager(toAPI(manager), m_client.base.clientInfo); } -PassRefPtr<ImmutableDictionary> WebNotificationProvider::notificationPermissions() +PassRefPtr<API::Dictionary> WebNotificationProvider::notificationPermissions() { if (!m_client.notificationPermissions) - return ImmutableDictionary::create(); + return API::Dictionary::create(); return adoptRef(toImpl(m_client.notificationPermissions(m_client.base.clientInfo))); } diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.h b/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.h index b48d43346..14fabe16c 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.h +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationProvider.h @@ -32,6 +32,9 @@ #include <wtf/Vector.h> namespace API { + +class Dictionary; + template<> struct ClientTraits<WKNotificationProviderBase> { typedef std::tuple<WKNotificationProviderV0> Versions; }; @@ -39,11 +42,9 @@ template<> struct ClientTraits<WKNotificationProviderBase> { namespace WebKit { -class ImmutableDictionary; class WebNotification; class WebNotificationManagerProxy; class WebPageProxy; -class WebSecurityOrigin; class WebNotificationProvider : public API::Client<WKNotificationProviderBase> { public: @@ -55,7 +56,7 @@ public: void addNotificationManager(WebNotificationManagerProxy*); void removeNotificationManager(WebNotificationManagerProxy*); - PassRefPtr<ImmutableDictionary> notificationPermissions(); + PassRefPtr<API::Dictionary> notificationPermissions(); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/PageClient.h b/Source/WebKit2/UIProcess/PageClient.h index 018b1baf9..a5467f94b 100644 --- a/Source/WebKit2/UIProcess/PageClient.h +++ b/Source/WebKit2/UIProcess/PageClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,8 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef PageClient_h -#define PageClient_h +#pragma once #include "ShareableBitmap.h" #include "WebColorPicker.h" @@ -32,9 +31,11 @@ #include "WebPopupMenuProxy.h" #include <WebCore/AlternativeTextClient.h> #include <WebCore/EditorClient.h> +#include <WebCore/UserInterfaceLayoutDirection.h> +#include <WebCore/ValidationBubble.h> #include <wtf/Forward.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include "PluginComplexTextInputState.h" OBJC_CLASS CALayer; @@ -46,15 +47,22 @@ OBJC_CLASS NSTextAlternatives; #endif namespace WebCore { - class Cursor; - struct ViewportAttributes; +class Cursor; +class TextIndicator; +class WebMediaSessionManager; +enum class TextIndicatorWindowLifetime : uint8_t; +enum class TextIndicatorWindowDismissalAnimation : uint8_t; +struct Highlight; +struct ViewportAttributes; } namespace WebKit { class DrawingAreaProxy; -class FindIndicator; class NativeWebKeyboardEvent; +class NativeWebMouseEvent; +class RemoteLayerTreeTransaction; +class ViewSnapshot; class WebContextMenuProxy; class WebEditCommandProxy; class WebPopupMenuProxy; @@ -71,7 +79,11 @@ class WebColorPicker; class WebFullScreenManagerProxyClient; #endif -#if PLATFORM(MAC) +#if USE(GSTREAMER) +class InstallMissingMediaPluginsPermissionRequest; +#endif + +#if PLATFORM(COCOA) struct ColorSpaceData; #endif @@ -82,16 +94,11 @@ public: // Create a new drawing area proxy for the given page. virtual std::unique_ptr<DrawingAreaProxy> createDrawingAreaProxy() = 0; - // Tell the view to invalidate the given rect. The rect is in view coordinates. - virtual void setViewNeedsDisplay(const WebCore::IntRect&) = 0; + // Tell the view to invalidate the given region. The region is in view coordinates. + virtual void setViewNeedsDisplay(const WebCore::Region&) = 0; - // Tell the view to immediately display its invalid rect. - virtual void displayView() = 0; - - // Return true if scrollView() can copy bits in the view. - virtual bool canScrollView() = 0; - // Tell the view to scroll scrollRect by scrollOffset. - virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset) = 0; + // Tell the view to scroll to the given position, and whether this was a programmatic scroll. + virtual void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, bool isProgrammaticScroll) = 0; // Return the size of the view the page is associated with. virtual WebCore::IntSize viewSize() = 0; @@ -105,6 +112,9 @@ public: // Return whether the view is visible. virtual bool isViewVisible() = 0; + // Return whether the view is visible, or occluded by another window. + virtual bool isViewVisibleOrOccluded() { return isViewVisible(); } + // Return whether the view is in a window. virtual bool isViewInWindow() = 0; @@ -112,9 +122,9 @@ public: virtual bool isVisuallyIdle() { return !isViewVisible(); } // Return the layer hosting mode for the view. - virtual LayerHostingMode viewLayerHostingMode() { return LayerHostingModeDefault; } + virtual LayerHostingMode viewLayerHostingMode() { return LayerHostingMode::InProcess; } - virtual void processDidCrash() = 0; + virtual void processDidExit() = 0; virtual void didRelaunchProcess() = 0; virtual void pageClosed() = 0; @@ -122,36 +132,30 @@ public: virtual void toolTipChanged(const String&, const String&) = 0; - virtual bool decidePolicyForGeolocationPermissionRequest(WebFrameProxy&, WebSecurityOrigin&, GeolocationPermissionRequestProxy&) + virtual bool decidePolicyForGeolocationPermissionRequest(WebFrameProxy&, API::SecurityOrigin&, GeolocationPermissionRequestProxy&) { return false; } - virtual void didCommitLoadForMainFrame() = 0; + virtual void didStartProvisionalLoadForMainFrame() { }; + virtual void didFailProvisionalLoadForMainFrame() { }; + virtual void didCommitLoadForMainFrame(const String& mimeType, bool useCustomContentProvider) = 0; -#if USE(TILED_BACKING_STORE) +#if USE(COORDINATED_GRAPHICS_MULTIPROCESS) virtual void pageDidRequestScroll(const WebCore::IntPoint&) = 0; virtual void didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect) = 0; virtual void pageTransitionViewportReady() = 0; -#endif -#if USE(COORDINATED_GRAPHICS) virtual void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&) = 0; #endif -#if PLATFORM(EFL) || PLATFORM(GTK) - virtual void updateTextInputState() = 0; -#endif // PLATFORM(EFL) || PLATOFRM(GTK) - -#if PLATFORM(EFL) || PLATFORM(GTK) virtual void handleDownloadRequest(DownloadProxy*) = 0; -#endif // PLATFORM(EFL) || PLATFORM(GTK) -#if PLATFORM(EFL) || PLATFORM(IOS) + virtual bool handleRunOpenPanel(WebPageProxy*, WebFrameProxy*, API::OpenPanelParameters*, WebOpenPanelResultListenerProxy*) { return false; } + virtual void didChangeContentSize(const WebCore::IntSize&) = 0; -#endif #if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT) - virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) = 0; + virtual void startDrag(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&& dragImage) = 0; #endif virtual void setCursor(const WebCore::Cursor&) = 0; @@ -162,69 +166,106 @@ public: virtual void clearAllEditCommands() = 0; virtual bool canUndoRedo(WebPageProxy::UndoOrRedo) = 0; virtual void executeUndoRedo(WebPageProxy::UndoOrRedo) = 0; -#if PLATFORM(MAC) + virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) = 0; +#if PLATFORM(COCOA) virtual void accessibilityWebProcessTokenReceived(const IPC::DataReference&) = 0; - virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, Vector<WebCore::KeypressCommand>&) = 0; virtual bool executeSavedCommandBySelector(const String& selector) = 0; virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) = 0; virtual void updateSecureInputState() = 0; virtual void resetSecureInputState() = 0; virtual void notifyInputContextAboutDiscardedComposition() = 0; virtual void makeFirstResponder() = 0; - virtual void setAcceleratedCompositingRootLayer(CALayer *) = 0; - virtual CALayer *acceleratedCompositingRootLayer() const = 0; - virtual RetainPtr<CGImageRef> takeViewSnapshot() = 0; - virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) = 0; + virtual void setAcceleratedCompositingRootLayer(LayerOrView *) = 0; + virtual LayerOrView *acceleratedCompositingRootLayer() const = 0; + virtual PassRefPtr<ViewSnapshot> takeViewSnapshot() = 0; +#if ENABLE(MAC_GESTURE_EVENTS) + virtual void gestureEventWasNotHandledByWebCore(const NativeWebGestureEvent&) = 0; +#endif +#endif + +#if PLATFORM(COCOA) || PLATFORM(GTK) + virtual void selectionDidChange() = 0; #endif #if USE(APPKIT) - virtual void setPromisedData(const String& pasteboardName, PassRefPtr<WebCore::SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title, + virtual void setPromisedDataForImage(const String& pasteboardName, PassRefPtr<WebCore::SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title, const String& url, const String& visibleUrl, PassRefPtr<WebCore::SharedBuffer> archiveBuffer) = 0; -#endif +#if ENABLE(ATTACHMENT_ELEMENT) + virtual void setPromisedDataForAttachment(const String& pasteboardName, const String& filename, const String& extension, const String& title, + const String& url, const String& visibleUrl) = 0; -#if PLATFORM(GTK) - virtual void getEditorCommandsForKeyEvent(const NativeWebKeyboardEvent&, const AtomicString&, Vector<WTF::String>&) = 0; #endif +#endif + virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&) = 0; virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&) = 0; - virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&) = 0; - virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) = 0; + virtual WebCore::IntPoint screenToRootView(const WebCore::IntPoint&) = 0; + virtual WebCore::IntRect rootViewToScreen(const WebCore::IntRect&) = 0; +#if PLATFORM(MAC) + virtual WebCore::IntRect rootViewToWindow(const WebCore::IntRect&) = 0; +#endif +#if PLATFORM(IOS) + virtual WebCore::IntPoint accessibilityScreenToRootView(const WebCore::IntPoint&) = 0; + virtual WebCore::IntRect rootViewToAccessibilityScreen(const WebCore::IntRect&) = 0; + virtual void didNotHandleTapAsClick(const WebCore::IntPoint&) = 0; +#endif virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) = 0; #if ENABLE(TOUCH_EVENTS) virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) = 0; #endif - virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*) = 0; - virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*) = 0; + virtual RefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy&) = 0; +#if ENABLE(CONTEXT_MENUS) + virtual std::unique_ptr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy&, const ContextMenuContextData&, const UserData&) = 0; +#endif #if ENABLE(INPUT_TYPE_COLOR) - virtual PassRefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) = 0; + virtual RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&) = 0; +#endif + +#if PLATFORM(COCOA) + virtual Ref<WebCore::ValidationBubble> createValidationBubble(const String& message, const WebCore::ValidationBubble::Settings&) = 0; #endif - virtual void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate) = 0; +#if PLATFORM(COCOA) + virtual void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorWindowLifetime) = 0; + virtual void clearTextIndicator(WebCore::TextIndicatorWindowDismissalAnimation) = 0; + virtual void setTextIndicatorAnimationProgress(float) = 0; +#endif -#if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&) = 0; virtual void exitAcceleratedCompositingMode() = 0; virtual void updateAcceleratedCompositingMode(const LayerTreeContext&) = 0; -#endif -#if !PLATFORM(IOS) && PLATFORM(MAC) +#if PLATFORM(MAC) virtual void pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus) = 0; virtual void setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, PluginComplexTextInputState) = 0; - virtual void didPerformDictionaryLookup(const AttributedString&, const DictionaryPopupInfo&) = 0; - virtual void dismissDictionaryLookupPanel() = 0; + virtual void didPerformDictionaryLookup(const WebCore::DictionaryPopupInfo&) = 0; + virtual void dismissContentRelativeChildWindows(bool withAnimation = true) = 0; virtual void showCorrectionPanel(WebCore::AlternativeTextType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) = 0; virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingAlternativeText) = 0; virtual String dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAlternativeText) = 0; - virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponseType, const String& replacedString, const String& replacementString) = 0; - virtual void recommendedScrollbarStyleDidChange(int32_t newStyle) = 0; + virtual void recordAutocorrectionResponse(WebCore::AutocorrectionResponse, const String& replacedString, const String& replacementString) = 0; + virtual void recommendedScrollbarStyleDidChange(WebCore::ScrollbarStyle) = 0; + virtual void removeNavigationGestureSnapshot() = 0; + virtual void handleControlledElementIDResponse(const String&) = 0; + + virtual CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const = 0; virtual ColorSpaceData colorSpace() = 0; + virtual void showPlatformContextMenu(NSMenu *, WebCore::IntPoint) = 0; + + virtual void startWindowDrag() = 0; + virtual NSWindow *platformWindow() = 0; + +#if WK_API_ENABLED + virtual NSView *inspectorAttachmentView() = 0; + virtual _WKRemoteObjectRegistry *remoteObjectRegistry() = 0; +#endif + #if USE(APPKIT) - virtual WKView* wkView() const = 0; virtual void intrinsicContentSizeDidChange(const WebCore::IntSize& intrinsicContentSize) = 0; #if USE(DICTATION_ALTERNATIVES) virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&) = 0; @@ -232,29 +273,115 @@ public: virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext) = 0; virtual Vector<String> dictationAlternatives(uint64_t dictationContext) = 0; #endif // USE(DICTATION_ALTERNATIVES) +#if USE(INSERTION_UNDO_GROUPING) + virtual void registerInsertionUndoGrouping() = 0; +#endif // USE(INSERTION_UNDO_GROUPING) #endif // USE(APPKIT) + virtual void setEditableElementIsFocused(bool) = 0; #endif // PLATFORM(MAC) -#if PLATFORM(IOS) - virtual void mainDocumentDidReceiveMobileDocType() = 0; +#if PLATFORM(COCOA) + virtual void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) = 0; +#endif +#if PLATFORM(IOS) + virtual void commitPotentialTapFailed() = 0; virtual void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color&, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius) = 0; - virtual void didChangeViewportArguments(const WebCore::ViewportArguments&) = 0; + virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) = 0; + virtual void layerTreeCommitComplete() = 0; - virtual void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable) = 0; + virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition, uint64_t transactionID) = 0; + virtual void couldNotRestorePageState() = 0; + virtual void restorePageState(const WebCore::FloatPoint& scrollPosition, const WebCore::FloatPoint& scrollOrigin, const WebCore::FloatSize& obscuredInsetOnSave, double scale) = 0; + virtual void restorePageCenterAndScale(const WebCore::FloatPoint& center, double scale) = 0; + + virtual void startAssistingNode(const AssistedNodeInformation&, bool userIsInteracting, bool blurPreviousNode, API::Object* userData) = 0; virtual void stopAssistingNode() = 0; - virtual void selectionDidChange() = 0; + virtual bool isAssistingNode() = 0; virtual bool interpretKeyEvent(const NativeWebKeyboardEvent&, bool isCharEvent) = 0; virtual void positionInformationDidChange(const InteractionInformationAtPosition&) = 0; + virtual void saveImageToLibrary(PassRefPtr<WebCore::SharedBuffer>) = 0; + virtual void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) = 0; + virtual void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect) = 0; + virtual void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale) = 0; + virtual void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) = 0; + virtual double minimumZoomScale() const = 0; + virtual WebCore::FloatRect documentRect() const = 0; + virtual void overflowScrollViewWillStartPanGesture() = 0; + virtual void overflowScrollViewDidScroll() = 0; + virtual void overflowScrollWillStartScroll() = 0; + virtual void overflowScrollDidEndScroll() = 0; + virtual Vector<String> mimeTypesWithCustomContentProviders() = 0; + + virtual void showInspectorHighlight(const WebCore::Highlight&) = 0; + virtual void hideInspectorHighlight() = 0; + + virtual void showInspectorIndication() = 0; + virtual void hideInspectorIndication() = 0; + + virtual void enableInspectorNodeSearch() = 0; + virtual void disableInspectorNodeSearch() = 0; #endif // Auxiliary Client Creation #if ENABLE(FULLSCREEN_API) virtual WebFullScreenManagerProxyClient& fullScreenManagerProxyClient() = 0; #endif + + // Custom representations. + virtual void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&) = 0; + + virtual void navigationGestureDidBegin() = 0; + virtual void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&) = 0; + virtual void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&) = 0; + virtual void navigationGestureDidEnd() = 0; + virtual void willRecordNavigationSnapshot(WebBackForwardListItem&) = 0; + virtual void didRemoveNavigationGestureSnapshot() = 0; + + virtual void didFirstVisuallyNonEmptyLayoutForMainFrame() = 0; + virtual void didFinishLoadForMainFrame() = 0; + virtual void didFailLoadForMainFrame() = 0; + virtual void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) = 0; + + virtual void didChangeBackgroundColor() = 0; + +#if PLATFORM(MAC) + virtual void didPerformImmediateActionHitTest(const WebHitTestResultData&, bool contentPreventsDefault, API::Object*) = 0; + + virtual void* immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult>, uint64_t, RefPtr<API::Object>) = 0; + + virtual void didHandleAcceptedCandidate() = 0; + + virtual void videoControlsManagerDidChange() = 0; +#endif + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + virtual WebCore::WebMediaSessionManager& mediaSessionManager() = 0; +#endif + + virtual void refView() = 0; + virtual void derefView() = 0; + +#if ENABLE(VIDEO) && USE(GSTREAMER) + virtual bool decidePolicyForInstallMissingMediaPluginsPermissionRequest(InstallMissingMediaPluginsPermissionRequest&) = 0; +#endif + + virtual void didRestoreScrollPosition() = 0; + + virtual bool windowIsFrontWindowUnderMouse(const NativeWebMouseEvent&) { return false; } + + virtual WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection() = 0; + +#if USE(QUICK_LOOK) + virtual void requestPasswordForQuickLookDocument(const String& fileName, std::function<void(const String&)>&&) = 0; +#endif + +#if ENABLE(DATA_INTERACTION) + virtual void didPerformDataInteractionControllerOperation() = 0; + virtual void didHandleStartDataInteractionRequest(bool started) = 0; + virtual void startDataInteractionWithImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& image, const WebCore::FloatPoint& anchorPoint, bool isLink) = 0; +#endif }; } // namespace WebKit - -#endif // PageClient_h diff --git a/Source/WebKit2/UIProcess/PageLoadState.cpp b/Source/WebKit2/UIProcess/PageLoadState.cpp index d4044165c..dd9d4c7d9 100644 --- a/Source/WebKit2/UIProcess/PageLoadState.cpp +++ b/Source/WebKit2/UIProcess/PageLoadState.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,13 +26,16 @@ #include "config.h" #include "PageLoadState.h" +#include "WebPageProxy.h" + namespace WebKit { // Progress always starts at this value. This helps provide feedback as soon as a load starts. static const double initialProgressValue = 0.1; -PageLoadState::PageLoadState() - : m_mayHaveUncommittedChanges(false) +PageLoadState::PageLoadState(WebPageProxy& webPageProxy) + : m_webPageProxy(webPageProxy) + , m_mayHaveUncommittedChanges(false) , m_outstandingTransactionCount(0) { } @@ -42,6 +45,26 @@ PageLoadState::~PageLoadState() ASSERT(m_observers.isEmpty()); } +PageLoadState::Transaction::Transaction(PageLoadState& pageLoadState) + : m_webPageProxy(&pageLoadState.m_webPageProxy) + , m_pageLoadState(&pageLoadState) +{ + m_pageLoadState->beginTransaction(); +} + +PageLoadState::Transaction::Transaction(Transaction&& other) + : m_webPageProxy(WTFMove(other.m_webPageProxy)) + , m_pageLoadState(other.m_pageLoadState) +{ + other.m_pageLoadState = nullptr; +} + +PageLoadState::Transaction::~Transaction() +{ + if (m_pageLoadState) + m_pageLoadState->endTransaction(); +} + void PageLoadState::addObserver(Observer& observer) { ASSERT(!m_observers.contains(&observer)); @@ -51,10 +74,8 @@ void PageLoadState::addObserver(Observer& observer) void PageLoadState::removeObserver(Observer& observer) { - ASSERT(m_observers.contains(&observer)); - - size_t index = m_observers.find(&observer); - m_observers.remove(index); + bool removed = m_observers.removeFirst(&observer); + ASSERT_UNUSED(removed, removed); } void PageLoadState::endTransaction() @@ -72,12 +93,20 @@ void PageLoadState::commitChanges() m_mayHaveUncommittedChanges = false; + bool canGoBackChanged = m_committedState.canGoBack != m_uncommittedState.canGoBack; + bool canGoForwardChanged = m_committedState.canGoForward != m_uncommittedState.canGoForward; bool titleChanged = m_committedState.title != m_uncommittedState.title; - bool isLoadingChanged = isLoadingState(m_committedState.state) != isLoadingState(m_uncommittedState.state); + bool isLoadingChanged = isLoading(m_committedState) != isLoading(m_uncommittedState); bool activeURLChanged = activeURL(m_committedState) != activeURL(m_uncommittedState); bool hasOnlySecureContentChanged = hasOnlySecureContent(m_committedState) != hasOnlySecureContent(m_uncommittedState); bool estimatedProgressChanged = estimatedProgress(m_committedState) != estimatedProgress(m_uncommittedState); + bool networkRequestsInProgressChanged = m_committedState.networkRequestsInProgress != m_uncommittedState.networkRequestsInProgress; + bool certificateInfoChanged = m_committedState.certificateInfo != m_uncommittedState.certificateInfo; + if (canGoBackChanged) + callObserverCallback(&Observer::willChangeCanGoBack); + if (canGoForwardChanged) + callObserverCallback(&Observer::willChangeCanGoForward); if (titleChanged) callObserverCallback(&Observer::willChangeTitle); if (isLoadingChanged) @@ -88,10 +117,20 @@ void PageLoadState::commitChanges() callObserverCallback(&Observer::willChangeHasOnlySecureContent); if (estimatedProgressChanged) callObserverCallback(&Observer::willChangeEstimatedProgress); + if (networkRequestsInProgressChanged) + callObserverCallback(&Observer::willChangeNetworkRequestsInProgress); + if (certificateInfoChanged) + callObserverCallback(&Observer::willChangeCertificateInfo); m_committedState = m_uncommittedState; + m_webPageProxy.isLoadingChanged(); + // The "did" ordering is the reverse of the "will". This is a requirement of Cocoa Key-Value Observing. + if (certificateInfoChanged) + callObserverCallback(&Observer::didChangeCertificateInfo); + if (networkRequestsInProgressChanged) + callObserverCallback(&Observer::didChangeNetworkRequestsInProgress); if (estimatedProgressChanged) callObserverCallback(&Observer::didChangeEstimatedProgress); if (hasOnlySecureContentChanged) @@ -102,6 +141,10 @@ void PageLoadState::commitChanges() callObserverCallback(&Observer::didChangeIsLoading); if (titleChanged) callObserverCallback(&Observer::didChangeTitle); + if (canGoForwardChanged) + callObserverCallback(&Observer::didChangeCanGoForward); + if (canGoBackChanged) + callObserverCallback(&Observer::didChangeCanGoBack); } void PageLoadState::reset(const Transaction::Token& token) @@ -121,11 +164,12 @@ void PageLoadState::reset(const Transaction::Token& token) m_uncommittedState.title = String(); m_uncommittedState.estimatedProgress = 0; + m_uncommittedState.networkRequestsInProgress = false; } bool PageLoadState::isLoading() const { - return isLoadingState(m_committedState.state); + return isLoading(m_committedState); } String PageLoadState::activeURL(const Data& data) @@ -161,7 +205,7 @@ bool PageLoadState::hasOnlySecureContent(const Data& data) if (data.hasInsecureContent) return false; - return data.url.startsWith("https:", false); + return WebCore::protocolIs(data.url, "https"); } bool PageLoadState::hasOnlySecureContent() const @@ -230,13 +274,14 @@ void PageLoadState::didFailProvisionalLoad(const Transaction::Token& token) m_uncommittedState.unreachableURL = m_lastUnreachableURL; } -void PageLoadState::didCommitLoad(const Transaction::Token& token) +void PageLoadState::didCommitLoad(const Transaction::Token& token, WebCertificateInfo& certificateInfo, bool hasInsecureContent) { ASSERT_UNUSED(token, &token.m_pageLoadState == this); ASSERT(m_uncommittedState.state == State::Provisional); m_uncommittedState.state = State::Committed; - m_uncommittedState.hasInsecureContent = false; + m_uncommittedState.hasInsecureContent = hasInsecureContent; + m_uncommittedState.certificateInfo = &certificateInfo; m_uncommittedState.url = m_uncommittedState.provisionalURL; m_uncommittedState.provisionalURL = String(); @@ -295,6 +340,28 @@ void PageLoadState::setTitle(const Transaction::Token& token, const String& titl m_uncommittedState.title = title; } +bool PageLoadState::canGoBack() const +{ + return m_committedState.canGoBack; +} + +void PageLoadState::setCanGoBack(const Transaction::Token& token, bool canGoBack) +{ + ASSERT_UNUSED(token, &token.m_pageLoadState == this); + m_uncommittedState.canGoBack = canGoBack; +} + +bool PageLoadState::canGoForward() const +{ + return m_committedState.canGoForward; +} + +void PageLoadState::setCanGoForward(const Transaction::Token& token, bool canGoForward) +{ + ASSERT_UNUSED(token, &token.m_pageLoadState == this); + m_uncommittedState.canGoForward = canGoForward; +} + void PageLoadState::didStartProgress(const Transaction::Token& token) { ASSERT_UNUSED(token, &token.m_pageLoadState == this); @@ -313,9 +380,18 @@ void PageLoadState::didFinishProgress(const Transaction::Token& token) m_uncommittedState.estimatedProgress = 1; } -bool PageLoadState::isLoadingState(State state) +void PageLoadState::setNetworkRequestsInProgress(const Transaction::Token& token, bool networkRequestsInProgress) +{ + ASSERT_UNUSED(token, &token.m_pageLoadState == this); + m_uncommittedState.networkRequestsInProgress = networkRequestsInProgress; +} + +bool PageLoadState::isLoading(const Data& data) { - switch (state) { + if (!data.pendingAPIRequestURL.isNull()) + return true; + + switch (data.state) { case State::Provisional: case State::Committed: return true; @@ -328,6 +404,16 @@ bool PageLoadState::isLoadingState(State state) return false; } +void PageLoadState::willChangeProcessIsResponsive() +{ + callObserverCallback(&Observer::willChangeWebProcessIsResponsive); +} + +void PageLoadState::didChangeProcessIsResponsive() +{ + callObserverCallback(&Observer::didChangeWebProcessIsResponsive); +} + void PageLoadState::callObserverCallback(void (Observer::*callback)()) { for (auto* observer : m_observers) diff --git a/Source/WebKit2/UIProcess/PageLoadState.h b/Source/WebKit2/UIProcess/PageLoadState.h index 0501e4500..e2afdfd8d 100644 --- a/Source/WebKit2/UIProcess/PageLoadState.h +++ b/Source/WebKit2/UIProcess/PageLoadState.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,13 +26,17 @@ #ifndef PageLoadState_h #define PageLoadState_h +#include "WebCertificateInfo.h" #include <wtf/text/WTFString.h> namespace WebKit { +class WebCertificateInfo; +class WebPageProxy; + class PageLoadState { public: - PageLoadState(); + explicit PageLoadState(WebPageProxy&); ~PageLoadState(); enum class State { @@ -59,31 +63,33 @@ public: virtual void willChangeEstimatedProgress() = 0; virtual void didChangeEstimatedProgress() = 0; + + virtual void willChangeCanGoBack() = 0; + virtual void didChangeCanGoBack() = 0; + + virtual void willChangeCanGoForward() = 0; + virtual void didChangeCanGoForward() = 0; + + virtual void willChangeNetworkRequestsInProgress() = 0; + virtual void didChangeNetworkRequestsInProgress() = 0; + + virtual void willChangeCertificateInfo() = 0; + virtual void didChangeCertificateInfo() = 0; + + virtual void willChangeWebProcessIsResponsive() = 0; + virtual void didChangeWebProcessIsResponsive() = 0; }; class Transaction { WTF_MAKE_NONCOPYABLE(Transaction); public: - Transaction(Transaction&& other) - : m_pageLoadState(other.m_pageLoadState) - { - other.m_pageLoadState = nullptr; - } - - ~Transaction() - { - if (m_pageLoadState) - m_pageLoadState->endTransaction(); - } + Transaction(Transaction&&); + ~Transaction(); private: friend class PageLoadState; - explicit Transaction(PageLoadState& pageLoadState) - : m_pageLoadState(&pageLoadState) - { - m_pageLoadState->beginTransaction(); - } + explicit Transaction(PageLoadState&); class Token { public: @@ -100,6 +106,7 @@ public: #endif }; + RefPtr<WebPageProxy> m_webPageProxy; PageLoadState* m_pageLoadState; }; @@ -122,6 +129,9 @@ public: bool hasOnlySecureContent() const; double estimatedProgress() const; + bool networkRequestsInProgress() const { return m_committedState.networkRequestsInProgress; } + + WebCertificateInfo* certificateInfo() const { return m_committedState.certificateInfo.get(); } const String& pendingAPIRequestURL() const; void setPendingAPIRequestURL(const Transaction::Token&, const String&); @@ -131,7 +141,7 @@ public: void didReceiveServerRedirectForProvisionalLoad(const Transaction::Token&, const String& url); void didFailProvisionalLoad(const Transaction::Token&); - void didCommitLoad(const Transaction::Token&); + void didCommitLoad(const Transaction::Token&, WebCertificateInfo&, bool hasInsecureContent); void didFinishLoad(const Transaction::Token&); void didFailLoad(const Transaction::Token&); @@ -144,13 +154,25 @@ public: const String& title() const; void setTitle(const Transaction::Token&, const String&); + bool canGoBack() const; + void setCanGoBack(const Transaction::Token&, bool); + + bool canGoForward() const; + void setCanGoForward(const Transaction::Token&, bool); + void didStartProgress(const Transaction::Token&); void didChangeProgress(const Transaction::Token&, double); void didFinishProgress(const Transaction::Token&); + void setNetworkRequestsInProgress(const Transaction::Token&, bool); -private: - static bool isLoadingState(State); + bool committedHasInsecureContent() const { return m_committedState.hasInsecureContent; } + // FIXME: We piggy-back off PageLoadState::Observer so that both WKWebView and WKObservablePageState + // can listen for changes. Once we get rid of WKObservablePageState these could just be part of API::NavigationClient. + void willChangeProcessIsResponsive(); + void didChangeProcessIsResponsive(); + +private: void beginTransaction() { ++m_outstandingTransactionCount; } void endTransaction(); @@ -162,7 +184,10 @@ private: Data() : state(State::Finished) , hasInsecureContent(false) + , canGoBack(false) + , canGoForward(false) , estimatedProgress(0) + , networkRequestsInProgress(false) { } @@ -178,13 +203,22 @@ private: String title; + bool canGoBack; + bool canGoForward; + double estimatedProgress; + bool networkRequestsInProgress; + + RefPtr<WebCertificateInfo> certificateInfo; }; + static bool isLoading(const Data&); static String activeURL(const Data&); static bool hasOnlySecureContent(const Data&); static double estimatedProgress(const Data&); + WebPageProxy& m_webPageProxy; + Data m_committedState; Data m_uncommittedState; diff --git a/Source/WebKit2/UIProcess/PageViewportControllerClient.h b/Source/WebKit2/UIProcess/PageViewportControllerClient.h new file mode 100644 index 000000000..4ad7ce506 --- /dev/null +++ b/Source/WebKit2/UIProcess/PageViewportControllerClient.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef PageViewportControllerClient_h +#define PageViewportControllerClient_h + +#include <wtf/Noncopyable.h> + +namespace WebCore { +class FloatPoint; +class IntSize; +} + +namespace WebKit { + +class PageViewportControllerClient { + WTF_MAKE_NONCOPYABLE(PageViewportControllerClient); +public: + PageViewportControllerClient() { } + virtual ~PageViewportControllerClient() { } + + virtual void setViewportPosition(const WebCore::FloatPoint&) = 0; + virtual void setPageScaleFactor(float) = 0; + + virtual void didChangeContentsSize(const WebCore::IntSize&) = 0; + virtual void didChangeVisibleContents() = 0; + virtual void didChangeViewportAttributes() = 0; +}; + +} // namespace WebKit + +#endif // PageViewportControllerClient_h diff --git a/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp b/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp new file mode 100644 index 000000000..0c039e6bc --- /dev/null +++ b/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PerActivityStateCPUUsageSampler.h" + +#include "Logging.h" +#include "WebProcessPool.h" +#include "WebProcessProxy.h" +#include <WebCore/DiagnosticLoggingKeys.h> +#include <wtf/DecimalNumber.h> + +namespace WebKit { + +static const int64_t microsecondsPerSecond = 1000000; + +using namespace WebCore; + +static const std::chrono::minutes loggingInterval { 60 }; + +PerActivityStateCPUUsageSampler::PerActivityStateCPUUsageSampler(WebProcessPool& processPool) + : m_processPool(processPool) + , m_loggingTimer(RunLoop::main(), this, &PerActivityStateCPUUsageSampler::loggingTimerFired) +{ + m_lastCPUTime = monotonicallyIncreasingTime(); + m_loggingTimer.startRepeating(loggingInterval); +} + +PerActivityStateCPUUsageSampler::~PerActivityStateCPUUsageSampler() +{ +} + +void PerActivityStateCPUUsageSampler::reportWebContentCPUTime(int64_t cpuTime, ActivityStateForCPUSampling activityState) +{ + auto result = m_cpuTimeInActivityState.add(activityState, cpuTime); + if (!result.isNewEntry) + result.iterator->value += cpuTime; +} + +static inline String loggingKeyForActivityState(ActivityStateForCPUSampling state) +{ + switch (state) { + case ActivityStateForCPUSampling::NonVisible: + return DiagnosticLoggingKeys::nonVisibleStateKey(); + case ActivityStateForCPUSampling::VisibleNonActive: + return DiagnosticLoggingKeys::visibleNonActiveStateKey(); + case ActivityStateForCPUSampling::VisibleAndActive: + return DiagnosticLoggingKeys::visibleAndActiveStateKey(); + } +} + +void PerActivityStateCPUUsageSampler::loggingTimerFired() +{ + auto* page = pageForLogging(); + if (!page) { + m_cpuTimeInActivityState.clear(); + return; + } + + double currentCPUTime = monotonicallyIncreasingTime(); + int64_t cpuTimeDelta = (currentCPUTime - m_lastCPUTime) * microsecondsPerSecond; + + for (auto& pair : m_cpuTimeInActivityState) { + double cpuUsage = static_cast<double>(pair.value * 100.) / cpuTimeDelta; + String activityStateKey = loggingKeyForActivityState(pair.key); + page->logDiagnosticMessageWithValue(DiagnosticLoggingKeys::cpuUsageKey(), activityStateKey, cpuUsage, 2, ShouldSample::No); + RELEASE_LOG(PerformanceLogging, "WebContent processes used %.1f%% CPU in %s state", cpuUsage, activityStateKey.utf8().data()); + } + + m_cpuTimeInActivityState.clear(); + m_lastCPUTime = currentCPUTime; +} + +WebPageProxy* PerActivityStateCPUUsageSampler::pageForLogging() const +{ + for (auto& webProcess : m_processPool.processes()) { + if (!webProcess->pageCount()) + continue; + return *webProcess->pages().begin(); + } + return nullptr; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h b/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h new file mode 100644 index 000000000..dab6f4b75 --- /dev/null +++ b/Source/WebKit2/UIProcess/PerActivityStateCPUUsageSampler.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <WebCore/Page.h> +#include <wtf/HashMap.h> +#include <wtf/RunLoop.h> + +namespace WebKit { + +class WebPageProxy; +class WebProcessPool; + +class PerActivityStateCPUUsageSampler { +public: + explicit PerActivityStateCPUUsageSampler(WebProcessPool&); + ~PerActivityStateCPUUsageSampler(); + + void reportWebContentCPUTime(int64_t cpuTime, WebCore::ActivityStateForCPUSampling); + +private: + void loggingTimerFired(); + WebPageProxy* pageForLogging() const; + + WebProcessPool& m_processPool; + RunLoop::Timer<PerActivityStateCPUUsageSampler> m_loggingTimer; + typedef HashMap<WebCore::ActivityStateForCPUSampling, int64_t, WTF::IntHash<WebCore::ActivityStateForCPUSampling>, WTF::StrongEnumHashTraits<WebCore::ActivityStateForCPUSampling>> CPUTimeInActivityStateMap; + CPUTimeInActivityStateMap m_cpuTimeInActivityState; + double m_lastCPUTime; +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp index e5724032d..25075924e 100644 --- a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,10 +27,10 @@ #include "PlugInAutoStartProvider.h" #include "APIArray.h" -#include "ImmutableDictionary.h" -#include "WebContext.h" +#include "APIDictionary.h" #include "WebContextClient.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" #include <wtf/CurrentTime.h> using namespace WebCore; @@ -39,9 +39,11 @@ static const double plugInAutoStartExpirationTimeThreshold = 30 * 24 * 60 * 60; namespace WebKit { -PlugInAutoStartProvider::PlugInAutoStartProvider(WebContext* context) - : m_context(context) +PlugInAutoStartProvider::PlugInAutoStartProvider(WebProcessPool* processPool) + : m_processPool(processPool) { + m_hashToOriginMap.add(SessionID::defaultSessionID(), HashMap<unsigned, String>()); + m_autoStartTable.add(SessionID::defaultSessionID(), AutoStartTable()); } static double expirationTimeFromNow() @@ -49,64 +51,68 @@ static double expirationTimeFromNow() return currentTime() + plugInAutoStartExpirationTimeThreshold; } -void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash) +void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, SessionID sessionID) { - if (m_hashToOriginMap.contains(plugInOriginHash)) + auto sessionIterator = m_hashToOriginMap.find(sessionID); + if (sessionIterator == m_hashToOriginMap.end()) { + if (m_hashToOriginMap.get(SessionID::defaultSessionID()).contains(plugInOriginHash)) + return; + sessionIterator = m_hashToOriginMap.set(sessionID, HashMap<unsigned, String>()).iterator; + } else if (sessionIterator->value.contains(plugInOriginHash) || m_hashToOriginMap.get(SessionID::defaultSessionID()).contains(plugInOriginHash)) return; - AutoStartTable::iterator it = m_autoStartTable.find(pageOrigin); - if (it == m_autoStartTable.end()) - it = m_autoStartTable.add(pageOrigin, PlugInAutoStartOriginHash()).iterator; + AutoStartTable::iterator it = m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(pageOrigin, PlugInAutoStartOriginMap()).iterator; double expirationTime = expirationTimeFromNow(); it->value.set(plugInOriginHash, expirationTime); - m_hashToOriginMap.set(plugInOriginHash, pageOrigin); + sessionIterator->value.set(plugInOriginHash, pageOrigin); - m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime)); - m_context->client().plugInAutoStartOriginHashesChanged(m_context); + m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime, sessionID)); + + if (!sessionID.isEphemeral()) + m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); } -PlugInAutoStartOriginHash PlugInAutoStartProvider::autoStartOriginHashesCopy() const +SessionPlugInAutoStartOriginMap PlugInAutoStartProvider::autoStartOriginHashesCopy() const { - PlugInAutoStartOriginHash copyMap; - AutoStartTable::const_iterator end = m_autoStartTable.end(); - for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) { - PlugInAutoStartOriginHash::const_iterator mapEnd = it->value.end(); - for (PlugInAutoStartOriginHash::const_iterator mapIt = it->value.begin(); mapIt != mapEnd; ++mapIt) - copyMap.set(mapIt->key, mapIt->value); + SessionPlugInAutoStartOriginMap sessionMap; + + for (const auto& sessionKeyOriginHash : m_autoStartTable) { + PlugInAutoStartOriginMap& map = sessionMap.add(sessionKeyOriginHash.key, PlugInAutoStartOriginMap()).iterator->value; + for (const auto& keyOriginHash : sessionKeyOriginHash.value) { + for (const auto& originHash : keyOriginHash.value) + map.set(originHash.key, originHash.value); + } } - return copyMap; + return sessionMap; } -PassRefPtr<ImmutableDictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const +Ref<API::Dictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const { - ImmutableDictionary::MapType map; - AutoStartTable::const_iterator end = m_autoStartTable.end(); + API::Dictionary::MapType map; + double now = currentTime(); - for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) { - ImmutableDictionary::MapType hashMap; - PlugInAutoStartOriginHash::const_iterator valueEnd = it->value.end(); - for (PlugInAutoStartOriginHash::const_iterator valueIt = it->value.begin(); valueIt != valueEnd; ++valueIt) { - if (now > valueIt->value) - continue; - hashMap.set(String::number(valueIt->key), API::Double::create(valueIt->value)); + for (const auto& stringOriginHash : m_autoStartTable.get(SessionID::defaultSessionID())) { + API::Dictionary::MapType hashMap; + for (const auto& originHash : stringOriginHash.value) { + if (now <= originHash.value) + hashMap.set(String::number(originHash.key), API::Double::create(originHash.value)); } - if (hashMap.size()) - map.set(it->key, ImmutableDictionary::create(std::move(hashMap))); + map.set(stringOriginHash.key, API::Dictionary::create(WTFMove(hashMap))); } - return ImmutableDictionary::create(std::move(map)); + return API::Dictionary::create(WTFMove(map)); } -void PlugInAutoStartProvider::setAutoStartOriginsTable(ImmutableDictionary& table) +void PlugInAutoStartProvider::setAutoStartOriginsTable(API::Dictionary& table) { setAutoStartOriginsTableWithItemsPassingTest(table, [](double) { return true; }); } -void PlugInAutoStartProvider::setAutoStartOriginsFilteringOutEntriesAddedAfterTime(ImmutableDictionary& table, double time) +void PlugInAutoStartProvider::setAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& table, double time) { double adjustedTimestamp = time + plugInAutoStartExpirationTimeThreshold; setAutoStartOriginsTableWithItemsPassingTest(table, [adjustedTimestamp](double expirationTimestamp) { @@ -114,66 +120,72 @@ void PlugInAutoStartProvider::setAutoStartOriginsFilteringOutEntriesAddedAfterTi }); } -void PlugInAutoStartProvider::setAutoStartOriginsTableWithItemsPassingTest(ImmutableDictionary& table, std::function<bool(double expirationTimestamp)> isExpirationTimeAcceptable) +void PlugInAutoStartProvider::setAutoStartOriginsTableWithItemsPassingTest(API::Dictionary& table, std::function<bool(double expirationTimestamp)> isExpirationTimeAcceptable) { ASSERT(isExpirationTimeAcceptable); m_hashToOriginMap.clear(); m_autoStartTable.clear(); HashMap<unsigned, double> hashMap; + HashMap<unsigned, String>& hashToOriginMap = m_hashToOriginMap.add(SessionID::defaultSessionID(), HashMap<unsigned, String>()).iterator->value; + AutoStartTable& ast = m_autoStartTable.add(SessionID::defaultSessionID(), AutoStartTable()).iterator->value; - ImmutableDictionary::MapType::const_iterator end = table.map().end(); - for (ImmutableDictionary::MapType::const_iterator it = table.map().begin(); it != end; ++it) { - PlugInAutoStartOriginHash hashes; - ImmutableDictionary* hashesForPage = static_cast<ImmutableDictionary*>(it->value.get()); - ImmutableDictionary::MapType::const_iterator hashEnd = hashesForPage->map().end(); - for (ImmutableDictionary::MapType::const_iterator hashIt = hashesForPage->map().begin(); hashIt != hashEnd; ++hashIt) { + for (auto& strDict : table.map()) { + PlugInAutoStartOriginMap hashes; + for (auto& hashTime : static_cast<API::Dictionary*>(strDict.value.get())->map()) { bool ok; - unsigned hash = hashIt->key.toUInt(&ok); + unsigned hash = hashTime.key.toUInt(&ok); if (!ok) continue; - if (hashIt->value->type() != API::Double::APIType) + if (hashTime.value->type() != API::Double::APIType) continue; - double expirationTime = static_cast<API::Double*>(hashIt->value.get())->value(); + double expirationTime = static_cast<API::Double*>(hashTime.value.get())->value(); if (!isExpirationTimeAcceptable(expirationTime)) continue; hashes.set(hash, expirationTime); hashMap.set(hash, expirationTime); - m_hashToOriginMap.set(hash, it->key); + hashToOriginMap.set(hash, strDict.key); } if (!hashes.isEmpty()) - m_autoStartTable.set(it->key, hashes); + ast.set(strDict.key, hashes); } - m_context->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginHashes(hashMap)); + m_processPool->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginDefaultHashes(hashMap)); } void PlugInAutoStartProvider::setAutoStartOriginsArray(API::Array& originList) { m_autoStartOrigins.clear(); - for (size_t i = 0, length = originList.size(); i < length; ++i) { - if (originList.at(i)->type() != API::String::APIType) - continue; - m_autoStartOrigins.append(static_cast<API::String*>(originList.at(i))->string()); - } + for (const auto& string : originList.elementsOfType<API::String>()) + m_autoStartOrigins.append(string->string()); } -void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash) +void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash, SessionID sessionID) { - HashMap<unsigned, String>::const_iterator it = m_hashToOriginMap.find(plugInOriginHash); - if (it == m_hashToOriginMap.end()) { - ASSERT_NOT_REACHED(); - return; + HashMap<WebCore::SessionID, HashMap<unsigned, String>>::const_iterator sessionIterator = m_hashToOriginMap.find(sessionID); + HashMap<unsigned, String>::const_iterator it; + bool contains = false; + if (sessionIterator != m_hashToOriginMap.end()) { + it = sessionIterator->value.find(plugInOriginHash); + contains = it != sessionIterator->value.end(); + } + if (!contains) { + sessionIterator = m_hashToOriginMap.find(SessionID::defaultSessionID()); + it = sessionIterator->value.find(plugInOriginHash); + if (it == sessionIterator->value.end()) { + ASSERT_NOT_REACHED(); + return; + } } double newExpirationTime = expirationTimeFromNow(); - m_autoStartTable.find(it->value)->value.set(plugInOriginHash, newExpirationTime); - m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime)); - m_context->client().plugInAutoStartOriginHashesChanged(m_context); + m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(it->value, PlugInAutoStartOriginMap()).iterator->value.set(plugInOriginHash, newExpirationTime); + m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime, sessionID)); + m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h index c3b390272..fe6bc6f56 100644 --- a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h +++ b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h @@ -26,6 +26,7 @@ #ifndef PlugInAutoStartProvider_h #define PlugInAutoStartProvider_h +#include <WebCore/SessionID.h> #include <functional> #include <wtf/HashMap.h> #include <wtf/HashSet.h> @@ -36,41 +37,43 @@ namespace API { class Array; +class Dictionary; } namespace WebKit { -class ImmutableDictionary; -class WebContext; +class WebProcessPool; -typedef HashMap<unsigned, double> PlugInAutoStartOriginHash; +typedef HashMap<unsigned, double> PlugInAutoStartOriginMap; +typedef HashMap<WebCore::SessionID, PlugInAutoStartOriginMap> SessionPlugInAutoStartOriginMap; typedef Vector<String> PlugInAutoStartOrigins; class PlugInAutoStartProvider { WTF_MAKE_NONCOPYABLE(PlugInAutoStartProvider); public: - explicit PlugInAutoStartProvider(WebContext*); + explicit PlugInAutoStartProvider(WebProcessPool*); - void addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash); - void didReceiveUserInteraction(unsigned plugInOriginHash); + void addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID); + void didReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID); - PassRefPtr<ImmutableDictionary> autoStartOriginsTableCopy() const; - void setAutoStartOriginsTable(ImmutableDictionary&); - void setAutoStartOriginsFilteringOutEntriesAddedAfterTime(ImmutableDictionary&, double time); + Ref<API::Dictionary> autoStartOriginsTableCopy() const; + void setAutoStartOriginsTable(API::Dictionary&); + void setAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, double time); void setAutoStartOriginsArray(API::Array&); - PlugInAutoStartOriginHash autoStartOriginHashesCopy() const; + SessionPlugInAutoStartOriginMap autoStartOriginHashesCopy() const; const PlugInAutoStartOrigins& autoStartOrigins() const { return m_autoStartOrigins; } private: - WebContext* m_context; + WebProcessPool* m_processPool; - void setAutoStartOriginsTableWithItemsPassingTest(ImmutableDictionary&, std::function<bool(double expirationTimestamp)>); + void setAutoStartOriginsTableWithItemsPassingTest(API::Dictionary&, std::function<bool(double expirationTimestamp)>); - typedef HashMap<String, PlugInAutoStartOriginHash, CaseFoldingHash> AutoStartTable; - AutoStartTable m_autoStartTable; + typedef HashMap<String, PlugInAutoStartOriginMap, ASCIICaseInsensitiveHash> AutoStartTable; + typedef HashMap<WebCore::SessionID, AutoStartTable> SessionAutoStartTable; + SessionAutoStartTable m_autoStartTable; - HashMap<unsigned, String> m_hashToOriginMap; + HashMap<WebCore::SessionID, HashMap<unsigned, String>> m_hashToOriginMap; PlugInAutoStartOrigins m_autoStartOrigins; }; diff --git a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp index 0dde1a093..6079068bb 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp @@ -41,7 +41,6 @@ namespace WebKit { PluginInfoStore::PluginInfoStore() : m_pluginListIsUpToDate(false) - , m_client(0) { } @@ -68,7 +67,7 @@ void PluginInfoStore::loadPluginsIfNecessary() if (m_pluginListIsUpToDate) return; - ListHashSet<String, 32> uniquePluginPaths; + ListHashSet<String> uniquePluginPaths; // First, load plug-ins from the additional plug-ins directories specified. for (size_t i = 0; i < m_additionalPluginsDirectories.size(); ++i) @@ -88,9 +87,6 @@ void PluginInfoStore::loadPluginsIfNecessary() loadPlugin(m_plugins, pluginPath); m_pluginListIsUpToDate = true; - - if (m_client) - m_client->pluginInfoStoreDidLoadPlugins(this); } void PluginInfoStore::loadPlugin(Vector<PluginModuleInfo>& plugins, const String& pluginPath) @@ -115,15 +111,12 @@ Vector<PluginModuleInfo> PluginInfoStore::plugins() PluginModuleInfo PluginInfoStore::findPluginForMIMEType(const String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const { ASSERT(!mimeType.isNull()); - - for (size_t i = 0; i < m_plugins.size(); ++i) { - const PluginModuleInfo& plugin = m_plugins[i]; + for (const auto& plugin : m_plugins) { if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin) continue; - - for (size_t j = 0; j < plugin.info.mimes.size(); ++j) { - const MimeClassInfo& mimeClassInfo = plugin.info.mimes[j]; + + for (const auto& mimeClassInfo : plugin.info.mimes) { if (mimeClassInfo.type == mimeType) return plugin; } @@ -135,19 +128,13 @@ PluginModuleInfo PluginInfoStore::findPluginForMIMEType(const String& mimeType, PluginModuleInfo PluginInfoStore::findPluginForExtension(const String& extension, String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const { ASSERT(!extension.isNull()); - - for (size_t i = 0; i < m_plugins.size(); ++i) { - const PluginModuleInfo& plugin = m_plugins[i]; + for (const auto& plugin : m_plugins) { if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin) continue; - for (size_t j = 0; j < plugin.info.mimes.size(); ++j) { - const MimeClassInfo& mimeClassInfo = plugin.info.mimes[j]; - - const Vector<String>& extensions = mimeClassInfo.extensions; - - if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) { + for (const auto& mimeClassInfo : plugin.info.mimes) { + if (mimeClassInfo.extensions.contains(extension)) { // We found a supported extension, set the correct MIME type. mimeType = mimeClassInfo.type; return plugin; @@ -163,15 +150,15 @@ static inline String pathExtension(const URL& url) String extension; String filename = url.lastPathComponent(); if (!filename.endsWith('/')) { - int extensionPos = filename.reverseFind('.'); - if (extensionPos != -1) + size_t extensionPos = filename.reverseFind('.'); + if (extensionPos != notFound) extension = filename.substring(extensionPos + 1); } - - return extension; + return extension.convertToASCIILowercase(); } -#if !PLATFORM(MAC) +#if !PLATFORM(COCOA) + PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo&) { return PluginModuleLoadNormally; @@ -197,7 +184,7 @@ PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const URL& url, P } // Next, check if any plug-ins claim to support the URL extension. - String extension = pathExtension(url).lower(); + String extension = pathExtension(url); if (!extension.isNull() && mimeType.isEmpty()) { PluginModuleInfo plugin = findPluginForExtension(extension, mimeType, allowedPluginTypes); if (!plugin.path.isNull()) @@ -219,11 +206,11 @@ PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const URL& url, P PluginModuleInfo PluginInfoStore::infoForPluginWithPath(const String& pluginPath) const { - for (size_t i = 0; i < m_plugins.size(); ++i) { - if (m_plugins[i].path == pluginPath) - return m_plugins[i]; + for (const auto& plugin : m_plugins) { + if (plugin.path == pluginPath) + return plugin; } - + ASSERT_NOT_REACHED(); return PluginModuleInfo(); } diff --git a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h index 7b4f509c7..2791c98f6 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2012, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,15 +40,6 @@ namespace WebKit { class PluginInfoStore; -class PluginInfoStoreClient { - WTF_MAKE_NONCOPYABLE(PluginInfoStoreClient); -public: - virtual ~PluginInfoStoreClient() { } - virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) = 0; -protected: - PluginInfoStoreClient() { } -}; - class PluginInfoStore { WTF_MAKE_NONCOPYABLE(PluginInfoStore); @@ -73,9 +64,6 @@ public: static PluginModuleLoadPolicy defaultLoadPolicyForPlugin(const PluginModuleInfo&); - void setClient(PluginInfoStoreClient* client) { m_client = client; } - PluginInfoStoreClient* client() const { return m_client; } - private: PluginModuleInfo findPluginForMIMEType(const String& mimeType, WebCore::PluginData::AllowedPluginTypes) const; PluginModuleInfo findPluginForExtension(const String& extension, String& mimeType, WebCore::PluginData::AllowedPluginTypes) const; @@ -103,7 +91,6 @@ private: Vector<String> m_additionalPluginsDirectories; Vector<PluginModuleInfo> m_plugins; bool m_pluginListIsUpToDate; - PluginInfoStoreClient* m_client; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp index 156fb6de4..6d0be9fdf 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp @@ -29,20 +29,22 @@ #if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginProcessProxy.h" -#include "WebContext.h" #include <wtf/CryptographicallyRandomNumber.h> #include <wtf/StdLibExtras.h> #include <wtf/text/WTFString.h> namespace WebKit { -PluginProcessManager& PluginProcessManager::shared() +PluginProcessManager& PluginProcessManager::singleton() { static NeverDestroyed<PluginProcessManager> pluginProcessManager; return pluginProcessManager; } PluginProcessManager::PluginProcessManager() +#if PLATFORM(COCOA) + : m_processSuppressionDisabledForPageCounter([this](RefCounterEvent event) { updateProcessSuppressionDisabled(event); }) +#endif { } @@ -71,18 +73,18 @@ uint64_t PluginProcessManager::pluginProcessToken(const PluginModuleInfo& plugin attributes.processType = pluginProcessType; attributes.sandboxPolicy = pluginProcessSandboxPolicy; - m_pluginProcessTokens.append(std::make_pair(std::move(attributes), token)); + m_pluginProcessTokens.append(std::make_pair(WTFMove(attributes), token)); m_knownTokens.add(token); return token; } -void PluginProcessManager::getPluginProcessConnection(uint64_t pluginProcessToken, PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply) +void PluginProcessManager::getPluginProcessConnection(uint64_t pluginProcessToken, Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&& reply) { ASSERT(pluginProcessToken); PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken); - pluginProcess->getPluginProcessConnection(reply); + pluginProcess->getPluginProcessConnection(WTFMove(reply)); } void PluginProcessManager::removePluginProcessProxy(PluginProcessProxy* pluginProcessProxy) @@ -93,16 +95,24 @@ void PluginProcessManager::removePluginProcessProxy(PluginProcessProxy* pluginPr m_pluginProcesses.remove(vectorIndex); } -void PluginProcessManager::getSitesWithData(const PluginModuleInfo& plugin, WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) +void PluginProcessManager::fetchWebsiteData(const PluginModuleInfo& plugin, std::function<void (Vector<String>)> completionHandler) { PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); - pluginProcess->getSitesWithData(webPluginSiteDataManager, callbackID); + + pluginProcess->fetchWebsiteData(WTFMove(completionHandler)); +} + +void PluginProcessManager::deleteWebsiteData(const PluginModuleInfo& plugin, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) +{ + PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); + + pluginProcess->deleteWebsiteData(modifiedSince, WTFMove(completionHandler)); } -void PluginProcessManager::clearSiteData(const PluginModuleInfo& plugin, WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +void PluginProcessManager::deleteWebsiteDataForHostNames(const PluginModuleInfo& plugin, const Vector<String>& hostNames, std::function<void ()> completionHandler) { PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); - pluginProcess->clearSiteData(webPluginSiteDataManager, sites, flags, maxAgeInSeconds, callbackID); + pluginProcess->deleteWebsiteDataForHostNames(hostNames, WTFMove(completionHandler)); } PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t pluginProcessToken) @@ -115,10 +125,10 @@ PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t plug for (size_t i = 0; i < m_pluginProcessTokens.size(); ++i) { auto& attributesAndToken = m_pluginProcessTokens[i]; if (attributesAndToken.second == pluginProcessToken) { - RefPtr<PluginProcessProxy> pluginProcess = PluginProcessProxy::create(this, attributesAndToken.first, attributesAndToken.second); - PluginProcessProxy* pluginProcessPtr = pluginProcess.get(); + auto pluginProcess = PluginProcessProxy::create(this, attributesAndToken.first, attributesAndToken.second); + PluginProcessProxy* pluginProcessPtr = pluginProcess.ptr(); - m_pluginProcesses.append(pluginProcess.release()); + m_pluginProcesses.append(WTFMove(pluginProcess)); return pluginProcessPtr; } } diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h index 0c59a764a..dd44d622c 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h @@ -31,15 +31,17 @@ #include "PluginModuleInfo.h" #include "PluginProcess.h" #include "PluginProcessAttributes.h" +#include "ProcessThrottler.h" #include "WebProcessProxyMessages.h" #include <wtf/Forward.h> #include <wtf/HashSet.h> #include <wtf/NeverDestroyed.h> #include <wtf/Noncopyable.h> +#include <wtf/RefCounter.h> #include <wtf/Vector.h> namespace IPC { - class ArgumentEncoder; +class Encoder; } namespace WebKit { @@ -47,24 +49,26 @@ namespace WebKit { class PluginInfoStore; class PluginProcessProxy; class WebProcessProxy; -class WebPluginSiteDataManager; class PluginProcessManager { WTF_MAKE_NONCOPYABLE(PluginProcessManager); friend class NeverDestroyed<PluginProcessManager>; public: - static PluginProcessManager& shared(); + static PluginProcessManager& singleton(); uint64_t pluginProcessToken(const PluginModuleInfo&, PluginProcessType, PluginProcessSandboxPolicy); - void getPluginProcessConnection(uint64_t pluginProcessToken, PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>); + void getPluginProcessConnection(uint64_t pluginProcessToken, Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&&); void removePluginProcessProxy(PluginProcessProxy*); - void getSitesWithData(const PluginModuleInfo&, WebPluginSiteDataManager*, uint64_t callbackID); - void clearSiteData(const PluginModuleInfo&, WebPluginSiteDataManager*, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); + void fetchWebsiteData(const PluginModuleInfo&, std::function<void (Vector<String>)> completionHandler); + void deleteWebsiteData(const PluginModuleInfo&, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler); + void deleteWebsiteDataForHostNames(const PluginModuleInfo&, const Vector<String>& hostNames, std::function<void ()> completionHandler); -#if PLATFORM(MAC) - void setProcessSuppressionEnabled(bool); +#if PLATFORM(COCOA) + inline ProcessSuppressionDisabledToken processSuppressionDisabledToken(); + inline bool processSuppressionDisabled() const; + void updateProcessSuppressionDisabled(RefCounterEvent); #endif private: @@ -76,8 +80,24 @@ private: HashSet<uint64_t> m_knownTokens; Vector<RefPtr<PluginProcessProxy>> m_pluginProcesses; + +#if PLATFORM(COCOA) + ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter; +#endif }; +#if PLATFORM(COCOA) +inline ProcessSuppressionDisabledToken PluginProcessManager::processSuppressionDisabledToken() +{ + return m_processSuppressionDisabledForPageCounter.count(); +} + +inline bool PluginProcessManager::processSuppressionDisabled() const +{ + return m_processSuppressionDisabledForPageCounter.value(); +} +#endif + } // namespace WebKit #endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp index 27772f561..5ff51b509 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp @@ -32,15 +32,14 @@ #include "PluginProcessCreationParameters.h" #include "PluginProcessManager.h" #include "PluginProcessMessages.h" -#include "WebContext.h" #include "WebCoreArgumentCoders.h" -#include "WebPluginSiteDataManager.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" #include <WebCore/NotImplemented.h> #include <wtf/RunLoop.h> -#if PLATFORM(MAC) -#include "MachPort.h" +#if OS(LINUX) +#include "MemoryPressureMonitor.h" #endif using namespace WebCore; @@ -53,9 +52,16 @@ static const double snapshottingMinimumLifetime = 30; static const double shutdownTimeout = 1 * 60; static const double snapshottingShutdownTimeout = 15; -PassRefPtr<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) +static uint64_t generateCallbackID() { - return adoptRef(new PluginProcessProxy(PluginProcessManager, pluginProcessAttributes, pluginProcessToken)); + static uint64_t callbackID; + + return ++callbackID; +} + +Ref<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) +{ + return adoptRef(*new PluginProcessProxy(PluginProcessManager, pluginProcessAttributes, pluginProcessToken)); } PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) @@ -63,7 +69,7 @@ PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManage , m_pluginProcessAttributes(pluginProcessAttributes) , m_pluginProcessToken(pluginProcessToken) , m_numPendingConnectionRequests(0) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_modalWindowIsShowing(false) , m_fullscreenWindowIsShowing(false) , m_preFullscreenAppPresentationOptions(0) @@ -74,61 +80,76 @@ PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManage PluginProcessProxy::~PluginProcessProxy() { + ASSERT(m_pendingFetchWebsiteDataRequests.isEmpty()); + ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataRequests.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty()); } void PluginProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) { - launchOptions.processType = ProcessLauncher::PluginProcess; + ChildProcessProxy::getLaunchOptions(launchOptions); platformGetLaunchOptions(launchOptions, m_pluginProcessAttributes); } +void PluginProcessProxy::processWillShutDown(IPC::Connection& connection) +{ + ASSERT_UNUSED(connection, this->connection() == &connection); +} + // Asks the plug-in process to create a new connection to a web process. The connection identifier will be // encoded in the given argument encoder and sent back to the connection of the given web process. -void PluginProcessProxy::getPluginProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply) +void PluginProcessProxy::getPluginProcessConnection(Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&& reply) { - m_pendingConnectionReplies.append(reply); + m_pendingConnectionReplies.append(WTFMove(reply)); - if (isLaunching()) { + if (state() == State::Launching) { m_numPendingConnectionRequests++; return; } // Ask the plug-in process to create a connection. Since the plug-in can be waiting for a synchronous reply // we need to make sure that this message is always processed, even when the plug-in is waiting for a synchronus reply. - m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, IPC::DispatchMessageEvenWhenWaitingForSyncReply); + m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); } -void PluginProcessProxy::getSitesWithData(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) +void PluginProcessProxy::fetchWebsiteData(std::function<void (Vector<String>)> completionHandler) { - ASSERT(!m_pendingGetSitesReplies.contains(callbackID)); - m_pendingGetSitesReplies.set(callbackID, webPluginSiteDataManager); + uint64_t callbackID = generateCallbackID(); + m_pendingFetchWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler)); - if (isLaunching()) { - m_pendingGetSitesRequests.append(callbackID); + if (state() == State::Launching) { + m_pendingFetchWebsiteDataRequests.append(callbackID); return; } - // Ask the plug-in process for the sites with data. m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0); } -void PluginProcessProxy::clearSiteData(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +void PluginProcessProxy::deleteWebsiteData(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) +{ + uint64_t callbackID = generateCallbackID(); + m_pendingDeleteWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler)); + + if (state() == State::Launching) { + m_pendingDeleteWebsiteDataRequests.append({ modifiedSince, callbackID }); + return; + } + + m_connection->send(Messages::PluginProcess::DeleteWebsiteData(modifiedSince, callbackID), 0); +} + +void PluginProcessProxy::deleteWebsiteDataForHostNames(const Vector<String>& hostNames, std::function<void ()> completionHandler) { - ASSERT(!m_pendingClearSiteDataReplies.contains(callbackID)); - m_pendingClearSiteDataReplies.set(callbackID, webPluginSiteDataManager); - - if (isLaunching()) { - ClearSiteDataRequest request; - request.sites = sites; - request.flags = flags; - request.maxAgeInSeconds = maxAgeInSeconds; - request.callbackID = callbackID; - m_pendingClearSiteDataRequests.append(request); + uint64_t callbackID = generateCallbackID(); + m_pendingDeleteWebsiteDataForHostNamesCallbacks.set(callbackID, WTFMove(completionHandler)); + + if (state() == State::Launching) { + m_pendingDeleteWebsiteDataForHostNamesRequests.append({ hostNames, callbackID }); return; } - // Ask the plug-in process to clear the site data. - m_connection->send(Messages::PluginProcess::ClearSiteData(sites, flags, maxAgeInSeconds, callbackID), 0); + m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(hostNames, callbackID), 0); } void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch() @@ -137,28 +158,37 @@ void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch() while (!m_pendingConnectionReplies.isEmpty()) { RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND), false); -#elif USE(UNIX_DOMAIN_SOCKETS) +#if USE(UNIX_DOMAIN_SOCKETS) reply->send(IPC::Attachment(), false); +#elif OS(DARWIN) + reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND), false); #else notImplemented(); #endif } - while (!m_pendingGetSitesReplies.isEmpty()) - didGetSitesWithData(Vector<String>(), m_pendingGetSitesReplies.begin()->key); + m_pendingFetchWebsiteDataRequests.clear(); + for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values()) + callback({ }); + m_pendingFetchWebsiteDataCallbacks.clear(); + + m_pendingDeleteWebsiteDataRequests.clear(); + for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataRequests.clear(); - while (!m_pendingClearSiteDataReplies.isEmpty()) - didClearSiteData(m_pendingClearSiteDataReplies.begin()->key); + m_pendingDeleteWebsiteDataForHostNamesRequests.clear(); + for (const auto& callback : m_pendingDeleteWebsiteDataForHostNamesCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataForHostNamesCallbacks.clear(); // Tell the plug-in process manager to forget about this plug-in process proxy. This may cause us to be deleted. m_pluginProcessManager->removePluginProcessProxy(this); } -void PluginProcessProxy::didClose(IPC::Connection*) +void PluginProcessProxy::didClose(IPC::Connection&) { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (m_modalWindowIsShowing) endModal(); @@ -166,15 +196,15 @@ void PluginProcessProxy::didClose(IPC::Connection*) exitFullscreen(); #endif - const Vector<WebContext*>& contexts = WebContext::allContexts(); - for (size_t i = 0; i < contexts.size(); ++i) - contexts[i]->sendToAllProcesses(Messages::PluginProcessConnectionManager::PluginProcessCrashed(m_pluginProcessToken)); + const Vector<WebProcessPool*>& processPools = WebProcessPool::allProcessPools(); + for (size_t i = 0; i < processPools.size(); ++i) + processPools[i]->sendToAllProcesses(Messages::PluginProcessConnectionManager::PluginProcessCrashed(m_pluginProcessToken)); // This will cause us to be deleted. pluginProcessCrashedOrFailedToLaunch(); } -void PluginProcessProxy::didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference, IPC::StringReference) +void PluginProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } @@ -187,8 +217,8 @@ void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, IPC::Connection::I return; } - m_connection = IPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main()); -#if PLATFORM(MAC) + m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this); +#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 m_connection->setShouldCloseConnectionOnMachExceptions(); #endif @@ -203,33 +233,40 @@ void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, IPC::Connection::I parameters.minimumLifetime = minimumLifetime; parameters.terminationTimeout = shutdownTimeout; } + +#if OS(LINUX) + if (MemoryPressureMonitor::isEnabled()) + parameters.memoryPressureMonitorHandle = MemoryPressureMonitor::singleton().createHandle(); +#endif + platformInitializePluginProcess(parameters); // Initialize the plug-in host process. m_connection->send(Messages::PluginProcess::InitializePluginProcess(parameters), 0); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) m_connection->send(Messages::PluginProcess::SetQOS(pluginProcessLatencyQOS(), pluginProcessThroughputQOS()), 0); #endif - // Send all our pending requests. - for (size_t i = 0; i < m_pendingGetSitesRequests.size(); ++i) - m_connection->send(Messages::PluginProcess::GetSitesWithData(m_pendingGetSitesRequests[i]), 0); - m_pendingGetSitesRequests.clear(); + for (auto callbackID : m_pendingFetchWebsiteDataRequests) + m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0); + m_pendingFetchWebsiteDataRequests.clear(); - for (size_t i = 0; i < m_pendingClearSiteDataRequests.size(); ++i) { - const ClearSiteDataRequest& request = m_pendingClearSiteDataRequests[i]; - m_connection->send(Messages::PluginProcess::ClearSiteData(request.sites, request.flags, request.maxAgeInSeconds, request.callbackID), 0); - } - m_pendingClearSiteDataRequests.clear(); + for (auto& request : m_pendingDeleteWebsiteDataRequests) + m_connection->send(Messages::PluginProcess::DeleteWebsiteData(request.modifiedSince, request.callbackID), 0); + m_pendingDeleteWebsiteDataRequests.clear(); + + for (auto& request : m_pendingDeleteWebsiteDataForHostNamesRequests) + m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(request.hostNames, request.callbackID), 0); + m_pendingDeleteWebsiteDataForHostNamesRequests.clear(); for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i) m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0); m_numPendingConnectionRequests = 0; -#if PLATFORM(MAC) - if (WebContext::processSuppressionIsEnabledForAllContexts()) +#if PLATFORM(COCOA) + if (!PluginProcessManager::singleton().processSuppressionDisabled()) setProcessSuppressionEnabled(true); #endif } @@ -241,10 +278,10 @@ void PluginProcessProxy::didCreateWebProcessConnection(const IPC::Attachment& co // Grab the first pending connection reply. RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND), supportsAsynchronousPluginInitialization); -#elif USE(UNIX_DOMAIN_SOCKETS) +#if USE(UNIX_DOMAIN_SOCKETS) reply->send(connectionIdentifier, supportsAsynchronousPluginInitialization); +#elif OS(DARWIN) + reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND), supportsAsynchronousPluginInitialization); #else notImplemented(); #endif @@ -252,18 +289,20 @@ void PluginProcessProxy::didCreateWebProcessConnection(const IPC::Attachment& co void PluginProcessProxy::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID) { - RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingGetSitesReplies.take(callbackID); - ASSERT(webPluginSiteDataManager); + auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID); + callback(sites); +} - webPluginSiteDataManager->didGetSitesWithDataForSinglePlugin(sites, callbackID); +void PluginProcessProxy::didDeleteWebsiteData(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID); + callback(); } -void PluginProcessProxy::didClearSiteData(uint64_t callbackID) +void PluginProcessProxy::didDeleteWebsiteDataForHostNames(uint64_t callbackID) { - RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingClearSiteDataReplies.take(callbackID); - ASSERT(webPluginSiteDataManager); - - webPluginSiteDataManager->didClearSiteDataForSinglePlugin(callbackID); + auto callback = m_pendingDeleteWebsiteDataForHostNamesCallbacks.take(callbackID); + callback(); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h index 484a20c29..ef43eabb0 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h @@ -37,21 +37,15 @@ #include "WebProcessProxyMessages.h" #include <wtf/Deque.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include <wtf/RetainPtr.h> OBJC_CLASS NSObject; OBJC_CLASS WKPlaceholderModalWindow; #endif -// FIXME: This is platform specific. -namespace IPC { - class MachPort; -} - namespace WebKit { class PluginProcessManager; -class WebPluginSiteDataManager; class WebProcessProxy; struct PluginProcessCreationParameters; @@ -60,17 +54,21 @@ struct RawPluginMetaData { String name; String description; String mimeDescription; + +#if PLATFORM(GTK) + bool requiresGtk2; +#endif }; #endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) int pluginProcessLatencyQOS(); int pluginProcessThroughputQOS(); #endif class PluginProcessProxy : public ChildProcessProxy { public: - static PassRefPtr<PluginProcessProxy> create(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); + static Ref<PluginProcessProxy> create(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); ~PluginProcessProxy(); const PluginProcessAttributes& pluginProcessAttributes() const { return m_pluginProcessAttributes; } @@ -78,26 +76,24 @@ public: // Asks the plug-in process to create a new connection to a web process. The connection identifier will be // encoded in the given argument encoder and sent back to the connection of the given web process. - void getPluginProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>); - - // Asks the plug-in process to get a list of domains for which the plug-in has data stored. - void getSitesWithData(WebPluginSiteDataManager*, uint64_t callbackID); + void getPluginProcessConnection(Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&&); - // Asks the plug-in process to clear the data for the given sites. - void clearSiteData(WebPluginSiteDataManager*, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); + void fetchWebsiteData(std::function<void (Vector<String>)> completionHandler); + void deleteWebsiteData(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler); + void deleteWebsiteDataForHostNames(const Vector<String>& hostNames, std::function<void ()> completionHandler); bool isValid() const { return m_connection; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void setProcessSuppressionEnabled(bool); - // Returns whether the plug-in needs the heap to be marked executable. - static bool pluginNeedsExecutableHeap(const PluginModuleInfo&); - +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 // Creates a property list in ~/Library/Preferences that contains all the MIME types supported by the plug-in. static bool createPropertyListFile(const PluginModuleInfo&); #endif +#endif + #if PLUGIN_ARCHITECTURE(X11) static bool scanPlugin(const String& pluginPath, RawPluginMetaData& result); #endif @@ -105,27 +101,29 @@ public: private: PluginProcessProxy(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); - virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; + void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&, const PluginProcessAttributes&); + void processWillShutDown(IPC::Connection&) override; void pluginProcessCrashedOrFailedToLaunch(); // IPC::Connection::Client - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; - virtual void didClose(IPC::Connection*) override; - virtual void didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + void didClose(IPC::Connection&) override; + void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; // ProcessLauncher::Client - virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier); + void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; // Message handlers void didCreateWebProcessConnection(const IPC::Attachment&, bool supportsAsynchronousPluginInitialization); void didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteData(uint64_t callbackID); + void didDeleteWebsiteData(uint64_t callbackID); + void didDeleteWebsiteDataForHostNames(uint64_t callbackID); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) bool getPluginProcessSerialNumber(ProcessSerialNumber&); void makePluginProcessTheFrontProcess(); void makeUIProcessTheFrontProcess(); @@ -139,7 +137,6 @@ private: void endModal(); void applicationDidBecomeActive(); - void openPluginPreferencePane(); void launchProcess(const String& launchPath, const Vector<String>& arguments, bool& result); void launchApplicationAtURL(const String& urlString, const Vector<String>& arguments, bool& result); void openURL(const String& url, bool& result, int32_t& status, String& launchedURLString); @@ -159,23 +156,28 @@ private: Deque<RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>> m_pendingConnectionReplies; - Vector<uint64_t> m_pendingGetSitesRequests; - HashMap<uint64_t, RefPtr<WebPluginSiteDataManager>> m_pendingGetSitesReplies; + Vector<uint64_t> m_pendingFetchWebsiteDataRequests; + HashMap<uint64_t, std::function<void (Vector<String>)>> m_pendingFetchWebsiteDataCallbacks; + + struct DeleteWebsiteDataRequest { + std::chrono::system_clock::time_point modifiedSince; + uint64_t callbackID; + }; + Vector<DeleteWebsiteDataRequest> m_pendingDeleteWebsiteDataRequests; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataCallbacks; - struct ClearSiteDataRequest { - Vector<String> sites; - uint64_t flags; - uint64_t maxAgeInSeconds; + struct DeleteWebsiteDataForHostNamesRequest { + Vector<String> hostNames; uint64_t callbackID; }; - Vector<ClearSiteDataRequest> m_pendingClearSiteDataRequests; - HashMap<uint64_t, RefPtr<WebPluginSiteDataManager>> m_pendingClearSiteDataReplies; + Vector<DeleteWebsiteDataForHostNamesRequest> m_pendingDeleteWebsiteDataForHostNamesRequests; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataForHostNamesCallbacks; // If createPluginConnection is called while the process is still launching we'll keep count of it and send a bunch of requests // when the process finishes launching. unsigned m_numPendingConnectionRequests; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) RetainPtr<NSObject> m_activationObserver; RetainPtr<WKPlaceholderModalWindow *> m_placeholderWindow; bool m_modalWindowIsShowing; diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in index 25afc5d67..e18e55eb0 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in @@ -26,15 +26,13 @@ messages -> PluginProcessProxy { DidCreateWebProcessConnection(IPC::Attachment connectionIdentifier, bool supportsAsynchronousPluginInitialization) DidGetSitesWithData(Vector<String> sites, uint64_t callbackID) - DidClearSiteData(uint64_t callbackID) + DidDeleteWebsiteData(uint64_t callbackID) + DidDeleteWebsiteDataForHostNames(uint64_t callbackID) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) SetModalWindowIsShowing(bool modalWindowIsShowing) SetFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) - # Open the plug-ins preference pane (as specified in the plug-in's Info.plist file). - OpenPluginPreferencePane() - # Returns true if the UI process launched the process. LaunchProcess(String launchPath, Vector<String> arguments) -> (bool result) diff --git a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp b/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp deleted file mode 100644 index acfa80241..000000000 --- a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebPluginSiteDataManager.h" - -#if ENABLE(NETSCAPE_PLUGIN_API) - -#include "APIArray.h" -#include "PluginProcessManager.h" -#include "WebContext.h" -#include "WebProcessMessages.h" - -using namespace WebCore; - -namespace WebKit { - -class WebPluginSiteDataManager::GetSitesWithDataState { -public: - explicit GetSitesWithDataState(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) - : m_webPluginSiteDataManager(webPluginSiteDataManager) - , m_callbackID(callbackID) - , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) - { - } - - void getSitesWithDataForNextPlugin() - { - if (m_plugins.isEmpty()) { - Vector<String> sites; - copyToVector(m_sites, sites); - - m_webPluginSiteDataManager->didGetSitesWithDataForAllPlugins(sites, m_callbackID); - return; - } - - PluginProcessManager::shared().getSitesWithData(m_plugins.last(), m_webPluginSiteDataManager, m_callbackID); - m_plugins.removeLast(); - } - - void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites) - { - for (size_t i = 0; i < sites.size(); ++i) - m_sites.add(sites[i]); - - getSitesWithDataForNextPlugin(); - } - -private: - WebPluginSiteDataManager* m_webPluginSiteDataManager; - uint64_t m_callbackID; - Vector<PluginModuleInfo> m_plugins; - HashSet<String> m_sites; -}; - -class WebPluginSiteDataManager::ClearSiteDataState { -public: - explicit ClearSiteDataState(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) - : m_webPluginSiteDataManager(webPluginSiteDataManager) - , m_sites(sites) - , m_flags(flags) - , m_maxAgeInSeconds(maxAgeInSeconds) - , m_callbackID(callbackID) - , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) - { - } - - void clearSiteDataForNextPlugin() - { - if (m_plugins.isEmpty()) { - m_webPluginSiteDataManager->didClearSiteDataForAllPlugins(m_callbackID); - return; - } - - PluginProcessManager::shared().clearSiteData(m_plugins.last(), m_webPluginSiteDataManager, m_sites, m_flags, m_maxAgeInSeconds, m_callbackID); - m_plugins.removeLast(); - } - - void didClearSiteDataForSinglePlugin() - { - clearSiteDataForNextPlugin(); - } - -private: - WebPluginSiteDataManager* m_webPluginSiteDataManager; - Vector<String> m_sites; - uint64_t m_flags; - uint64_t m_maxAgeInSeconds; - uint64_t m_callbackID; - Vector<PluginModuleInfo> m_plugins; -}; - -PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext) -{ - return adoptRef(new WebPluginSiteDataManager(webContext)); -} - -WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext) - : m_webContext(webContext) -{ -} - -WebPluginSiteDataManager::~WebPluginSiteDataManager() -{ - ASSERT(m_arrayCallbacks.isEmpty()); - ASSERT(m_voidCallbacks.isEmpty()); - ASSERT(m_pendingGetSitesWithData.isEmpty()); - ASSERT(m_pendingClearSiteData.isEmpty()); -} - -void WebPluginSiteDataManager::invalidate() -{ - invalidateCallbackMap(m_arrayCallbacks); - - m_pendingGetSitesWithData.clear(); - m_pendingClearSiteData.clear(); -} - -void WebPluginSiteDataManager::getSitesWithData(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - - if (!m_webContext) { - callback->invalidate(); - return; - } - - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - ASSERT(!m_pendingGetSitesWithData.contains(callbackID)); - - GetSitesWithDataState* state = new GetSitesWithDataState(this, callbackID); - m_pendingGetSitesWithData.set(callbackID, adoptPtr(state)); - state->getSitesWithDataForNextPlugin(); -} - -void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - callback->performCallbackWithReturnValue(API::Array::createStringArray(sites).get()); -} - -void WebPluginSiteDataManager::clearSiteData(API::Array* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback> prpCallback) -{ - RefPtr<VoidCallback> callback = prpCallback; - if (!m_webContext) { - callback->invalidate(); - return; - } - - Vector<String> sitesVector; - - // If the array is empty, don't do anything. - if (sites) { - if (!sites->size()) { - callback->performCallback(); - return; - } - - for (size_t i = 0; i < sites->size(); ++i) { - if (API::String* site = sites->at<API::String>(i)) - sitesVector.append(site->string()); - } - } - - uint64_t callbackID = callback->callbackID(); - m_voidCallbacks.set(callbackID, callback.release()); - - ASSERT(!m_pendingClearSiteData.contains(callbackID)); - - ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID); - m_pendingClearSiteData.set(callbackID, adoptPtr(state)); - state->clearSiteDataForNextPlugin(); -} - -void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID) -{ - RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - callback->performCallback(); -} - -void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID) -{ - GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID); - ASSERT(state); - - state->didGetSitesWithDataForSinglePlugin(sites); -} - -void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID) -{ - OwnPtr<GetSitesWithDataState> state = m_pendingGetSitesWithData.take(callbackID); - ASSERT(state); - - didGetSitesWithData(sites, callbackID); -} - -void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID) -{ - ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID); - ASSERT(state); - - state->didClearSiteDataForSinglePlugin(); -} - -void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID) -{ - OwnPtr<ClearSiteDataState> state = m_pendingClearSiteData.take(callbackID); - ASSERT(state); - - didClearSiteData(callbackID); -} - -} // namespace WebKit - -#endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h b/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h deleted file mode 100644 index f6918f959..000000000 --- a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebPluginSiteDataManager_h -#define WebPluginSiteDataManager_h - -#if ENABLE(NETSCAPE_PLUGIN_API) - -#include "APIObject.h" -#include "Arguments.h" -#include "GenericCallback.h" -#include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> - -namespace WebKit { - -class WebContext; -class WebProcessProxy; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebPluginSiteDataManager : public API::ObjectImpl<API::Object::Type::PluginSiteDataManager> { -public: - static PassRefPtr<WebPluginSiteDataManager> create(WebContext*); - virtual ~WebPluginSiteDataManager(); - - void invalidate(); - void clearContext() { m_webContext = 0; } - - void getSitesWithData(PassRefPtr<ArrayCallback>); - void didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID); - - void clearSiteData(API::Array* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback>); - void didClearSiteData(uint64_t callbackID); - - void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteDataForSinglePlugin(uint64_t callbackID); - -private: - explicit WebPluginSiteDataManager(WebContext*); - - WebContext* m_webContext; - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; - HashMap<uint64_t, RefPtr<VoidCallback>> m_voidCallbacks; - - void didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteDataForAllPlugins(uint64_t callbackID); - - class GetSitesWithDataState; - HashMap<uint64_t, OwnPtr<GetSitesWithDataState>> m_pendingGetSitesWithData; - - class ClearSiteDataState; - HashMap<uint64_t, OwnPtr<ClearSiteDataState>> m_pendingClearSiteData; -}; - -} // namespace WebKit - -#endif // ENABLE(NETSCAPE_PLUGIN_API) - -#endif // WebPluginSiteDataManager_h diff --git a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp b/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp index c6e46524d..3e1c2ef5a 100644 --- a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp +++ b/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp @@ -30,26 +30,48 @@ #include "NetscapePluginModule.h" #include <WebCore/FileSystem.h> +#include <WebCore/PlatformDisplay.h> #include <wtf/text/CString.h> namespace WebKit { -static const unsigned gSchemaVersion = 1; +static const unsigned gSchemaVersion = 3; -PluginInfoCache& PluginInfoCache::shared() +PluginInfoCache& PluginInfoCache::singleton() { static NeverDestroyed<PluginInfoCache> pluginInfoCache; return pluginInfoCache; } +static inline const char* cacheFilenameForCurrentDisplay() +{ +#if PLATFORM(X11) + if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11) + return "plugins-x11"; +#endif +#if PLATFORM(WAYLAND) + if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::Wayland) + return "plugins-wayland"; +#endif + + ASSERT_NOT_REACHED(); + return "plugins"; +} + PluginInfoCache::PluginInfoCache() : m_cacheFile(g_key_file_new()) - , m_saveToFileIdleId(0) + , m_saveToFileIdle(RunLoop::main(), this, &PluginInfoCache::saveToFile) , m_readOnlyMode(false) { + m_saveToFileIdle.setPriority(G_PRIORITY_DEFAULT_IDLE); + GUniquePtr<char> cacheDirectory(g_build_filename(g_get_user_cache_dir(), "webkitgtk", nullptr)); if (WebCore::makeAllDirectories(cacheDirectory.get())) { - m_cachePath.reset(g_build_filename(cacheDirectory.get(), "plugins", nullptr)); + // Delete old cache file. + GUniquePtr<char> oldCachePath(g_build_filename(cacheDirectory.get(), "plugins", nullptr)); + WebCore::deleteFile(WebCore::stringFromFileSystemRepresentation(oldCachePath.get())); + + m_cachePath.reset(g_build_filename(cacheDirectory.get(), cacheFilenameForCurrentDisplay(), nullptr)); g_key_file_load_from_file(m_cacheFile.get(), m_cachePath.get(), G_KEY_FILE_NONE, nullptr); } @@ -72,23 +94,10 @@ PluginInfoCache::PluginInfoCache() PluginInfoCache::~PluginInfoCache() { - if (m_saveToFileIdleId) { - g_source_remove(m_saveToFileIdleId); - saveToFile(); - } -} - -gboolean PluginInfoCache::saveToFileIdleCallback(PluginInfoCache* cache) -{ - cache->saveToFile(); - return FALSE; } void PluginInfoCache::saveToFile() { - std::lock_guard<std::mutex> lock(m_mutex); - m_saveToFileIdleId = 0; - gsize dataLength; GUniquePtr<char> data(g_key_file_to_data(m_cacheFile.get(), &dataLength, nullptr)); if (!data) @@ -124,6 +133,8 @@ bool PluginInfoCache::getPluginInfo(const String& pluginPath, PluginModuleInfo& NetscapePluginModule::parseMIMEDescription(String::fromUTF8(stringValue.get()), plugin.info.mimes); #endif + plugin.requiresGtk2 = g_key_file_get_boolean(m_cacheFile.get(), pluginGroup.data(), "requires-gtk2", nullptr); + return true; } @@ -143,14 +154,15 @@ void PluginInfoCache::updatePluginInfo(const String& pluginPath, const PluginMod g_key_file_set_string(m_cacheFile.get(), pluginGroup.data(), "mime-description", mimeDescription.utf8().data()); #endif + g_key_file_set_boolean(m_cacheFile.get(), pluginGroup.data(), "requires-gtk2", plugin.requiresGtk2); + if (m_cachePath && !m_readOnlyMode) { // Save the cache file in an idle to make sure it happens in the main thread and // it's done only once when this is called multiple times in a very short time. - std::lock_guard<std::mutex> lock(m_mutex); - if (m_saveToFileIdleId) + if (m_saveToFileIdle.isActive()) return; - m_saveToFileIdleId = g_idle_add(reinterpret_cast<GSourceFunc>(PluginInfoCache::saveToFileIdleCallback), this); + m_saveToFileIdle.startOneShot(0); } } diff --git a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h b/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h index 872f1eb01..1af7085e2 100644 --- a/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h +++ b/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h @@ -29,9 +29,9 @@ #if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginModuleInfo.h" -#include <mutex> #include <wtf/NeverDestroyed.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/RunLoop.h> +#include <wtf/glib/GUniquePtr.h> namespace WebKit { @@ -39,7 +39,7 @@ class PluginInfoCache { WTF_MAKE_NONCOPYABLE(PluginInfoCache); friend class NeverDestroyed<PluginInfoCache>; public: - static PluginInfoCache& shared(); + static PluginInfoCache& singleton(); bool getPluginInfo(const String& pluginPath, PluginModuleInfo&); void updatePluginInfo(const String& pluginPath, const PluginModuleInfo&); @@ -49,13 +49,11 @@ private: ~PluginInfoCache(); void saveToFile(); - static gboolean saveToFileIdleCallback(PluginInfoCache*); GUniquePtr<GKeyFile> m_cacheFile; GUniquePtr<char> m_cachePath; - unsigned m_saveToFileIdleId; + RunLoop::Timer<PluginInfoCache> m_saveToFileIdle; bool m_readOnlyMode; - std::mutex m_mutex; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp b/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp index a9685618f..3b7ef381a 100644 --- a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp +++ b/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp @@ -32,8 +32,12 @@ #include "PluginInfoStore.h" #include "NetscapePluginModule.h" -#include "PluginDatabase.h" +#include "PluginSearchPath.h" +#include "ProcessExecutablePath.h" #include <WebCore/FileSystem.h> +#include <WebCore/PlatformDisplay.h> +#include <limits.h> +#include <stdlib.h> #if PLATFORM(GTK) #include "PluginInfoCache.h" @@ -45,51 +49,17 @@ namespace WebKit { Vector<String> PluginInfoStore::pluginsDirectories() { - Vector<String> result; - - result.append(homeDirectoryPath() + "/.mozilla/plugins"); - result.append(homeDirectoryPath() + "/.netscape/plugins"); - result.append("/usr/lib/browser/plugins"); - result.append("/usr/local/lib/mozilla/plugins"); - result.append("/usr/lib/firefox/plugins"); - result.append("/usr/lib64/browser-plugins"); - result.append("/usr/lib/browser-plugins"); - result.append("/usr/lib/mozilla/plugins"); - result.append("/usr/local/netscape/plugins"); - result.append("/opt/mozilla/plugins"); - result.append("/opt/mozilla/lib/plugins"); - result.append("/opt/netscape/plugins"); - result.append("/opt/netscape/communicator/plugins"); - result.append("/usr/lib/netscape/plugins"); - result.append("/usr/lib/netscape/plugins-libc5"); - result.append("/usr/lib/netscape/plugins-libc6"); - result.append("/usr/lib64/netscape/plugins"); - result.append("/usr/lib64/mozilla/plugins"); - result.append("/usr/lib/nsbrowser/plugins"); - result.append("/usr/lib64/nsbrowser/plugins"); - - String mozillaHome(getenv("MOZILLA_HOME")); - if (!mozillaHome.isEmpty()) - result.append(mozillaHome + "/plugins"); - - String mozillaPaths(getenv("MOZ_PLUGIN_PATH")); - if (!mozillaPaths.isEmpty()) { - Vector<String> paths; - mozillaPaths.split(UChar(':'), /* allowEmptyEntries */ false, paths); - result.appendVector(paths); - } - - return result; + return WebKit::pluginsDirectories(); } Vector<String> PluginInfoStore::pluginPathsInDirectory(const String& directory) { Vector<String> result; - Vector<String> pluginPaths = listDirectory(directory, String("*.so")); - Vector<String>::const_iterator end = pluginPaths.end(); - for (Vector<String>::const_iterator it = pluginPaths.begin(); it != end; ++it) { - if (fileExists(*it)) - result.append(*it); + char normalizedPath[PATH_MAX]; + for (const auto& path : listDirectory(directory, String("*.so"))) { + CString filename = fileSystemRepresentation(path); + if (realpath(filename.data(), normalizedPath)) + result.append(stringFromFileSystemRepresentation(normalizedPath)); } return result; @@ -103,11 +73,22 @@ Vector<String> PluginInfoStore::individualPluginPaths() bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin) { #if PLATFORM(GTK) - if (PluginInfoCache::shared().getPluginInfo(pluginPath, plugin)) + if (PluginInfoCache::singleton().getPluginInfo(pluginPath, plugin)) { +#if ENABLE(PLUGIN_PROCESS_GTK2) + if (plugin.requiresGtk2) { + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return false; + String pluginProcessPath = executablePathOfPluginProcess(); + pluginProcessPath.append('2'); + if (!fileExists(pluginProcessPath)) + return false; + } +#endif return true; + } if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) { - PluginInfoCache::shared().updatePluginInfo(pluginPath, plugin); + PluginInfoCache::singleton().updatePluginInfo(pluginPath, plugin); return true; } return false; diff --git a/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp b/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp index 18e15864f..7601f4313 100644 --- a/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp +++ b/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Igalia S.L. + * Copyright (C) 2011, 2014 Igalia S.L. * Copyright (C) 2011 Apple Inc. * Copyright (C) 2012 Samsung Electronics * @@ -33,14 +33,19 @@ #include "PluginProcessCreationParameters.h" #include "ProcessExecutablePath.h" #include <WebCore/FileSystem.h> +#include <WebCore/PlatformDisplay.h> +#include <sys/wait.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> -#if PLATFORM(GTK) || PLATFORM(EFL) + +#if PLATFORM(GTK) #include <glib.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #endif -#include <sys/wait.h> +#if PLATFORM(GTK) +#include "Module.h" +#endif using namespace WebCore; @@ -48,33 +53,57 @@ namespace WebKit { void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes) { -#if PLATFORM(EFL) && !defined(NDEBUG) - const char* commandPrefix = getenv("PLUGIN_PROCESS_COMMAND_PREFIX"); - if (commandPrefix && *commandPrefix) - launchOptions.processCmdPrefix = String::fromUTF8(commandPrefix); -#endif + launchOptions.processType = ProcessLauncher::ProcessType::Plugin64; launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path); +#if PLATFORM(GTK) + if (pluginProcessAttributes.moduleInfo.requiresGtk2) + launchOptions.extraInitializationData.add("requires-gtk2", emptyString()); +#endif } void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&) { } +#if PLATFORM(GTK) +static bool pluginRequiresGtk2(const String& pluginPath) +{ + std::unique_ptr<Module> module = std::make_unique<Module>(pluginPath); + if (!module->load()) + return false; + return module->functionPointer<gpointer>("gtk_object_get_type"); +} +#endif + #if PLUGIN_ARCHITECTURE(X11) bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result) { -#if PLATFORM(GTK) || PLATFORM(EFL) - CString binaryPath = fileSystemRepresentation(executablePathOfPluginProcess()); +#if PLATFORM(GTK) + String pluginProcessPath = executablePathOfPluginProcess(); + +#if PLATFORM(GTK) + bool requiresGtk2 = pluginRequiresGtk2(pluginPath); + if (requiresGtk2) { + if (PlatformDisplay::sharedDisplay().type() != PlatformDisplay::Type::X11) + return false; +#if ENABLE(PLUGIN_PROCESS_GTK2) + pluginProcessPath.append('2'); + if (!fileExists(pluginProcessPath)) + return false; +#else + return false; +#endif + } +#endif + + CString binaryPath = fileSystemRepresentation(pluginProcessPath); CString pluginPathCString = fileSystemRepresentation(pluginPath); char* argv[4]; argv[0] = const_cast<char*>(binaryPath.data()); argv[1] = const_cast<char*>("-scanPlugin"); argv[2] = const_cast<char*>(pluginPathCString.data()); - argv[3] = 0; - - int status; - GUniqueOutPtr<char> stdOut; + argv[3] = nullptr; // If the disposition of SIGCLD signal is set to SIG_IGN (default) // then the signal will be ignored and g_spawn_sync() will not be @@ -90,27 +119,42 @@ bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& } #endif - if (!g_spawn_sync(0, argv, 0, G_SPAWN_STDERR_TO_DEV_NULL, 0, 0, &stdOut.outPtr(), 0, &status, 0)) + int status; + GUniqueOutPtr<char> stdOut; + GUniqueOutPtr<GError> error; + if (!g_spawn_sync(nullptr, argv, nullptr, G_SPAWN_STDERR_TO_DEV_NULL, nullptr, nullptr, &stdOut.outPtr(), nullptr, &status, &error.outPtr())) { + WTFLogAlways("Failed to launch %s: %s", argv[0], error->message); return false; + } - if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS || !stdOut) + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { + WTFLogAlways("Error scanning plugin %s, %s returned %d exit status", argv[2], argv[0], status); return false; + } - String stdOutString = String::fromUTF8(stdOut.get()); + if (!stdOut) { + WTFLogAlways("Error scanning plugin %s, %s didn't write any output to stdout", argv[2], argv[0]); + return false; + } Vector<String> lines; - stdOutString.split(UChar('\n'), true, lines); + String::fromUTF8(stdOut.get()).split(UChar('\n'), true, lines); - if (lines.size() < 3) + if (lines.size() < 3) { + WTFLogAlways("Error scanning plugin %s, too few lines of output provided", argv[2]); return false; + } result.name.swap(lines[0]); result.description.swap(lines[1]); result.mimeDescription.swap(lines[2]); +#if PLATFORM(GTK) + result.requiresGtk2 = requiresGtk2; +#endif return !result.mimeDescription.isEmpty(); -#else // PLATFORM(GTK) || PLATFORM(EFL) +#else // PLATFORM(GTK) return false; -#endif // PLATFORM(GTK) || PLATFORM(EFL) +#endif // PLATFORM(GTK) } #endif // PLUGIN_ARCHITECTURE(X11) diff --git a/Source/WebKit2/UIProcess/ProcessAssertion.cpp b/Source/WebKit2/UIProcess/ProcessAssertion.cpp new file mode 100644 index 000000000..a66e1224f --- /dev/null +++ b/Source/WebKit2/UIProcess/ProcessAssertion.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProcessAssertion.h" + +#if !PLATFORM(IOS) + +namespace WebKit { + +ProcessAssertion::ProcessAssertion(pid_t, AssertionState assertionState, Function<void()>&&) + : m_assertionState(assertionState) +{ +} + +ProcessAssertion::~ProcessAssertion() +{ +} + +void ProcessAssertion::setState(AssertionState assertionState) +{ + if (m_assertionState == assertionState) + return; + + m_assertionState = assertionState; +} + +ProcessAndUIAssertion::ProcessAndUIAssertion(pid_t pid, AssertionState assertionState) + : ProcessAssertion(pid, assertionState) +{ +} + +ProcessAndUIAssertion::~ProcessAndUIAssertion() +{ +} + +void ProcessAndUIAssertion::setState(AssertionState assertionState) +{ + ProcessAssertion::setState(assertionState); +} + +void ProcessAndUIAssertion::setClient(ProcessAssertionClient& client) +{ + ProcessAssertion::setClient(client); +} + +} + +#endif // !PLATFORM(IOS) diff --git a/Source/WebKit2/UIProcess/ProcessAssertion.h b/Source/WebKit2/UIProcess/ProcessAssertion.h new file mode 100644 index 000000000..e054affe8 --- /dev/null +++ b/Source/WebKit2/UIProcess/ProcessAssertion.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProcessAssertion_h +#define ProcessAssertion_h + +#include <functional> +#include <wtf/Function.h> + +#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR) +#include <wtf/RetainPtr.h> +#include <wtf/WeakPtr.h> +OBJC_CLASS BKSProcessAssertion; +#endif + +namespace WebKit { + +enum class AssertionState { + Suspended, + Background, + Foreground +}; + +class ProcessAssertionClient { +public: + virtual ~ProcessAssertionClient() { }; + virtual void assertionWillExpireImminently() = 0; +}; + +class ProcessAssertion { +public: + ProcessAssertion(pid_t, AssertionState, Function<void()>&& invalidationCallback = { }); + ~ProcessAssertion(); + + void setClient(ProcessAssertionClient& client) { m_client = &client; } + ProcessAssertionClient* client() { return m_client; } + + AssertionState state() const { return m_assertionState; } + void setState(AssertionState); + +#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR) +protected: + enum class Validity { No, Yes, Unset }; + Validity validity() const { return m_validity; } +#endif + +private: +#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR) + WeakPtr<ProcessAssertion> createWeakPtr() { return m_weakFactory.createWeakPtr(); } + void markAsInvalidated(); + + RetainPtr<BKSProcessAssertion> m_assertion; + Validity m_validity { Validity::Unset }; + WeakPtrFactory<ProcessAssertion> m_weakFactory; + Function<void()> m_invalidationCallback; +#endif + AssertionState m_assertionState; + ProcessAssertionClient* m_client { nullptr }; +}; + +class ProcessAndUIAssertion : public ProcessAssertion { +public: + ProcessAndUIAssertion(pid_t, AssertionState); + ~ProcessAndUIAssertion(); + + void setClient(ProcessAssertionClient&); + + void setState(AssertionState); + +#if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR) +private: + void updateRunInBackgroundCount(); + + bool m_isHoldingBackgroundAssertion { false }; +#endif +}; + +} + +#endif // ProcessAssertion_h diff --git a/Source/WebKit2/UIProcess/ProcessThrottler.cpp b/Source/WebKit2/UIProcess/ProcessThrottler.cpp new file mode 100644 index 000000000..77b0b8c71 --- /dev/null +++ b/Source/WebKit2/UIProcess/ProcessThrottler.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO , PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ProcessThrottler.h" + +#include "Logging.h" +#include "ProcessThrottlerClient.h" + +namespace WebKit { + +static const unsigned processSuspensionTimeout = 30; + +ProcessThrottler::ProcessThrottler(ProcessThrottlerClient& process) + : m_process(process) + , m_suspendTimer(RunLoop::main(), this, &ProcessThrottler::suspendTimerFired) + , m_foregroundCounter([this](RefCounterEvent) { updateAssertion(); }) + , m_backgroundCounter([this](RefCounterEvent) { updateAssertion(); }) + , m_suspendMessageCount(0) +{ +} + +AssertionState ProcessThrottler::assertionState() +{ + ASSERT(!m_suspendTimer.isActive()); + + if (m_foregroundCounter.value()) + return AssertionState::Foreground; + if (m_backgroundCounter.value()) + return AssertionState::Background; + return AssertionState::Suspended; +} + +void ProcessThrottler::updateAssertionNow() +{ + m_suspendTimer.stop(); + if (m_assertion) { + if (m_assertion->state() != assertionState()) + RELEASE_LOG(ProcessSuspension, "%p - ProcessThrottler::updateAssertionNow() updating process assertion state to %u (foregroundActivities: %lu, backgroundActivities: %lu)", this, assertionState(), m_foregroundCounter.value(), m_backgroundCounter.value()); + m_assertion->setState(assertionState()); + m_process.didSetAssertionState(assertionState()); + } +} + +void ProcessThrottler::updateAssertion() +{ + // If the process is currently runnable but will be suspended then first give it a chance to complete what it was doing + // and clean up - move it to the background and send it a message to notify. Schedule a timeout so it can't stay running + // in the background for too long. + if (m_assertion && m_assertion->state() != AssertionState::Suspended && !m_foregroundCounter.value() && !m_backgroundCounter.value()) { + ++m_suspendMessageCount; + RELEASE_LOG(ProcessSuspension, "%p - ProcessThrottler::updateAssertion() sending PrepareToSuspend IPC", this); + m_process.sendPrepareToSuspend(); + m_suspendTimer.startOneShot(processSuspensionTimeout); + m_assertion->setState(AssertionState::Background); + m_process.didSetAssertionState(AssertionState::Background); + return; + } + + bool shouldBeRunnable = m_foregroundCounter.value() || m_backgroundCounter.value(); + + // If we're currently waiting for the Web process to do suspension cleanup, but no longer need to be suspended, tell the Web process to cancel the cleanup. + if (m_suspendTimer.isActive() && shouldBeRunnable) + m_process.sendCancelPrepareToSuspend(); + + if (m_assertion && m_assertion->state() == AssertionState::Suspended && shouldBeRunnable) + m_process.sendProcessDidResume(); + + updateAssertionNow(); +} + +void ProcessThrottler::didConnectToProcess(pid_t pid) +{ + m_suspendTimer.stop(); + m_assertion = std::make_unique<ProcessAndUIAssertion>(pid, assertionState()); + m_process.didSetAssertionState(assertionState()); + m_assertion->setClient(*this); +} + +void ProcessThrottler::suspendTimerFired() +{ + updateAssertionNow(); +} + +void ProcessThrottler::processReadyToSuspend() +{ + if (!--m_suspendMessageCount) + updateAssertionNow(); + ASSERT(m_suspendMessageCount >= 0); +} + +void ProcessThrottler::didCancelProcessSuspension() +{ + if (!--m_suspendMessageCount) + updateAssertionNow(); + ASSERT(m_suspendMessageCount >= 0); +} + +void ProcessThrottler::assertionWillExpireImminently() +{ + m_process.sendProcessWillSuspendImminently(); +} + +} diff --git a/Source/WebKit2/UIProcess/ProcessThrottler.h b/Source/WebKit2/UIProcess/ProcessThrottler.h new file mode 100644 index 000000000..29f58a10f --- /dev/null +++ b/Source/WebKit2/UIProcess/ProcessThrottler.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProcessThrottler_h +#define ProcessThrottler_h + +#include "ProcessAssertion.h" + +#include <wtf/RefCounter.h> +#include <wtf/RunLoop.h> +#include <wtf/WeakPtr.h> + +namespace WebKit { + +enum UserObservablePageCounterType { }; +typedef RefCounter<UserObservablePageCounterType> UserObservablePageCounter; +enum ProcessSuppressionDisabledCounterType { }; +typedef RefCounter<ProcessSuppressionDisabledCounterType> ProcessSuppressionDisabledCounter; +typedef ProcessSuppressionDisabledCounter::Token ProcessSuppressionDisabledToken; + +class ProcessThrottlerClient; + +class ProcessThrottler : private ProcessAssertionClient { +public: + enum ForegroundActivityCounterType { }; + typedef RefCounter<ForegroundActivityCounterType> ForegroundActivityCounter; + typedef ForegroundActivityCounter::Token ForegroundActivityToken; + enum BackgroundActivityCounterType { }; + typedef RefCounter<BackgroundActivityCounterType> BackgroundActivityCounter; + typedef BackgroundActivityCounter::Token BackgroundActivityToken; + + ProcessThrottler(ProcessThrottlerClient&); + + inline ForegroundActivityToken foregroundActivityToken() const; + inline BackgroundActivityToken backgroundActivityToken() const; + + void didConnectToProcess(pid_t); + void processReadyToSuspend(); + void didCancelProcessSuspension(); + +private: + AssertionState assertionState(); + void updateAssertion(); + void updateAssertionNow(); + void suspendTimerFired(); + + // ProcessAssertionClient + void assertionWillExpireImminently() override; + + ProcessThrottlerClient& m_process; + std::unique_ptr<ProcessAndUIAssertion> m_assertion; + RunLoop::Timer<ProcessThrottler> m_suspendTimer; + ForegroundActivityCounter m_foregroundCounter; + BackgroundActivityCounter m_backgroundCounter; + int m_suspendMessageCount; +}; + +inline ProcessThrottler::ForegroundActivityToken ProcessThrottler::foregroundActivityToken() const +{ + return ForegroundActivityToken(m_foregroundCounter.count()); +} + +inline ProcessThrottler::BackgroundActivityToken ProcessThrottler::backgroundActivityToken() const +{ + return BackgroundActivityToken(m_backgroundCounter.count()); +} + +} + +#endif // ProcessThrottler_h diff --git a/Source/WebKit2/UIProcess/ProcessThrottlerClient.h b/Source/WebKit2/UIProcess/ProcessThrottlerClient.h new file mode 100644 index 000000000..f8def87b6 --- /dev/null +++ b/Source/WebKit2/UIProcess/ProcessThrottlerClient.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProcessThrottlerClient_h +#define ProcessThrottlerClient_h + +#include "ProcessAssertion.h" + +namespace WebKit { + +class ProcessThrottlerClient { +public: + virtual ~ProcessThrottlerClient() { } + + virtual void sendProcessWillSuspendImminently() = 0; + virtual void sendPrepareToSuspend() = 0; + virtual void sendCancelPrepareToSuspend() = 0; + virtual void sendProcessDidResume() = 0; + virtual void didSetAssertionState(AssertionState) = 0; +}; + +} // namespace WebKit + +#endif // ProcessThrottlerClient_h + diff --git a/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.cpp b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.cpp new file mode 100644 index 000000000..2228b03c2 --- /dev/null +++ b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RemoteWebInspectorProxy.h" + +#include "RemoteWebInspectorProxyMessages.h" +#include "RemoteWebInspectorUIMessages.h" +#include "WebInspectorProxy.h" +#include "WebPageGroup.h" +#include "WebPageProxy.h" +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +RemoteWebInspectorProxy::RemoteWebInspectorProxy() +{ +} + +RemoteWebInspectorProxy::~RemoteWebInspectorProxy() +{ + ASSERT(!m_inspectorPage); +} + +void RemoteWebInspectorProxy::invalidate() +{ + closeFrontendPageAndWindow(); +} + +void RemoteWebInspectorProxy::load(const String& debuggableType, const String& backendCommandsURL) +{ + createFrontendPageAndWindow(); + + m_inspectorPage->process().send(Messages::RemoteWebInspectorUI::Initialize(debuggableType, backendCommandsURL), m_inspectorPage->pageID()); + m_inspectorPage->loadRequest(URL(URL(), WebInspectorProxy::inspectorPageURL())); +} + +void RemoteWebInspectorProxy::closeFromBackend() +{ + closeFrontendPageAndWindow(); +} + +void RemoteWebInspectorProxy::closeFromCrash() +{ + // Behave as if the frontend just closed, so clients are informed the frontend is gone. + frontendDidClose(); +} + +void RemoteWebInspectorProxy::show() +{ + bringToFront(); +} + +void RemoteWebInspectorProxy::sendMessageToFrontend(const String& message) +{ + m_inspectorPage->process().send(Messages::RemoteWebInspectorUI::SendMessageToFrontend(message), m_inspectorPage->pageID()); +} + +void RemoteWebInspectorProxy::frontendDidClose() +{ + if (m_client) + m_client->closeFromFrontend(); + + closeFrontendPageAndWindow(); +} + +void RemoteWebInspectorProxy::bringToFront() +{ + platformBringToFront(); +} + +void RemoteWebInspectorProxy::save(const String& suggestedURL, const String& content, bool base64Encoded, bool forceSaveDialog) +{ + platformSave(suggestedURL, content, base64Encoded, forceSaveDialog); +} + +void RemoteWebInspectorProxy::append(const String& suggestedURL, const String& content) +{ + platformAppend(suggestedURL, content); +} + +void RemoteWebInspectorProxy::startWindowDrag() +{ + platformStartWindowDrag(); +} + +void RemoteWebInspectorProxy::openInNewTab(const String& url) +{ + platformOpenInNewTab(url); +} + +void RemoteWebInspectorProxy::sendMessageToBackend(const String& message) +{ + if (m_client) + m_client->sendMessageToBackend(message); +} + +void RemoteWebInspectorProxy::createFrontendPageAndWindow() +{ + if (m_inspectorPage) + return; + + m_inspectorPage = platformCreateFrontendPageAndWindow(); + + trackInspectorPage(m_inspectorPage); + + m_inspectorPage->process().addMessageReceiver(Messages::RemoteWebInspectorProxy::messageReceiverName(), m_inspectorPage->pageID(), *this); + m_inspectorPage->process().assumeReadAccessToBaseURL(WebInspectorProxy::inspectorBaseURL()); +} + +void RemoteWebInspectorProxy::closeFrontendPageAndWindow() +{ + if (!m_inspectorPage) + return; + + m_inspectorPage->process().removeMessageReceiver(Messages::RemoteWebInspectorProxy::messageReceiverName(), m_inspectorPage->pageID()); + + untrackInspectorPage(m_inspectorPage); + + m_inspectorPage = nullptr; + + platformCloseFrontendPageAndWindow(); +} + +#if !PLATFORM(MAC) +WebPageProxy* RemoteWebInspectorProxy::platformCreateFrontendPageAndWindow() +{ + notImplemented(); + return nullptr; +} + +void RemoteWebInspectorProxy::platformBringToFront() { } +void RemoteWebInspectorProxy::platformSave(const String&, const String&, bool, bool) { } +void RemoteWebInspectorProxy::platformAppend(const String&, const String&) { } +void RemoteWebInspectorProxy::platformStartWindowDrag() { } +void RemoteWebInspectorProxy::platformOpenInNewTab(const String&) { } +void RemoteWebInspectorProxy::platformCloseFrontendPageAndWindow() { } +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.h b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.h new file mode 100644 index 000000000..d9556a823 --- /dev/null +++ b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "APIObject.h" +#include "MessageReceiver.h" +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> + +#if PLATFORM(MAC) +OBJC_CLASS NSURL; +OBJC_CLASS NSWindow; +OBJC_CLASS WKRemoteWebInspectorProxyObjCAdapter; +OBJC_CLASS WKWebInspectorWKWebView; +#endif + +namespace WebKit { + +class WebPageProxy; + +class RemoteWebInspectorProxyClient { +public: + virtual ~RemoteWebInspectorProxyClient() { } + virtual void sendMessageToBackend(const String& message) = 0; + virtual void closeFromFrontend() = 0; +}; + +class RemoteWebInspectorProxy : public RefCounted<RemoteWebInspectorProxy>, public IPC::MessageReceiver { +public: + static Ref<RemoteWebInspectorProxy> create() + { + return adoptRef(*new RemoteWebInspectorProxy()); + } + + ~RemoteWebInspectorProxy(); + + void setClient(RemoteWebInspectorProxyClient* client) { m_client = client; } + + void invalidate(); + + void load(const String& debuggableType, const String& backendCommandsURL); + void closeFromBackend(); + void show(); + + void sendMessageToFrontend(const String& message); + +#if PLATFORM(MAC) + NSWindow *window() const { return m_window.get(); } + WKWebInspectorWKWebView *webView() const { return m_webView.get(); } +#endif + + void closeFromCrash(); + +private: + RemoteWebInspectorProxy(); + + // IPC::MessageReceiver + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + + // RemoteWebInspectorProxy messages. + void frontendDidClose(); + void bringToFront(); + void save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs); + void append(const String& filename, const String& content); + void startWindowDrag(); + void openInNewTab(const String& url); + void sendMessageToBackend(const String& message); + + void createFrontendPageAndWindow(); + void closeFrontendPageAndWindow(); + + // Platform implementations. + WebPageProxy* platformCreateFrontendPageAndWindow(); + void platformCloseFrontendPageAndWindow(); + void platformBringToFront(); + void platformSave(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs); + void platformAppend(const String& filename, const String& content); + void platformStartWindowDrag(); + void platformOpenInNewTab(const String& url); + + RemoteWebInspectorProxyClient* m_client { nullptr }; + WebPageProxy* m_inspectorPage { nullptr }; + +#if PLATFORM(MAC) + RetainPtr<WKWebInspectorWKWebView> m_webView; + RetainPtr<NSWindow> m_window; + RetainPtr<WKRemoteWebInspectorProxyObjCAdapter> m_objCAdapter; + HashMap<String, RetainPtr<NSURL>> m_suggestedToActualURLMap; +#endif +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.messages.in b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.messages.in index b6acdc26b..84b5259d7 100644 --- a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/RemoteWebInspectorProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Intel Corporation. All rights reserved. +# Copyright (C) 2016 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,14 +20,16 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(NETWORK_INFO) +messages -> RemoteWebInspectorProxy { + FrontendDidClose() + BringToFront() -messages -> WebNetworkInfoManagerProxy { - StartUpdating(); - StopUpdating(); + Save(String filename, String content, bool base64Encoded, bool forceSaveAs) + Append(String filename, String content) - GetBandwidth() -> (double bandwidth); - IsMetered() -> (bool metered); -} + StartWindowDrag() + + OpenInNewTab(String url) -#endif + SendMessageToBackend(String message) +} diff --git a/Source/WebKit2/UIProcess/ResponsivenessTimer.cpp b/Source/WebKit2/UIProcess/ResponsivenessTimer.cpp index 9739fa3a1..feb469f08 100644 --- a/Source/WebKit2/UIProcess/ResponsivenessTimer.cpp +++ b/Source/WebKit2/UIProcess/ResponsivenessTimer.cpp @@ -30,7 +30,7 @@ namespace WebKit { static const double responsivenessTimeout = 3; -ResponsivenessTimer::ResponsivenessTimer(ResponsivenessTimer::Client* client) +ResponsivenessTimer::ResponsivenessTimer(ResponsivenessTimer::Client& client) : m_client(client) , m_isResponsive(true) , m_timer(RunLoop::main(), this, &ResponsivenessTimer::timerFired) @@ -49,13 +49,19 @@ void ResponsivenessTimer::invalidate() void ResponsivenessTimer::timerFired() { - if (m_isResponsive) { - m_isResponsive = false; - m_client->didBecomeUnresponsive(this); - } else { - // The timer fired while unresponsive. - m_client->interactionOccurredWhileUnresponsive(this); + if (!m_isResponsive) + return; + + if (!m_client.mayBecomeUnresponsive()) { + m_timer.startOneShot(responsivenessTimeout); + return; } + + m_client.willChangeIsResponsive(); + m_isResponsive = false; + m_client.didChangeIsResponsive(); + + m_client.didBecomeUnresponsive(); } void ResponsivenessTimer::start() @@ -69,12 +75,21 @@ void ResponsivenessTimer::start() void ResponsivenessTimer::stop() { if (!m_isResponsive) { - // We got a life sign from the web process! - m_client->didBecomeResponsive(this); + // We got a life sign from the web process. + m_client.willChangeIsResponsive(); m_isResponsive = true; + m_client.didChangeIsResponsive(); + + m_client.didBecomeResponsive(); } m_timer.stop(); } +void ResponsivenessTimer::processTerminated() +{ + // Since there is no web process, we must not be waiting for it anymore. + stop(); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/ResponsivenessTimer.h b/Source/WebKit2/UIProcess/ResponsivenessTimer.h index f75c0a998..9b100406f 100644 --- a/Source/WebKit2/UIProcess/ResponsivenessTimer.h +++ b/Source/WebKit2/UIProcess/ResponsivenessTimer.h @@ -35,12 +35,16 @@ public: class Client { public: virtual ~Client() { } - virtual void didBecomeUnresponsive(ResponsivenessTimer*) = 0; - virtual void interactionOccurredWhileUnresponsive(ResponsivenessTimer*) = 0; - virtual void didBecomeResponsive(ResponsivenessTimer*) = 0; + virtual void didBecomeUnresponsive() = 0; + virtual void didBecomeResponsive() = 0; + + virtual void willChangeIsResponsive() = 0; + virtual void didChangeIsResponsive() = 0; + + virtual bool mayBecomeUnresponsive() = 0; }; - explicit ResponsivenessTimer(ResponsivenessTimer::Client*); + explicit ResponsivenessTimer(ResponsivenessTimer::Client&); ~ResponsivenessTimer(); void start(); @@ -50,10 +54,12 @@ public: bool isResponsive() { return m_isResponsive; } + void processTerminated(); + private: void timerFired(); - ResponsivenessTimer::Client* m_client; + ResponsivenessTimer::Client& m_client; bool m_isResponsive; RunLoop::Timer<ResponsivenessTimer> m_timer; diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp new file mode 100644 index 000000000..383df5894 --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RemoteScrollingCoordinatorProxy.h" + +#if ENABLE(ASYNC_SCROLLING) + +#include "ArgumentCoders.h" +#include "RemoteLayerTreeDrawingAreaProxy.h" +#include "RemoteScrollingCoordinator.h" +#include "RemoteScrollingCoordinatorMessages.h" +#include "RemoteScrollingCoordinatorTransaction.h" +#include "WebPageProxy.h" +#include "WebProcessProxy.h" +#include <WebCore/ScrollingStateFrameScrollingNode.h> +#include <WebCore/ScrollingStateOverflowScrollingNode.h> +#include <WebCore/ScrollingStateTree.h> +#include <WebCore/ScrollingTreeScrollingNode.h> + +using namespace WebCore; + +namespace WebKit { + +RemoteScrollingCoordinatorProxy::RemoteScrollingCoordinatorProxy(WebPageProxy& webPageProxy) + : m_webPageProxy(webPageProxy) + , m_scrollingTree(RemoteScrollingTree::create(*this)) + , m_requestedScrollInfo(nullptr) + , m_propagatesMainFrameScrolls(true) +{ +} + +RemoteScrollingCoordinatorProxy::~RemoteScrollingCoordinatorProxy() +{ +} + +ScrollingNodeID RemoteScrollingCoordinatorProxy::rootScrollingNodeID() const +{ + if (!m_scrollingTree->rootNode()) + return 0; + + return m_scrollingTree->rootNode()->scrollingNodeID(); +} + +const RemoteLayerTreeHost* RemoteScrollingCoordinatorProxy::layerTreeHost() const +{ + DrawingAreaProxy* drawingArea = m_webPageProxy.drawingArea(); + if (!is<RemoteLayerTreeDrawingAreaProxy>(drawingArea)) { + ASSERT_NOT_REACHED(); + return nullptr; + } + + RemoteLayerTreeDrawingAreaProxy& remoteDrawingArea = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea); + return &remoteDrawingArea.remoteLayerTreeHost(); +} + +void RemoteScrollingCoordinatorProxy::commitScrollingTreeState(const RemoteScrollingCoordinatorTransaction& transaction, RequestedScrollInfo& requestedScrollInfo) +{ + m_requestedScrollInfo = &requestedScrollInfo; + + // FIXME: There must be a better idiom for this. + std::unique_ptr<ScrollingStateTree> stateTree(const_cast<RemoteScrollingCoordinatorTransaction&>(transaction).scrollingStateTree().release()); + + const RemoteLayerTreeHost* layerTreeHost = this->layerTreeHost(); + if (!layerTreeHost) { + ASSERT_NOT_REACHED(); + return; + } + + connectStateNodeLayers(*stateTree, *layerTreeHost); + m_scrollingTree->commitTreeState(WTFMove(stateTree)); + + m_requestedScrollInfo = nullptr; +} + +#if !PLATFORM(IOS) +void RemoteScrollingCoordinatorProxy::connectStateNodeLayers(ScrollingStateTree& stateTree, const RemoteLayerTreeHost& layerTreeHost) +{ + for (auto& currNode : stateTree.nodeMap().values()) { + if (currNode->hasChangedProperty(ScrollingStateNode::ScrollLayer)) + currNode->setLayer(layerTreeHost.getLayer(currNode->layer())); + + switch (currNode->nodeType()) { + case FrameScrollingNode: { + ScrollingStateFrameScrollingNode& scrollingStateNode = downcast<ScrollingStateFrameScrollingNode>(*currNode); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::ScrolledContentsLayer)) + scrollingStateNode.setScrolledContentsLayer(layerTreeHost.getLayer(scrollingStateNode.scrolledContentsLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::CounterScrollingLayer)) + scrollingStateNode.setCounterScrollingLayer(layerTreeHost.getLayer(scrollingStateNode.counterScrollingLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::InsetClipLayer)) + scrollingStateNode.setInsetClipLayer(layerTreeHost.getLayer(scrollingStateNode.insetClipLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::ContentShadowLayer)) + scrollingStateNode.setContentShadowLayer(layerTreeHost.getLayer(scrollingStateNode.contentShadowLayer())); + + // FIXME: we should never have header and footer layers coming from the WebProcess. + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::HeaderLayer)) + scrollingStateNode.setHeaderLayer(layerTreeHost.getLayer(scrollingStateNode.headerLayer())); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateFrameScrollingNode::FooterLayer)) + scrollingStateNode.setFooterLayer(layerTreeHost.getLayer(scrollingStateNode.footerLayer())); + break; + } + case OverflowScrollingNode: { + ScrollingStateOverflowScrollingNode& scrollingStateNode = downcast<ScrollingStateOverflowScrollingNode>(*currNode); + + if (scrollingStateNode.hasChangedProperty(ScrollingStateOverflowScrollingNode::ScrolledContentsLayer)) + scrollingStateNode.setScrolledContentsLayer(layerTreeHost.getLayer(scrollingStateNode.scrolledContentsLayer())); + break; + } + case FixedNode: + case StickyNode: + break; + } + } +} +#endif + +bool RemoteScrollingCoordinatorProxy::handleWheelEvent(const PlatformWheelEvent& event) +{ + ScrollingTree::EventResult result = m_scrollingTree->tryToHandleWheelEvent(event); + return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values. +} + +TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p) const +{ + return m_scrollingTree->eventTrackingTypeForPoint(eventName, p); +} + +void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const FloatRect& fixedPositionRect, double scale) +{ + m_scrollingTree->viewportChangedViaDelegatedScrolling(nodeID, fixedPositionRect, scale); +} + +void RemoteScrollingCoordinatorProxy::currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical) +{ + m_webPageProxy.send(Messages::RemoteScrollingCoordinator::CurrentSnapPointIndicesChangedForNode(nodeID, horizontal, vertical)); +} + +// This comes from the scrolling tree. +void RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& newScrollPosition, const std::optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction) +{ + // Scroll updates for the main frame are sent via WebPageProxy::updateVisibleContentRects() + // so don't send them here. + if (!m_propagatesMainFrameScrolls && scrolledNodeID == rootScrollingNodeID()) + return; + +#if PLATFORM(IOS) + m_webPageProxy.overflowScrollViewDidScroll(); +#endif + m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction == ScrollingLayerPositionAction::Sync)); +} + +void RemoteScrollingCoordinatorProxy::scrollingTreeNodeRequestsScroll(ScrollingNodeID scrolledNodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll) +{ + if (scrolledNodeID == rootScrollingNodeID() && m_requestedScrollInfo) { + m_requestedScrollInfo->requestsScrollPositionUpdate = true; + m_requestedScrollInfo->requestIsProgrammaticScroll = representsProgrammaticScroll; + m_requestedScrollInfo->requestedScrollPosition = scrollPosition; + } +} + +String RemoteScrollingCoordinatorProxy::scrollingTreeAsText() const +{ + if (m_scrollingTree) + return m_scrollingTree->scrollingTreeAsText(); + + return emptyString(); +} + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h new file mode 100644 index 000000000..e87bb2c2e --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2014-2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RemoteScrollingCoordinatorProxy_h +#define RemoteScrollingCoordinatorProxy_h + +#if ENABLE(ASYNC_SCROLLING) + +#include "MessageReceiver.h" +#include "RemoteScrollingCoordinator.h" +#include "RemoteScrollingTree.h" +#include <wtf/Noncopyable.h> +#include <wtf/RefPtr.h> + +namespace WebCore { +class FloatPoint; +class PlatformWheelEvent; +} + +namespace WebKit { + +class RemoteLayerTreeHost; +class RemoteScrollingCoordinatorTransaction; +class RemoteScrollingTree; +class WebPageProxy; + +class RemoteScrollingCoordinatorProxy { + WTF_MAKE_NONCOPYABLE(RemoteScrollingCoordinatorProxy); +public: + explicit RemoteScrollingCoordinatorProxy(WebPageProxy&); + virtual ~RemoteScrollingCoordinatorProxy(); + + bool visualViewportEnabled() const { return m_scrollingTree && m_scrollingTree->visualViewportEnabled(); } + + // Inform the web process that the scroll position changed (called from the scrolling tree) + void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, const std::optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction); + void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll); + + WebCore::TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, WebCore::IntPoint) const; + + // Called externally when native views move around. + void viewportChangedViaDelegatedScrolling(WebCore::ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale); + + void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical); + + // FIXME: expose the tree and pass this to that? + bool handleWheelEvent(const WebCore::PlatformWheelEvent&); + + WebCore::ScrollingNodeID rootScrollingNodeID() const; + + const RemoteLayerTreeHost* layerTreeHost() const; + + struct RequestedScrollInfo { + bool requestsScrollPositionUpdate { }; + bool requestIsProgrammaticScroll { }; + WebCore::FloatPoint requestedScrollPosition; + }; + void commitScrollingTreeState(const RemoteScrollingCoordinatorTransaction&, RequestedScrollInfo&); + + void setPropagatesMainFrameScrolls(bool propagatesMainFrameScrolls) { m_propagatesMainFrameScrolls = propagatesMainFrameScrolls; } + bool propagatesMainFrameScrolls() const { return m_propagatesMainFrameScrolls; } + bool hasFixedOrSticky() const { return m_scrollingTree->hasFixedOrSticky(); } + +#if PLATFORM(IOS) + WebCore::FloatRect customFixedPositionRect() const; + void scrollingTreeNodeWillStartPanGesture(); + void scrollingTreeNodeWillStartScroll(); + void scrollingTreeNodeDidEndScroll(); +#if ENABLE(CSS_SCROLL_SNAP) + void adjustTargetContentOffsetForSnapping(CGSize maxScrollDimensions, CGPoint velocity, CGFloat topInset, CGPoint* targetContentOffset); + bool hasActiveSnapPoint() const; + CGPoint nearestActiveContentInsetAdjustedSnapPoint(CGFloat topInset, const CGPoint&) const; + bool shouldSetScrollViewDecelerationRateFast() const; +#endif +#endif + + String scrollingTreeAsText() const; + +private: + void connectStateNodeLayers(WebCore::ScrollingStateTree&, const RemoteLayerTreeHost&); +#if ENABLE(CSS_SCROLL_SNAP) + bool shouldSnapForMainFrameScrolling(WebCore::ScrollEventAxis) const; + float closestSnapOffsetForMainFrameScrolling(WebCore::ScrollEventAxis, float scrollDestination, float velocity, unsigned& closestIndex) const; +#endif + + WebPageProxy& m_webPageProxy; + RefPtr<RemoteScrollingTree> m_scrollingTree; + RequestedScrollInfo* m_requestedScrollInfo; +#if ENABLE(CSS_SCROLL_SNAP) + unsigned m_currentHorizontalSnapPointIndex { 0 }; + unsigned m_currentVerticalSnapPointIndex { 0 }; +#endif + bool m_propagatesMainFrameScrolls; +}; + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) + +#endif // RemoteScrollingCoordinatorProxy_h diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp new file mode 100644 index 000000000..421c7457c --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "RemoteScrollingTree.h" + +#if ENABLE(ASYNC_SCROLLING) + +#include "RemoteLayerTreeHost.h" +#include "RemoteScrollingCoordinatorProxy.h" +#include <WebCore/ScrollingTreeFixedNode.h> +#include <WebCore/ScrollingTreeStickyNode.h> + +#if PLATFORM(IOS) +#include "ScrollingTreeOverflowScrollingNodeIOS.h" +#include <WebCore/ScrollingTreeFrameScrollingNodeIOS.h> +#else +#include <WebCore/ScrollingTreeFrameScrollingNodeMac.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +Ref<RemoteScrollingTree> RemoteScrollingTree::create(RemoteScrollingCoordinatorProxy& scrollingCoordinator) +{ + return adoptRef(*new RemoteScrollingTree(scrollingCoordinator)); +} + +RemoteScrollingTree::RemoteScrollingTree(RemoteScrollingCoordinatorProxy& scrollingCoordinator) + : m_scrollingCoordinatorProxy(scrollingCoordinator) +{ +} + +RemoteScrollingTree::~RemoteScrollingTree() +{ +} + +ScrollingTree::EventResult RemoteScrollingTree::tryToHandleWheelEvent(const PlatformWheelEvent& wheelEvent) +{ + if (shouldHandleWheelEventSynchronously(wheelEvent)) + return SendToMainThread; + + if (willWheelEventStartSwipeGesture(wheelEvent)) + return DidNotHandleEvent; + + handleWheelEvent(wheelEvent); + return DidHandleEvent; +} + +#if PLATFORM(MAC) +void RemoteScrollingTree::handleWheelEventPhase(PlatformWheelEventPhase phase) +{ + // FIXME: hand off to m_scrollingCoordinatorProxy? +} +#endif + +#if PLATFORM(IOS) +WebCore::FloatRect RemoteScrollingTree::fixedPositionRect() +{ + return m_scrollingCoordinatorProxy.customFixedPositionRect(); +} + +void RemoteScrollingTree::scrollingTreeNodeWillStartPanGesture() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeWillStartPanGesture(); +} + +void RemoteScrollingTree::scrollingTreeNodeWillStartScroll() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeWillStartScroll(); +} + +void RemoteScrollingTree::scrollingTreeNodeDidEndScroll() +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeDidEndScroll(); +} + +#endif + +void RemoteScrollingTree::scrollingTreeNodeDidScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, const std::optional<FloatPoint>& layoutViewportOrigin, ScrollingLayerPositionAction scrollingLayerPositionAction) +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeDidScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction); +} + +void RemoteScrollingTree::scrollingTreeNodeRequestsScroll(ScrollingNodeID nodeID, const FloatPoint& scrollPosition, bool representsProgrammaticScroll) +{ + m_scrollingCoordinatorProxy.scrollingTreeNodeRequestsScroll(nodeID, scrollPosition, representsProgrammaticScroll); +} + +Ref<ScrollingTreeNode> RemoteScrollingTree::createScrollingTreeNode(ScrollingNodeType nodeType, ScrollingNodeID nodeID) +{ + switch (nodeType) { + case FrameScrollingNode: +#if PLATFORM(IOS) + return ScrollingTreeFrameScrollingNodeIOS::create(*this, nodeID); +#else + return ScrollingTreeFrameScrollingNodeMac::create(*this, nodeID); +#endif + case OverflowScrollingNode: +#if PLATFORM(IOS) + return ScrollingTreeOverflowScrollingNodeIOS::create(*this, nodeID); +#else + ASSERT_NOT_REACHED(); + break; +#endif + case FixedNode: + return ScrollingTreeFixedNode::create(*this, nodeID); + case StickyNode: + return ScrollingTreeStickyNode::create(*this, nodeID); + } + ASSERT_NOT_REACHED(); + return ScrollingTreeFixedNode::create(*this, nodeID); +} + +void RemoteScrollingTree::currentSnapPointIndicesDidChange(ScrollingNodeID nodeID, unsigned horizontal, unsigned vertical) +{ + m_scrollingCoordinatorProxy.currentSnapPointIndicesDidChange(nodeID, horizontal, vertical); +} + +} // namespace WebKit + +#endif // ENABLE(ASYNC_SCROLLING) diff --git a/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h new file mode 100644 index 000000000..7318ccc81 --- /dev/null +++ b/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingTree.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef RemoteScrollingTree_h +#define RemoteScrollingTree_h + +#if ENABLE(ASYNC_SCROLLING) + +#include "RemoteScrollingCoordinator.h" +#include <WebCore/ScrollingConstraints.h> +#include <WebCore/ScrollingTree.h> + +namespace WebKit { + +class RemoteScrollingCoordinatorProxy; + +class RemoteScrollingTree final : public WebCore::ScrollingTree { +public: + static Ref<RemoteScrollingTree> create(RemoteScrollingCoordinatorProxy&); + virtual ~RemoteScrollingTree(); + + bool isRemoteScrollingTree() const override { return true; } + EventResult tryToHandleWheelEvent(const WebCore::PlatformWheelEvent&) override; + + const RemoteScrollingCoordinatorProxy& scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy; } + + void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, const std::optional<WebCore::FloatPoint>& layoutViewportOrigin, WebCore::ScrollingLayerPositionAction = WebCore::ScrollingLayerPositionAction::Sync) override; + void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll) override; + + void currentSnapPointIndicesDidChange(WebCore::ScrollingNodeID, unsigned horizontal, unsigned vertical) override; + +private: + explicit RemoteScrollingTree(RemoteScrollingCoordinatorProxy&); + +#if PLATFORM(MAC) + void handleWheelEventPhase(WebCore::PlatformWheelEventPhase) override; +#endif + +#if PLATFORM(IOS) + WebCore::FloatRect fixedPositionRect() override; + void scrollingTreeNodeWillStartPanGesture() override; + void scrollingTreeNodeWillStartScroll() override; + void scrollingTreeNodeDidEndScroll() override; +#endif + + Ref<WebCore::ScrollingTreeNode> createScrollingTreeNode(WebCore::ScrollingNodeType, WebCore::ScrollingNodeID) override; + + RemoteScrollingCoordinatorProxy& m_scrollingCoordinatorProxy; +}; + +} // namespace WebKit + +SPECIALIZE_TYPE_TRAITS_SCROLLING_TREE(WebKit::RemoteScrollingTree, isRemoteScrollingTree()); + +#endif // ENABLE(ASYNC_SCROLLING) + +#endif // RemoteScrollingTree_h diff --git a/Source/WebKit2/UIProcess/StatisticsRequest.cpp b/Source/WebKit2/UIProcess/StatisticsRequest.cpp index 3223da5fd..bf51d234b 100644 --- a/Source/WebKit2/UIProcess/StatisticsRequest.cpp +++ b/Source/WebKit2/UIProcess/StatisticsRequest.cpp @@ -27,7 +27,7 @@ #include "StatisticsRequest.h" #include "APIArray.h" -#include "MutableDictionary.h" +#include "APIDictionary.h" namespace WebKit { @@ -51,17 +51,17 @@ uint64_t StatisticsRequest::addOutstandingRequest() return requestID; } -static void addToDictionaryFromHashMap(MutableDictionary* dictionary, const HashMap<String, uint64_t>& map) +static void addToDictionaryFromHashMap(API::Dictionary* dictionary, const HashMap<String, uint64_t>& map) { HashMap<String, uint64_t>::const_iterator end = map.end(); for (HashMap<String, uint64_t>::const_iterator it = map.begin(); it != end; ++it) dictionary->set(it->key, RefPtr<API::UInt64>(API::UInt64::create(it->value)).get()); } -static PassRefPtr<MutableDictionary> createDictionaryFromHashMap(const HashMap<String, uint64_t>& map) +static Ref<API::Dictionary> createDictionaryFromHashMap(const HashMap<String, uint64_t>& map) { - RefPtr<MutableDictionary> result = MutableDictionary::create(); - addToDictionaryFromHashMap(result.get(), map); + Ref<API::Dictionary> result = API::Dictionary::create(); + addToDictionaryFromHashMap(result.ptr(), map); return result; } @@ -71,7 +71,7 @@ void StatisticsRequest::completedRequest(uint64_t requestID, const StatisticsDat m_outstandingRequests.remove(requestID); if (!m_responseDictionary) - m_responseDictionary = MutableDictionary::create(); + m_responseDictionary = API::Dictionary::create(); // FIXME (Multi-WebProcess) <rdar://problem/13200059>: This code overwrites any previous response data received. // When getting responses from multiple WebProcesses we need to combine items instead of clobbering them. @@ -79,9 +79,9 @@ void StatisticsRequest::completedRequest(uint64_t requestID, const StatisticsDat addToDictionaryFromHashMap(m_responseDictionary.get(), data.statisticsNumbers); if (!data.javaScriptProtectedObjectTypeCounts.isEmpty()) - m_responseDictionary->set("JavaScriptProtectedObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptProtectedObjectTypeCounts).get()); + m_responseDictionary->set("JavaScriptProtectedObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptProtectedObjectTypeCounts)); if (!data.javaScriptObjectTypeCounts.isEmpty()) - m_responseDictionary->set("JavaScriptObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptObjectTypeCounts).get()); + m_responseDictionary->set("JavaScriptObjectTypeCounts", createDictionaryFromHashMap(data.javaScriptObjectTypeCounts)); if (!data.webCoreCacheStatistics.isEmpty()) { Vector<RefPtr<API::Object>> cacheStatistics; @@ -90,12 +90,12 @@ void StatisticsRequest::completedRequest(uint64_t requestID, const StatisticsDat for (const auto& statistic : data.webCoreCacheStatistics) cacheStatistics.uncheckedAppend(createDictionaryFromHashMap(statistic)); - m_responseDictionary->set("WebCoreCacheStatistics", API::Array::create(std::move(cacheStatistics)).get()); + m_responseDictionary->set("WebCoreCacheStatistics", API::Array::create(WTFMove(cacheStatistics))); } if (m_outstandingRequests.isEmpty()) { m_callback->performCallbackWithReturnValue(m_responseDictionary.get()); - m_callback = 0; + m_callback = nullptr; } } diff --git a/Source/WebKit2/UIProcess/StatisticsRequest.h b/Source/WebKit2/UIProcess/StatisticsRequest.h index bf9c37bbe..c5f03c887 100644 --- a/Source/WebKit2/UIProcess/StatisticsRequest.h +++ b/Source/WebKit2/UIProcess/StatisticsRequest.h @@ -35,7 +35,7 @@ namespace WebKit { struct StatisticsData; -typedef GenericCallback<WKDictionaryRef> DictionaryCallback; +typedef GenericCallback<API::Dictionary*> DictionaryCallback; enum StatisticsRequestType { StatisticsRequestTypeWebContent = 0x00000001, @@ -61,7 +61,7 @@ private: HashSet<uint64_t> m_outstandingRequests; RefPtr<DictionaryCallback> m_callback; - RefPtr<MutableDictionary> m_responseDictionary; + RefPtr<API::Dictionary> m_responseDictionary; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.cpp b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.cpp index 2595f074b..67ecb8945 100644 --- a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.cpp +++ b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.cpp @@ -27,13 +27,14 @@ #include "LocalStorageDatabase.h" #include "LocalStorageDatabaseTracker.h" -#include "WorkQueue.h" #include <WebCore/FileSystem.h> #include <WebCore/SQLiteStatement.h> #include <WebCore/SQLiteTransaction.h> #include <WebCore/SecurityOrigin.h> #include <WebCore/StorageMap.h> +#include <WebCore/SuddenTermination.h> #include <wtf/PassRefPtr.h> +#include <wtf/WorkQueue.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> @@ -45,16 +46,16 @@ static const int maximumItemsToUpdate = 100; namespace WebKit { -PassRefPtr<LocalStorageDatabase> LocalStorageDatabase::create(PassRefPtr<WorkQueue> queue, PassRefPtr<LocalStorageDatabaseTracker> tracker, PassRefPtr<SecurityOrigin> securityOrigin) +Ref<LocalStorageDatabase> LocalStorageDatabase::create(Ref<WorkQueue>&& queue, Ref<LocalStorageDatabaseTracker>&& tracker, const SecurityOriginData& securityOrigin) { - return adoptRef(new LocalStorageDatabase(queue, tracker, securityOrigin)); + return adoptRef(*new LocalStorageDatabase(WTFMove(queue), WTFMove(tracker), securityOrigin)); } -LocalStorageDatabase::LocalStorageDatabase(PassRefPtr<WorkQueue> queue, PassRefPtr<LocalStorageDatabaseTracker> tracker, PassRefPtr<SecurityOrigin> securityOrigin) - : m_queue(queue) - , m_tracker(tracker) +LocalStorageDatabase::LocalStorageDatabase(Ref<WorkQueue>&& queue, Ref<LocalStorageDatabaseTracker>&& tracker, const SecurityOriginData& securityOrigin) + : m_queue(WTFMove(queue)) + , m_tracker(WTFMove(tracker)) , m_securityOrigin(securityOrigin) - , m_databasePath(m_tracker->databasePath(m_securityOrigin.get())) + , m_databasePath(m_tracker->databasePath(m_securityOrigin)) , m_failedToOpenDatabase(false) , m_didImportItems(false) , m_isClosed(false) @@ -79,7 +80,7 @@ void LocalStorageDatabase::openDatabase(DatabaseOpeningStrategy openingStrategy) } if (m_database.isOpen()) - m_tracker->didOpenDatabaseWithOrigin(m_securityOrigin.get()); + m_tracker->didOpenDatabaseWithOrigin(m_securityOrigin); } bool LocalStorageDatabase::tryToOpenDatabase(DatabaseOpeningStrategy openingStrategy) @@ -171,7 +172,7 @@ void LocalStorageDatabase::importItems(StorageMap& storageMap) return; SQLiteStatement query(m_database, "SELECT key, value FROM ItemTable"); - if (query.prepare() != SQLResultOk) { + if (query.prepare() != SQLITE_OK) { LOG_ERROR("Unable to select items from ItemTable for local storage"); return; } @@ -179,12 +180,15 @@ void LocalStorageDatabase::importItems(StorageMap& storageMap) HashMap<String, String> items; int result = query.step(); - while (result == SQLResultRow) { - items.set(query.getColumnText(0), query.getColumnBlobAsString(1)); + while (result == SQLITE_ROW) { + String key = query.getColumnText(0); + String value = query.getColumnBlobAsString(1); + if (!key.isNull() && !value.isNull()) + items.set(key, value); result = query.step(); } - if (result != SQLResultDone) { + if (result != SQLITE_DONE) { LOG_ERROR("Error reading items from ItemTable for local storage"); return; } @@ -226,7 +230,7 @@ void LocalStorageDatabase::close() m_database.close(); if (isEmpty) - m_tracker->deleteDatabaseWithOrigin(m_securityOrigin.get()); + m_tracker->deleteDatabaseWithOrigin(m_securityOrigin); } void LocalStorageDatabase::itemDidChange(const String& key, const String& value) @@ -240,8 +244,15 @@ void LocalStorageDatabase::scheduleDatabaseUpdate() if (m_didScheduleDatabaseUpdate) return; + if (!m_disableSuddenTerminationWhileWritingToLocalStorage) + m_disableSuddenTerminationWhileWritingToLocalStorage = std::make_unique<SuddenTerminationDisabler>(); + m_didScheduleDatabaseUpdate = true; - m_queue->dispatchAfter(databaseUpdateInterval, bind(&LocalStorageDatabase::updateDatabase, this)); + + RefPtr<LocalStorageDatabase> localStorageDatabase(this); + m_queue->dispatchAfter(databaseUpdateInterval, [localStorageDatabase] { + localStorageDatabase->updateDatabase(); + }); } void LocalStorageDatabase::updateDatabase() @@ -256,6 +267,8 @@ void LocalStorageDatabase::updateDatabase() if (m_changedItems.size() <= maximumItemsToUpdate) { // There are few enough changed items that we can just always write all of them. m_changedItems.swap(changedItems); + updateDatabaseWithChangedItems(changedItems); + m_disableSuddenTerminationWhileWritingToLocalStorage = nullptr; } else { for (int i = 0; i < maximumItemsToUpdate; ++i) { auto it = m_changedItems.begin(); @@ -268,9 +281,8 @@ void LocalStorageDatabase::updateDatabase() // Reschedule the update for the remaining items. scheduleDatabaseUpdate(); + updateDatabaseWithChangedItems(changedItems); } - - updateDatabaseWithChangedItems(changedItems); } void LocalStorageDatabase::updateDatabaseWithChangedItems(const HashMap<String, String>& changedItems) @@ -284,26 +296,26 @@ void LocalStorageDatabase::updateDatabaseWithChangedItems(const HashMap<String, m_shouldClearItems = false; SQLiteStatement clearStatement(m_database, "DELETE FROM ItemTable"); - if (clearStatement.prepare() != SQLResultOk) { + if (clearStatement.prepare() != SQLITE_OK) { LOG_ERROR("Failed to prepare clear statement - cannot write to local storage database"); return; } int result = clearStatement.step(); - if (result != SQLResultDone) { + if (result != SQLITE_DONE) { LOG_ERROR("Failed to clear all items in the local storage database - %i", result); return; } } SQLiteStatement insertStatement(m_database, "INSERT INTO ItemTable VALUES (?, ?)"); - if (insertStatement.prepare() != SQLResultOk) { + if (insertStatement.prepare() != SQLITE_OK) { LOG_ERROR("Failed to prepare insert statement - cannot write to local storage database"); return; } SQLiteStatement deleteStatement(m_database, "DELETE FROM ItemTable WHERE key=?"); - if (deleteStatement.prepare() != SQLResultOk) { + if (deleteStatement.prepare() != SQLITE_OK) { LOG_ERROR("Failed to prepare delete statement - cannot write to local storage database"); return; } @@ -322,7 +334,7 @@ void LocalStorageDatabase::updateDatabaseWithChangedItems(const HashMap<String, statement.bindBlob(2, it->value); int result = statement.step(); - if (result != SQLResultDone) { + if (result != SQLITE_DONE) { LOG_ERROR("Failed to update item in the local storage database - %i", result); break; } @@ -339,13 +351,13 @@ bool LocalStorageDatabase::databaseIsEmpty() return false; SQLiteStatement query(m_database, "SELECT COUNT(*) FROM ItemTable"); - if (query.prepare() != SQLResultOk) { + if (query.prepare() != SQLITE_OK) { LOG_ERROR("Unable to count number of rows in ItemTable for local storage"); return false; } int result = query.step(); - if (result != SQLResultRow) { + if (result != SQLITE_ROW) { LOG_ERROR("No results when counting number of rows in ItemTable for local storage"); return false; } diff --git a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.h b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.h index 1acd6b253..9992031f4 100644 --- a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.h +++ b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabase.h @@ -23,20 +23,20 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LocalStorageDatabase_h -#define LocalStorageDatabase_h +#pragma once #include <WebCore/SQLiteDatabase.h> +#include <WebCore/SecurityOriginData.h> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/RefPtr.h> #include <wtf/ThreadSafeRefCounted.h> - -class WorkQueue; +#include <wtf/WorkQueue.h> namespace WebCore { class SecurityOrigin; class StorageMap; +class SuddenTerminationDisabler; } namespace WebKit { @@ -45,7 +45,7 @@ class LocalStorageDatabaseTracker; class LocalStorageDatabase : public ThreadSafeRefCounted<LocalStorageDatabase> { public: - static PassRefPtr<LocalStorageDatabase> create(PassRefPtr<WorkQueue>, PassRefPtr<LocalStorageDatabaseTracker>, PassRefPtr<WebCore::SecurityOrigin>); + static Ref<LocalStorageDatabase> create(Ref<WorkQueue>&&, Ref<LocalStorageDatabaseTracker>&&, const WebCore::SecurityOriginData&); ~LocalStorageDatabase(); // Will block until the import is complete. @@ -59,7 +59,7 @@ public: void close(); private: - LocalStorageDatabase(PassRefPtr<WorkQueue>, PassRefPtr<LocalStorageDatabaseTracker>, PassRefPtr<WebCore::SecurityOrigin>); + LocalStorageDatabase(Ref<WorkQueue>&&, Ref<LocalStorageDatabaseTracker>&&, const WebCore::SecurityOriginData&); enum DatabaseOpeningStrategy { CreateIfNonExistent, @@ -78,9 +78,9 @@ private: bool databaseIsEmpty(); - RefPtr<WorkQueue> m_queue; - RefPtr<LocalStorageDatabaseTracker> m_tracker; - RefPtr<WebCore::SecurityOrigin> m_securityOrigin; + Ref<WorkQueue> m_queue; + Ref<LocalStorageDatabaseTracker> m_tracker; + WebCore::SecurityOriginData m_securityOrigin; String m_databasePath; WebCore::SQLiteDatabase m_database; @@ -91,9 +91,9 @@ private: bool m_didScheduleDatabaseUpdate; bool m_shouldClearItems; HashMap<String, String> m_changedItems; + + std::unique_ptr<WebCore::SuddenTerminationDisabler> m_disableSuddenTerminationWhileWritingToLocalStorage; }; } // namespace WebKit - -#endif // LocalStorageDatabase_h diff --git a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.cpp b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.cpp index d0f771e7c..3e86b05ca 100644 --- a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.cpp +++ b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.cpp @@ -26,53 +26,56 @@ #include "config.h" #include "LocalStorageDatabaseTracker.h" -#include "WorkQueue.h" #include <WebCore/FileSystem.h> +#include <WebCore/SQLiteFileSystem.h> #include <WebCore/SQLiteStatement.h> #include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginData.h> +#include <WebCore/TextEncoding.h> +#include <wtf/MainThread.h> +#include <wtf/WorkQueue.h> #include <wtf/text/CString.h> using namespace WebCore; namespace WebKit { -PassRefPtr<LocalStorageDatabaseTracker> LocalStorageDatabaseTracker::create(PassRefPtr<WorkQueue> queue) +Ref<LocalStorageDatabaseTracker> LocalStorageDatabaseTracker::create(Ref<WorkQueue>&& queue, const String& localStorageDirectory) { - return adoptRef(new LocalStorageDatabaseTracker(queue)); + return adoptRef(*new LocalStorageDatabaseTracker(WTFMove(queue), localStorageDirectory)); } -LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(PassRefPtr<WorkQueue> queue) - : m_queue(queue) +LocalStorageDatabaseTracker::LocalStorageDatabaseTracker(Ref<WorkQueue>&& queue, const String& localStorageDirectory) + : m_queue(WTFMove(queue)) + , m_localStorageDirectory(localStorageDirectory.isolatedCopy()) { + ASSERT(!m_localStorageDirectory.isEmpty()); + + // Make sure the encoding is initialized before we start dispatching things to the queue. + UTF8Encoding(); + + m_queue->dispatch([protectedThis = makeRef(*this)]() mutable { + protectedThis->importOriginIdentifiers(); + }); } LocalStorageDatabaseTracker::~LocalStorageDatabaseTracker() { } -void LocalStorageDatabaseTracker::setLocalStorageDirectory(const String& localStorageDirectory) +String LocalStorageDatabaseTracker::databasePath(const SecurityOriginData& securityOrigin) const { - // FIXME: We should come up with a better idiom for safely copying strings across threads. - RefPtr<StringImpl> copiedLocalStorageDirectory; - if (localStorageDirectory.impl()) - copiedLocalStorageDirectory = localStorageDirectory.impl()->isolatedCopy(); - - m_queue->dispatch(bind(&LocalStorageDatabaseTracker::setLocalStorageDirectoryInternal, this, copiedLocalStorageDirectory.release())); + return databasePath(securityOrigin.databaseIdentifier() + ".localstorage"); } -String LocalStorageDatabaseTracker::databasePath(SecurityOrigin* securityOrigin) const +void LocalStorageDatabaseTracker::didOpenDatabaseWithOrigin(const SecurityOriginData& securityOrigin) { - return databasePath(securityOrigin->databaseIdentifier() + ".localstorage"); + addDatabaseWithOriginIdentifier(securityOrigin.databaseIdentifier(), databasePath(securityOrigin)); } -void LocalStorageDatabaseTracker::didOpenDatabaseWithOrigin(SecurityOrigin* securityOrigin) +void LocalStorageDatabaseTracker::deleteDatabaseWithOrigin(const SecurityOriginData& securityOrigin) { - addDatabaseWithOriginIdentifier(securityOrigin->databaseIdentifier(), databasePath(securityOrigin)); -} - -void LocalStorageDatabaseTracker::deleteDatabaseWithOrigin(SecurityOrigin* securityOrigin) -{ - removeDatabaseWithOriginIdentifier(securityOrigin->databaseIdentifier()); + removeDatabaseWithOriginIdentifier(securityOrigin.databaseIdentifier()); } void LocalStorageDatabaseTracker::deleteAllDatabases() @@ -84,19 +87,19 @@ void LocalStorageDatabaseTracker::deleteAllDatabases() return; SQLiteStatement statement(m_database, "SELECT origin, path FROM Origins"); - if (statement.prepare() != SQLResultOk) { + if (statement.prepare() != SQLITE_OK) { LOG_ERROR("Failed to prepare statement."); return; } int result; - while ((result = statement.step()) == SQLResultRow) { + while ((result = statement.step()) == SQLITE_ROW) { deleteFile(statement.getColumnText(1)); // FIXME: Call out to the client. } - if (result != SQLResultDone) + if (result != SQLITE_DONE) LOG_ERROR("Failed to read in all origins from the database."); if (m_database.isOpen()) @@ -110,7 +113,7 @@ void LocalStorageDatabaseTracker::deleteAllDatabases() return; SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins"); - if (deleteStatement.prepare() != SQLResultOk) { + if (deleteStatement.prepare() != SQLITE_OK) { LOG_ERROR("Unable to prepare deletion of all origins"); return; } @@ -123,35 +126,97 @@ void LocalStorageDatabaseTracker::deleteAllDatabases() deleteEmptyDirectory(m_localStorageDirectory); } -Vector<RefPtr<WebCore::SecurityOrigin>> LocalStorageDatabaseTracker::origins() const +static std::optional<time_t> fileCreationTime(const String& filePath) +{ + time_t time; + return getFileCreationTime(filePath, time) ? time : std::optional<time_t>(std::nullopt); +} + +static std::optional<time_t> fileModificationTime(const String& filePath) +{ + time_t time; + if (!getFileModificationTime(filePath, time)) + return std::nullopt; + + return time; +} + +Vector<SecurityOriginData> LocalStorageDatabaseTracker::deleteDatabasesModifiedSince(std::chrono::system_clock::time_point time) +{ + ASSERT(!isMainThread()); + importOriginIdentifiers(); + Vector<String> originIdentifiersToDelete; + + for (const String& origin : m_origins) { + String filePath = pathForDatabaseWithOriginIdentifier(origin); + + auto modificationTime = fileModificationTime(filePath); + if (!modificationTime) + continue; + + if (modificationTime.value() >= std::chrono::system_clock::to_time_t(time)) + originIdentifiersToDelete.append(origin); + } + + Vector<SecurityOriginData> deletedDatabaseOrigins; + deletedDatabaseOrigins.reserveInitialCapacity(originIdentifiersToDelete.size()); + + for (const auto& originIdentifier : originIdentifiersToDelete) { + removeDatabaseWithOriginIdentifier(originIdentifier); + + if (auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)) + deletedDatabaseOrigins.uncheckedAppend(*origin); + else + ASSERT_NOT_REACHED(); + } + + return deletedDatabaseOrigins; +} + +Vector<SecurityOriginData> LocalStorageDatabaseTracker::origins() const { - Vector<RefPtr<SecurityOrigin>> origins; + Vector<SecurityOriginData> origins; origins.reserveInitialCapacity(m_origins.size()); - for (HashSet<String>::const_iterator it = m_origins.begin(), end = m_origins.end(); it != end; ++it) - origins.uncheckedAppend(SecurityOrigin::createFromDatabaseIdentifier(*it)); + for (const String& originIdentifier : m_origins) { + if (auto origin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)) + origins.uncheckedAppend(*origin); + else + ASSERT_NOT_REACHED(); + } return origins; } -void LocalStorageDatabaseTracker::setLocalStorageDirectoryInternal(StringImpl* localStorageDirectory) +Vector<LocalStorageDatabaseTracker::OriginDetails> LocalStorageDatabaseTracker::originDetails() { - if (m_database.isOpen()) - m_database.close(); + Vector<OriginDetails> result; + result.reserveInitialCapacity(m_origins.size()); - m_localStorageDirectory = localStorageDirectory; - m_origins.clear(); + for (const String& origin : m_origins) { + String filePath = pathForDatabaseWithOriginIdentifier(origin); + + OriginDetails details; + details.originIdentifier = origin.isolatedCopy(); + details.creationTime = fileCreationTime(filePath); + details.modificationTime = fileModificationTime(filePath); + result.uncheckedAppend(details); + } - m_queue->dispatch(bind(&LocalStorageDatabaseTracker::importOriginIdentifiers, this)); + return result; } String LocalStorageDatabaseTracker::databasePath(const String& filename) const { if (!makeAllDirectories(m_localStorageDirectory)) { - LOG_ERROR("Unabled to create LocalStorage database path %s", m_localStorageDirectory.utf8().data()); + LOG_ERROR("Unable to create LocalStorage database path %s", m_localStorageDirectory.utf8().data()); return String(); } +#if PLATFORM(IOS) + platformMaybeExcludeFromBackup(); +#endif + return pathByAppendingComponent(m_localStorageDirectory, filename); } @@ -192,17 +257,17 @@ void LocalStorageDatabaseTracker::importOriginIdentifiers() if (m_database.isOpen()) { SQLiteStatement statement(m_database, "SELECT origin FROM Origins"); - if (statement.prepare() != SQLResultOk) { + if (statement.prepare() != SQLITE_OK) { LOG_ERROR("Failed to prepare statement."); return; } int result; - while ((result = statement.step()) == SQLResultRow) + while ((result = statement.step()) == SQLITE_ROW) m_origins.add(statement.getColumnText(0)); - if (result != SQLResultDone) { + if (result != SQLITE_DONE) { LOG_ERROR("Failed to read in all origins from the database."); return; } @@ -250,7 +315,7 @@ void LocalStorageDatabaseTracker::addDatabaseWithOriginIdentifier(const String& return; SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)"); - if (statement.prepare() != SQLResultOk) { + if (statement.prepare() != SQLITE_OK) { LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.utf8().data()); return; } @@ -258,7 +323,7 @@ void LocalStorageDatabaseTracker::addDatabaseWithOriginIdentifier(const String& statement.bindText(1, originIdentifier); statement.bindText(2, databasePath); - if (statement.step() != SQLResultDone) + if (statement.step() != SQLITE_DONE) LOG_ERROR("Unable to establish origin '%s' in the tracker", originIdentifier.utf8().data()); m_origins.add(originIdentifier); @@ -277,7 +342,7 @@ void LocalStorageDatabaseTracker::removeDatabaseWithOriginIdentifier(const Strin return; SQLiteStatement deleteStatement(m_database, "DELETE FROM Origins where origin=?"); - if (deleteStatement.prepare() != SQLResultOk) { + if (deleteStatement.prepare() != SQLITE_OK) { LOG_ERROR("Unable to prepare deletion of origin '%s'", originIdentifier.ascii().data()); return; } @@ -287,13 +352,13 @@ void LocalStorageDatabaseTracker::removeDatabaseWithOriginIdentifier(const Strin return; } - deleteFile(path); + SQLiteFileSystem::deleteDatabaseFile(path); m_origins.remove(originIdentifier); if (m_origins.isEmpty()) { - // There are no origins left, go ahead and delete the tracker database. + // There are no origins left; delete the tracker database. m_database.close(); - deleteFile(trackerDatabasePath()); + SQLiteFileSystem::deleteDatabaseFile(trackerDatabasePath()); deleteEmptyDirectory(m_localStorageDirectory); } @@ -306,7 +371,7 @@ String LocalStorageDatabaseTracker::pathForDatabaseWithOriginIdentifier(const St return String(); SQLiteStatement pathStatement(m_database, "SELECT path FROM Origins WHERE origin=?"); - if (pathStatement.prepare() != SQLResultOk) { + if (pathStatement.prepare() != SQLITE_OK) { LOG_ERROR("Unable to prepare selection of path for origin '%s'", originIdentifier.utf8().data()); return String(); } @@ -314,7 +379,7 @@ String LocalStorageDatabaseTracker::pathForDatabaseWithOriginIdentifier(const St pathStatement.bindText(1, originIdentifier); int result = pathStatement.step(); - if (result != SQLResultRow) + if (result != SQLITE_ROW) return String(); return pathStatement.getColumnText(0); diff --git a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.h b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.h index e16428907..7ceb1916d 100644 --- a/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.h +++ b/Source/WebKit2/UIProcess/Storage/LocalStorageDatabaseTracker.h @@ -23,43 +23,51 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LocalStorageDatabaseTracker_h -#define LocalStorageDatabaseTracker_h +#pragma once #include <WebCore/SQLiteDatabase.h> #include <wtf/HashSet.h> -#include <wtf/PassRefPtr.h> +#include <wtf/Optional.h> #include <wtf/RefPtr.h> #include <wtf/ThreadSafeRefCounted.h> +#include <wtf/WorkQueue.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> namespace WebCore { class SecurityOrigin; +struct SecurityOriginData; } -class WorkQueue; - namespace WebKit { +struct LocalStorageDetails; + class LocalStorageDatabaseTracker : public ThreadSafeRefCounted<LocalStorageDatabaseTracker> { public: - static PassRefPtr<LocalStorageDatabaseTracker> create(PassRefPtr<WorkQueue>); + static Ref<LocalStorageDatabaseTracker> create(Ref<WorkQueue>&&, const String& localStorageDirectory); ~LocalStorageDatabaseTracker(); - void setLocalStorageDirectory(const String&); - String databasePath(WebCore::SecurityOrigin*) const; + String databasePath(const WebCore::SecurityOriginData&) const; - void didOpenDatabaseWithOrigin(WebCore::SecurityOrigin*); - void deleteDatabaseWithOrigin(WebCore::SecurityOrigin*); + void didOpenDatabaseWithOrigin(const WebCore::SecurityOriginData&); + void deleteDatabaseWithOrigin(const WebCore::SecurityOriginData&); void deleteAllDatabases(); - Vector<RefPtr<WebCore::SecurityOrigin>> origins() const; + // Returns a vector of the origins whose databases have been deleted. + Vector<WebCore::SecurityOriginData> deleteDatabasesModifiedSince(std::chrono::system_clock::time_point); -private: - explicit LocalStorageDatabaseTracker(PassRefPtr<WorkQueue>); + Vector<WebCore::SecurityOriginData> origins() const; - void setLocalStorageDirectoryInternal(StringImpl*); + struct OriginDetails { + String originIdentifier; + std::optional<time_t> creationTime; + std::optional<time_t> modificationTime; + }; + Vector<OriginDetails> originDetails(); + +private: + LocalStorageDatabaseTracker(Ref<WorkQueue>&&, const String& localStorageDirectory); String databasePath(const String& filename) const; String trackerDatabasePath() const; @@ -82,8 +90,12 @@ private: WebCore::SQLiteDatabase m_database; HashSet<String> m_origins; + +#if PLATFORM(IOS) + void platformMaybeExcludeFromBackup() const; + + mutable bool m_hasExcludedFromBackup { false }; +#endif }; } // namespace WebKit - -#endif // LocalStorageDatabaseTracker_h diff --git a/Source/WebKit2/UIProcess/Storage/StorageManager.cpp b/Source/WebKit2/UIProcess/Storage/StorageManager.cpp index c08acc4ad..5803e2cb3 100644 --- a/Source/WebKit2/UIProcess/Storage/StorageManager.cpp +++ b/Source/WebKit2/UIProcess/Storage/StorageManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,14 +28,16 @@ #include "LocalStorageDatabase.h" #include "LocalStorageDatabaseTracker.h" -#include "SecurityOriginData.h" #include "StorageAreaMapMessages.h" #include "StorageManagerMessages.h" #include "WebProcessProxy.h" -#include "WorkQueue.h" +#include <WebCore/SecurityOriginData.h> #include <WebCore/SecurityOriginHash.h> #include <WebCore/StorageMap.h> #include <WebCore/TextEncoding.h> +#include <memory> +#include <wtf/WorkQueue.h> +#include <wtf/threads/BinarySemaphore.h> using namespace WebCore; @@ -43,36 +45,38 @@ namespace WebKit { class StorageManager::StorageArea : public ThreadSafeRefCounted<StorageManager::StorageArea> { public: - static PassRefPtr<StorageArea> create(LocalStorageNamespace*, PassRefPtr<SecurityOrigin>, unsigned quotaInBytes); + static Ref<StorageArea> create(LocalStorageNamespace*, const SecurityOriginData&, unsigned quotaInBytes); ~StorageArea(); - SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } + const WebCore::SecurityOriginData& securityOrigin() const { return m_securityOrigin; } - void addListener(IPC::Connection*, uint64_t storageMapID); - void removeListener(IPC::Connection*, uint64_t storageMapID); + void addListener(IPC::Connection&, uint64_t storageMapID); + void removeListener(IPC::Connection&, uint64_t storageMapID); - PassRefPtr<StorageArea> clone() const; + Ref<StorageArea> clone() const; void setItem(IPC::Connection* sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& value, const String& urlString, bool& quotaException); void removeItem(IPC::Connection* sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& urlString); void clear(IPC::Connection* sourceConnection, uint64_t sourceStorageAreaID, const String& urlString); - const HashMap<String, String>& items(); + const HashMap<String, String>& items() const; void clear(); + bool isSessionStorage() const { return !m_localStorageNamespace; } + private: - explicit StorageArea(LocalStorageNamespace*, PassRefPtr<SecurityOrigin>, unsigned quotaInBytes); + explicit StorageArea(LocalStorageNamespace*, const SecurityOriginData&, unsigned quotaInBytes); - void openDatabaseAndImportItemsIfNeeded(); + void openDatabaseAndImportItemsIfNeeded() const; void dispatchEvents(IPC::Connection* sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& oldValue, const String& newValue, const String& urlString) const; // Will be null if the storage area belongs to a session storage namespace. LocalStorageNamespace* m_localStorageNamespace; - RefPtr<LocalStorageDatabase> m_localStorageDatabase; - bool m_didImportItemsFromDatabase; + mutable RefPtr<LocalStorageDatabase> m_localStorageDatabase; + mutable bool m_didImportItemsFromDatabase { false }; - RefPtr<SecurityOrigin> m_securityOrigin; + SecurityOriginData m_securityOrigin; unsigned m_quotaInBytes; RefPtr<StorageMap> m_storageMap; @@ -81,15 +85,15 @@ private: class StorageManager::LocalStorageNamespace : public ThreadSafeRefCounted<LocalStorageNamespace> { public: - static PassRefPtr<LocalStorageNamespace> create(StorageManager*, uint64_t storageManagerID); + static Ref<LocalStorageNamespace> create(StorageManager*, uint64_t storageManagerID); ~LocalStorageNamespace(); StorageManager* storageManager() const { return m_storageManager; } - PassRefPtr<StorageArea> getOrCreateStorageArea(PassRefPtr<SecurityOrigin>); + Ref<StorageArea> getOrCreateStorageArea(SecurityOriginData&&); void didDestroyStorageArea(StorageArea*); - void clearStorageAreasMatchingOrigin(SecurityOrigin*); + void clearStorageAreasMatchingOrigin(const SecurityOriginData&); void clearAllStorageAreas(); private: @@ -100,17 +104,70 @@ private: unsigned m_quotaInBytes; // We don't hold an explicit reference to the StorageAreas; they are kept alive by the m_storageAreasByConnection map in StorageManager. - HashMap<RefPtr<SecurityOrigin>, StorageArea*> m_storageAreaMap; + HashMap<SecurityOriginData, StorageArea*> m_storageAreaMap; +}; + +class StorageManager::TransientLocalStorageNamespace : public ThreadSafeRefCounted<TransientLocalStorageNamespace> { +public: + static Ref<TransientLocalStorageNamespace> create() + { + return adoptRef(*new TransientLocalStorageNamespace()); + } + + ~TransientLocalStorageNamespace() + { + } + + Ref<StorageArea> getOrCreateStorageArea(SecurityOriginData&& securityOrigin) + { + return *m_storageAreaMap.ensure(securityOrigin, [this, securityOrigin]() mutable { + return StorageArea::create(nullptr, WTFMove(securityOrigin), m_quotaInBytes); + }).iterator->value.copyRef(); + } + + Vector<SecurityOriginData> origins() const + { + Vector<SecurityOriginData> origins; + + for (const auto& storageArea : m_storageAreaMap.values()) { + if (!storageArea->items().isEmpty()) + origins.append(storageArea->securityOrigin()); + } + + return origins; + } + + void clearStorageAreasMatchingOrigin(const SecurityOriginData& securityOrigin) + { + for (auto& storageArea : m_storageAreaMap.values()) { + if (storageArea->securityOrigin() == securityOrigin) + storageArea->clear(); + } + } + + void clearAllStorageAreas() + { + for (auto& storageArea : m_storageAreaMap.values()) + storageArea->clear(); + } + +private: + explicit TransientLocalStorageNamespace() + { + } + + const unsigned m_quotaInBytes = 5 * 1024 * 1024; + + HashMap<SecurityOriginData, RefPtr<StorageArea>> m_storageAreaMap; }; -PassRefPtr<StorageManager::StorageArea> StorageManager::StorageArea::create(LocalStorageNamespace* localStorageNamespace, PassRefPtr<SecurityOrigin> securityOrigin, unsigned quotaInBytes) +auto StorageManager::StorageArea::create(LocalStorageNamespace* localStorageNamespace, const SecurityOriginData& securityOrigin, unsigned quotaInBytes) -> Ref<StorageManager::StorageArea> { - return adoptRef(new StorageArea(localStorageNamespace, securityOrigin, quotaInBytes)); + return adoptRef(*new StorageArea(localStorageNamespace, securityOrigin, quotaInBytes)); } -StorageManager::StorageArea::StorageArea(LocalStorageNamespace* localStorageNamespace, PassRefPtr<SecurityOrigin> securityOrigin, unsigned quotaInBytes) +StorageManager::StorageArea::StorageArea(LocalStorageNamespace* localStorageNamespace, const SecurityOriginData& securityOrigin, unsigned quotaInBytes) : m_localStorageNamespace(localStorageNamespace) - , m_didImportItemsFromDatabase(false) , m_securityOrigin(securityOrigin) , m_quotaInBytes(quotaInBytes) , m_storageMap(StorageMap::create(m_quotaInBytes)) @@ -128,26 +185,26 @@ StorageManager::StorageArea::~StorageArea() m_localStorageNamespace->didDestroyStorageArea(this); } -void StorageManager::StorageArea::addListener(IPC::Connection* connection, uint64_t storageMapID) +void StorageManager::StorageArea::addListener(IPC::Connection& connection, uint64_t storageMapID) { - ASSERT(!m_eventListeners.contains(std::make_pair(connection, storageMapID))); - m_eventListeners.add(std::make_pair(connection, storageMapID)); + ASSERT(!m_eventListeners.contains(std::make_pair(&connection, storageMapID))); + m_eventListeners.add(std::make_pair(&connection, storageMapID)); } -void StorageManager::StorageArea::removeListener(IPC::Connection* connection, uint64_t storageMapID) +void StorageManager::StorageArea::removeListener(IPC::Connection& connection, uint64_t storageMapID) { - ASSERT(m_eventListeners.contains(std::make_pair(connection, storageMapID))); - m_eventListeners.remove(std::make_pair(connection, storageMapID)); + ASSERT(isSessionStorage() || m_eventListeners.contains(std::make_pair(&connection, storageMapID))); + m_eventListeners.remove(std::make_pair(&connection, storageMapID)); } -PassRefPtr<StorageManager::StorageArea> StorageManager::StorageArea::clone() const +Ref<StorageManager::StorageArea> StorageManager::StorageArea::clone() const { ASSERT(!m_localStorageNamespace); - RefPtr<StorageArea> storageArea = StorageArea::create(0, m_securityOrigin, m_quotaInBytes); + auto storageArea = StorageArea::create(nullptr, m_securityOrigin, m_quotaInBytes); storageArea->m_storageMap = m_storageMap; - return storageArea.release(); + return storageArea; } void StorageManager::StorageArea::setItem(IPC::Connection* sourceConnection, uint64_t sourceStorageAreaID, const String& key, const String& value, const String& urlString, bool& quotaException) @@ -156,9 +213,9 @@ void StorageManager::StorageArea::setItem(IPC::Connection* sourceConnection, uin String oldValue; - RefPtr<StorageMap> newStorageMap = m_storageMap->setItem(key, value, oldValue, quotaException); + auto newStorageMap = m_storageMap->setItem(key, value, oldValue, quotaException); if (newStorageMap) - m_storageMap = newStorageMap.release(); + m_storageMap = WTFMove(newStorageMap); if (quotaException) return; @@ -174,9 +231,9 @@ void StorageManager::StorageArea::removeItem(IPC::Connection* sourceConnection, openDatabaseAndImportItemsIfNeeded(); String oldValue; - RefPtr<StorageMap> newStorageMap = m_storageMap->removeItem(key, oldValue); + auto newStorageMap = m_storageMap->removeItem(key, oldValue); if (newStorageMap) - m_storageMap = newStorageMap.release(); + m_storageMap = WTFMove(newStorageMap); if (oldValue.isNull()) return; @@ -202,7 +259,7 @@ void StorageManager::StorageArea::clear(IPC::Connection* sourceConnection, uint6 dispatchEvents(sourceConnection, sourceStorageAreaID, String(), String(), String(), urlString); } -const HashMap<String, String>& StorageManager::StorageArea::items() +const HashMap<String, String>& StorageManager::StorageArea::items() const { openDatabaseAndImportItemsIfNeeded(); @@ -222,14 +279,14 @@ void StorageManager::StorageArea::clear() it->first->send(Messages::StorageAreaMap::ClearCache(), it->second); } -void StorageManager::StorageArea::openDatabaseAndImportItemsIfNeeded() +void StorageManager::StorageArea::openDatabaseAndImportItemsIfNeeded() const { if (!m_localStorageNamespace) return; // We open the database here even if we've already imported our items to ensure that the database is open if we need to write to it. if (!m_localStorageDatabase) - m_localStorageDatabase = LocalStorageDatabase::create(m_localStorageNamespace->storageManager()->m_queue, m_localStorageNamespace->storageManager()->m_localStorageDatabaseTracker, m_securityOrigin.get()); + m_localStorageDatabase = LocalStorageDatabase::create(m_localStorageNamespace->storageManager()->m_queue.copyRef(), m_localStorageNamespace->storageManager()->m_localStorageDatabaseTracker.copyRef(), m_securityOrigin); if (m_didImportItemsFromDatabase) return; @@ -247,9 +304,9 @@ void StorageManager::StorageArea::dispatchEvents(IPC::Connection* sourceConnecti } } -PassRefPtr<StorageManager::LocalStorageNamespace> StorageManager::LocalStorageNamespace::create(StorageManager* storageManager, uint64_t storageNamespaceID) +Ref<StorageManager::LocalStorageNamespace> StorageManager::LocalStorageNamespace::create(StorageManager* storageManager, uint64_t storageNamespaceID) { - return adoptRef(new LocalStorageNamespace(storageManager, storageNamespaceID)); + return adoptRef(*new LocalStorageNamespace(storageManager, storageNamespaceID)); } // FIXME: The quota value is copied from GroupSettings.cpp. @@ -266,16 +323,16 @@ StorageManager::LocalStorageNamespace::~LocalStorageNamespace() ASSERT(m_storageAreaMap.isEmpty()); } -PassRefPtr<StorageManager::StorageArea> StorageManager::LocalStorageNamespace::getOrCreateStorageArea(PassRefPtr<SecurityOrigin> securityOrigin) +auto StorageManager::LocalStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin) -> Ref<StorageArea> { - auto result = m_storageAreaMap.add(securityOrigin, nullptr); - if (!result.isNewEntry) - return result.iterator->value; + auto& slot = m_storageAreaMap.add(securityOrigin, nullptr).iterator->value; + if (slot) + return *slot; - RefPtr<StorageArea> storageArea = StorageArea::create(this, result.iterator->key, m_quotaInBytes); - result.iterator->value = storageArea.get(); + auto storageArea = StorageArea::create(this, WTFMove(securityOrigin), m_quotaInBytes); + slot = &storageArea.get(); - return storageArea.release(); + return storageArea; } void StorageManager::LocalStorageNamespace::didDestroyStorageArea(StorageArea* storageArea) @@ -290,23 +347,23 @@ void StorageManager::LocalStorageNamespace::didDestroyStorageArea(StorageArea* s m_storageManager->m_localStorageNamespaces.remove(m_storageNamespaceID); } -void StorageManager::LocalStorageNamespace::clearStorageAreasMatchingOrigin(SecurityOrigin* securityOrigin) +void StorageManager::LocalStorageNamespace::clearStorageAreasMatchingOrigin(const SecurityOriginData& securityOrigin) { - for (auto it = m_storageAreaMap.begin(), end = m_storageAreaMap.end(); it != end; ++it) { - if (it->key->equal(securityOrigin)) - it->value->clear(); + for (const auto& originAndStorageArea : m_storageAreaMap) { + if (originAndStorageArea.key == securityOrigin) + originAndStorageArea.value->clear(); } } void StorageManager::LocalStorageNamespace::clearAllStorageAreas() { - for (auto it = m_storageAreaMap.begin(), end = m_storageAreaMap.end(); it != end; ++it) - it->value->clear(); + for (auto* storageArea : m_storageAreaMap.values()) + storageArea->clear(); } class StorageManager::SessionStorageNamespace : public ThreadSafeRefCounted<SessionStorageNamespace> { public: - static PassRefPtr<SessionStorageNamespace> create(IPC::Connection* allowedConnection, unsigned quotaInBytes); + static Ref<SessionStorageNamespace> create(unsigned quotaInBytes); ~SessionStorageNamespace(); bool isEmpty() const { return m_storageAreaMap.isEmpty(); } @@ -314,27 +371,52 @@ public: IPC::Connection* allowedConnection() const { return m_allowedConnection.get(); } void setAllowedConnection(IPC::Connection*); - PassRefPtr<StorageArea> getOrCreateStorageArea(PassRefPtr<SecurityOrigin>); + Ref<StorageArea> getOrCreateStorageArea(SecurityOriginData&&); void cloneTo(SessionStorageNamespace& newSessionStorageNamespace); + Vector<SecurityOriginData> origins() const + { + Vector<SecurityOriginData> origins; + + for (const auto& storageArea : m_storageAreaMap.values()) { + if (!storageArea->items().isEmpty()) + origins.append(storageArea->securityOrigin()); + } + + return origins; + } + + void clearStorageAreasMatchingOrigin(const SecurityOriginData& securityOrigin) + { + for (auto& storageArea : m_storageAreaMap.values()) { + if (storageArea->securityOrigin() == securityOrigin) + storageArea->clear(); + } + } + + void clearAllStorageAreas() + { + for (auto& storageArea : m_storageAreaMap.values()) + storageArea->clear(); + } + private: - SessionStorageNamespace(IPC::Connection* allowedConnection, unsigned quotaInBytes); + explicit SessionStorageNamespace(unsigned quotaInBytes); RefPtr<IPC::Connection> m_allowedConnection; unsigned m_quotaInBytes; - HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>> m_storageAreaMap; + HashMap<SecurityOriginData, RefPtr<StorageArea>> m_storageAreaMap; }; -PassRefPtr<StorageManager::SessionStorageNamespace> StorageManager::SessionStorageNamespace::create(IPC::Connection* allowedConnection, unsigned quotaInBytes) +Ref<StorageManager::SessionStorageNamespace> StorageManager::SessionStorageNamespace::create(unsigned quotaInBytes) { - return adoptRef(new SessionStorageNamespace(allowedConnection, quotaInBytes)); + return adoptRef(*new SessionStorageNamespace(quotaInBytes)); } -StorageManager::SessionStorageNamespace::SessionStorageNamespace(IPC::Connection* allowedConnection, unsigned quotaInBytes) - : m_allowedConnection(allowedConnection) - , m_quotaInBytes(quotaInBytes) +StorageManager::SessionStorageNamespace::SessionStorageNamespace(unsigned quotaInBytes) + : m_quotaInBytes(quotaInBytes) { } @@ -349,31 +431,29 @@ void StorageManager::SessionStorageNamespace::setAllowedConnection(IPC::Connecti m_allowedConnection = allowedConnection; } -PassRefPtr<StorageManager::StorageArea> StorageManager::SessionStorageNamespace::getOrCreateStorageArea(PassRefPtr<SecurityOrigin> securityOrigin) +auto StorageManager::SessionStorageNamespace::getOrCreateStorageArea(SecurityOriginData&& securityOrigin) -> Ref<StorageArea> { - auto result = m_storageAreaMap.add(securityOrigin, nullptr); - if (result.isNewEntry) - result.iterator->value = StorageArea::create(0, result.iterator->key, m_quotaInBytes); - - return result.iterator->value; + return *m_storageAreaMap.ensure(securityOrigin, [this, securityOrigin]() mutable { + return StorageArea::create(nullptr, WTFMove(securityOrigin), m_quotaInBytes); + }).iterator->value.copyRef(); } void StorageManager::SessionStorageNamespace::cloneTo(SessionStorageNamespace& newSessionStorageNamespace) { ASSERT_UNUSED(newSessionStorageNamespace, newSessionStorageNamespace.isEmpty()); - for (HashMap<RefPtr<SecurityOrigin>, RefPtr<StorageArea>>::const_iterator it = m_storageAreaMap.begin(), end = m_storageAreaMap.end(); it != end; ++it) - newSessionStorageNamespace.m_storageAreaMap.add(it->key, it->value->clone()); + for (auto& pair : m_storageAreaMap) + newSessionStorageNamespace.m_storageAreaMap.add(pair.key, pair.value->clone()); } -PassRefPtr<StorageManager> StorageManager::create() +Ref<StorageManager> StorageManager::create(const String& localStorageDirectory) { - return adoptRef(new StorageManager); + return adoptRef(*new StorageManager(localStorageDirectory)); } -StorageManager::StorageManager() +StorageManager::StorageManager(const String& localStorageDirectory) : m_queue(WorkQueue::create("com.apple.WebKit.StorageManager")) - , m_localStorageDatabaseTracker(LocalStorageDatabaseTracker::create(m_queue)) + , m_localStorageDatabaseTracker(LocalStorageDatabaseTracker::create(m_queue.copyRef(), localStorageDirectory)) { // Make sure the encoding is initialized before we start dispatching things to the queue. UTF8Encoding(); @@ -383,61 +463,204 @@ StorageManager::~StorageManager() { } -void StorageManager::setLocalStorageDirectory(const String& localStorageDirectory) +void StorageManager::createSessionStorageNamespace(uint64_t storageNamespaceID, unsigned quotaInBytes) { - m_localStorageDatabaseTracker->setLocalStorageDirectory(localStorageDirectory); -} + m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID, quotaInBytes]() mutable { + ASSERT(!m_sessionStorageNamespaces.contains(storageNamespaceID)); -void StorageManager::createSessionStorageNamespace(uint64_t storageNamespaceID, IPC::Connection* allowedConnection, unsigned quotaInBytes) -{ - m_queue->dispatch(bind(&StorageManager::createSessionStorageNamespaceInternal, this, storageNamespaceID, RefPtr<IPC::Connection>(allowedConnection), quotaInBytes)); + m_sessionStorageNamespaces.set(storageNamespaceID, SessionStorageNamespace::create(quotaInBytes)); + }); } void StorageManager::destroySessionStorageNamespace(uint64_t storageNamespaceID) { - m_queue->dispatch(bind(&StorageManager::destroySessionStorageNamespaceInternal, this, storageNamespaceID)); + m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID] { + ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID)); + m_sessionStorageNamespaces.remove(storageNamespaceID); + }); } void StorageManager::setAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection* allowedConnection) { - m_queue->dispatch(bind(&StorageManager::setAllowedSessionStorageNamespaceConnectionInternal, this, storageNamespaceID, RefPtr<IPC::Connection>(allowedConnection))); + m_queue->dispatch([this, protectedThis = makeRef(*this), connection = RefPtr<IPC::Connection>(allowedConnection), storageNamespaceID]() mutable { + ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID)); + + m_sessionStorageNamespaces.get(storageNamespaceID)->setAllowedConnection(connection.get()); + }); } void StorageManager::cloneSessionStorageNamespace(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID) { - m_queue->dispatch(bind(&StorageManager::cloneSessionStorageNamespaceInternal, this, storageNamespaceID, newStorageNamespaceID)); + m_queue->dispatch([this, protectedThis = makeRef(*this), storageNamespaceID, newStorageNamespaceID] { + SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID); + if (!sessionStorageNamespace) { + // FIXME: We can get into this situation if someone closes the originating page from within a + // createNewPage callback. We bail for now, but we should really find a way to keep the session storage alive + // so we we'll clone the session storage correctly. + return; + } + + SessionStorageNamespace* newSessionStorageNamespace = m_sessionStorageNamespaces.get(newStorageNamespaceID); + ASSERT(newSessionStorageNamespace); + + sessionStorageNamespace->cloneTo(*newSessionStorageNamespace); + }); +} + +void StorageManager::processWillOpenConnection(WebProcessProxy&, IPC::Connection& connection) +{ + connection.addWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName(), m_queue.get(), this); +} + +void StorageManager::processDidCloseConnection(WebProcessProxy&, IPC::Connection& connection) +{ + connection.removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName()); + + m_queue->dispatch([this, protectedThis = makeRef(*this), connection = Ref<IPC::Connection>(connection)]() mutable { + Vector<std::pair<RefPtr<IPC::Connection>, uint64_t>> connectionAndStorageMapIDPairsToRemove; + for (auto& storageArea : m_storageAreasByConnection) { + if (storageArea.key.first != connection.ptr()) + continue; + + storageArea.value->removeListener(*storageArea.key.first, storageArea.key.second); + connectionAndStorageMapIDPairsToRemove.append(storageArea.key); + } + + for (auto& pair : connectionAndStorageMapIDPairsToRemove) + m_storageAreasByConnection.remove(pair); + }); +} + +void StorageManager::getSessionStorageOrigins(std::function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler) +{ + m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable { + HashSet<SecurityOriginData> origins; + + for (const auto& sessionStorageNamespace : m_sessionStorageNamespaces.values()) { + for (auto& origin : sessionStorageNamespace->origins()) + origins.add(origin); + } + + RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable { + completionHandler(WTFMove(origins)); + }); + }); +} + +void StorageManager::deleteSessionStorageOrigins(std::function<void()>&& completionHandler) +{ + m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable { + for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values()) + sessionStorageNamespace->clearAllStorageAreas(); + + RunLoop::main().dispatch(WTFMove(completionHandler)); + }); +} + +void StorageManager::deleteSessionStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>& origins, std::function<void()>&& completionHandler) +{ + Vector<WebCore::SecurityOriginData> copiedOrigins; + copiedOrigins.reserveInitialCapacity(origins.size()); + + for (auto& origin : origins) + copiedOrigins.uncheckedAppend(origin.isolatedCopy()); + + m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigins = WTFMove(copiedOrigins), completionHandler = WTFMove(completionHandler)]() mutable { + for (auto& origin : copiedOrigins) { + for (auto& sessionStorageNamespace : m_sessionStorageNamespaces.values()) + sessionStorageNamespace->clearStorageAreasMatchingOrigin(origin); + } + + RunLoop::main().dispatch(WTFMove(completionHandler)); + }); } -void StorageManager::processWillOpenConnection(WebProcessProxy* webProcessProxy) +void StorageManager::getLocalStorageOrigins(std::function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler) { - webProcessProxy->connection()->addWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName(), m_queue.get(), this); + m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable { + HashSet<SecurityOriginData> origins; + + for (auto& origin : m_localStorageDatabaseTracker->origins()) + origins.add(origin); + + for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) { + for (auto& origin : transientLocalStorageNamespace->origins()) + origins.add(origin); + } + + RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable { + completionHandler(WTFMove(origins)); + }); + }); } -void StorageManager::processWillCloseConnection(WebProcessProxy* webProcessProxy) +void StorageManager::getLocalStorageOriginDetails(std::function<void (Vector<LocalStorageDatabaseTracker::OriginDetails>)>&& completionHandler) { - webProcessProxy->connection()->removeWorkQueueMessageReceiver(Messages::StorageManager::messageReceiverName()); + m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable { + auto originDetails = m_localStorageDatabaseTracker->originDetails(); - m_queue->dispatch(bind(&StorageManager::invalidateConnectionInternal, this, RefPtr<IPC::Connection>(webProcessProxy->connection()))); + RunLoop::main().dispatch([originDetails = WTFMove(originDetails), completionHandler = WTFMove(completionHandler)]() mutable { + completionHandler(WTFMove(originDetails)); + }); + }); } -void StorageManager::getOrigins(FunctionDispatcher* callbackDispatcher, void* context, void (*callback)(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context)) +void StorageManager::deleteLocalStorageEntriesForOrigin(SecurityOriginData&& securityOrigin) { - m_queue->dispatch(bind(&StorageManager::getOriginsInternal, this, RefPtr<FunctionDispatcher>(callbackDispatcher), context, callback)); + m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigin = securityOrigin.isolatedCopy()]() mutable { + for (auto& localStorageNamespace : m_localStorageNamespaces.values()) + localStorageNamespace->clearStorageAreasMatchingOrigin(copiedOrigin); + + for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) + transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(copiedOrigin); + + m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(copiedOrigin); + }); } -void StorageManager::deleteEntriesForOrigin(SecurityOrigin* securityOrigin) +void StorageManager::deleteLocalStorageOriginsModifiedSince(std::chrono::system_clock::time_point time, std::function<void()>&& completionHandler) { - m_queue->dispatch(bind(&StorageManager::deleteEntriesForOriginInternal, this, RefPtr<SecurityOrigin>(securityOrigin))); + m_queue->dispatch([this, protectedThis = makeRef(*this), time, completionHandler = WTFMove(completionHandler)]() mutable { + auto deletedOrigins = m_localStorageDatabaseTracker->deleteDatabasesModifiedSince(time); + + for (const auto& origin : deletedOrigins) { + for (auto& localStorageNamespace : m_localStorageNamespaces.values()) + localStorageNamespace->clearStorageAreasMatchingOrigin(origin); + } + + for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) + transientLocalStorageNamespace->clearAllStorageAreas(); + + RunLoop::main().dispatch(WTFMove(completionHandler)); + }); } -void StorageManager::deleteAllEntries() +void StorageManager::deleteLocalStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>& origins, std::function<void()>&& completionHandler) { - m_queue->dispatch(bind(&StorageManager::deleteAllEntriesInternal, this)); + Vector<SecurityOriginData> copiedOrigins; + copiedOrigins.reserveInitialCapacity(origins.size()); + + for (auto& origin : origins) + copiedOrigins.uncheckedAppend(origin.isolatedCopy()); + + m_queue->dispatch([this, protectedThis = makeRef(*this), copiedOrigins = WTFMove(copiedOrigins), completionHandler = WTFMove(completionHandler)]() mutable { + for (auto& origin : copiedOrigins) { + for (auto& localStorageNamespace : m_localStorageNamespaces.values()) + localStorageNamespace->clearStorageAreasMatchingOrigin(origin); + + for (auto& transientLocalStorageNamespace : m_transientLocalStorageNamespaces.values()) + transientLocalStorageNamespace->clearStorageAreasMatchingOrigin(origin); + + m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(origin); + } + + RunLoop::main().dispatch(WTFMove(completionHandler)); + }); } -void StorageManager::createLocalStorageMap(IPC::Connection* connection, uint64_t storageMapID, uint64_t storageNamespaceID, const SecurityOriginData& securityOriginData) +void StorageManager::createLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData) { - std::pair<RefPtr<IPC::Connection>, uint64_t> connectionAndStorageMapIDPair(connection, storageMapID); + std::pair<RefPtr<IPC::Connection>, uint64_t> connectionAndStorageMapIDPair(&connection, storageMapID); // FIXME: This should be a message check. ASSERT((HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair))); @@ -453,16 +676,51 @@ void StorageManager::createLocalStorageMap(IPC::Connection* connection, uint64_t // FIXME: This should be a message check. ASSERT(localStorageNamespace); - RefPtr<StorageArea> storageArea = localStorageNamespace->getOrCreateStorageArea(securityOriginData.securityOrigin()); + auto storageArea = localStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData)); + storageArea->addListener(connection, storageMapID); + + result.iterator->value = WTFMove(storageArea); +} + +void StorageManager::createTransientLocalStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& topLevelOriginData, SecurityOriginData&& origin) +{ + // FIXME: This should be a message check. + ASSERT(m_storageAreasByConnection.isValidKey({ &connection, storageMapID })); + + // See if we already have session storage for this connection/origin combo. + // If so, update the map with the new ID, otherwise keep on trucking. + for (auto it = m_storageAreasByConnection.begin(), end = m_storageAreasByConnection.end(); it != end; ++it) { + if (it->key.first != &connection) + continue; + Ref<StorageArea> area = *it->value; + if (!area->isSessionStorage()) + continue; + if (!origin.securityOrigin()->isSameSchemeHostPort(area->securityOrigin().securityOrigin().get())) + continue; + area->addListener(connection, storageMapID); + m_storageAreasByConnection.remove(it); + m_storageAreasByConnection.add({ &connection, storageMapID }, WTFMove(area)); + return; + } + + auto& slot = m_storageAreasByConnection.add({ &connection, storageMapID }, nullptr).iterator->value; + + // FIXME: This should be a message check. + ASSERT(!slot); + + TransientLocalStorageNamespace* transientLocalStorageNamespace = getOrCreateTransientLocalStorageNamespace(storageNamespaceID, WTFMove(topLevelOriginData)); + + auto storageArea = transientLocalStorageNamespace->getOrCreateStorageArea(WTFMove(origin)); storageArea->addListener(connection, storageMapID); - result.iterator->value = storageArea.release(); + slot = WTFMove(storageArea); } -void StorageManager::createSessionStorageMap(IPC::Connection* connection, uint64_t storageMapID, uint64_t storageNamespaceID, const SecurityOriginData& securityOriginData) +void StorageManager::createSessionStorageMap(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageNamespaceID, SecurityOriginData&& securityOriginData) { // FIXME: This should be a message check. - ASSERT((HashMap<uint64_t, RefPtr<SessionStorageNamespace>>::isValidKey(storageNamespaceID))); + ASSERT(m_sessionStorageNamespaces.isValidKey(storageNamespaceID)); + SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID); if (!sessionStorageNamespace) { // We're getting an incoming message from the web process that's for session storage for a web page @@ -470,43 +728,46 @@ void StorageManager::createSessionStorageMap(IPC::Connection* connection, uint64 return; } - std::pair<RefPtr<IPC::Connection>, uint64_t> connectionAndStorageMapIDPair(connection, storageMapID); - // FIXME: This should be a message check. - ASSERT((HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair))); + ASSERT(m_storageAreasByConnection.isValidKey({ &connection, storageMapID })); - HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::AddResult result = m_storageAreasByConnection.add(connectionAndStorageMapIDPair, nullptr); + auto& slot = m_storageAreasByConnection.add({ &connection, storageMapID }, nullptr).iterator->value; // FIXME: This should be a message check. - ASSERT(result.isNewEntry); + ASSERT(!slot); // FIXME: This should be a message check. - ASSERT(connection == sessionStorageNamespace->allowedConnection()); + ASSERT(&connection == sessionStorageNamespace->allowedConnection()); - RefPtr<StorageArea> storageArea = sessionStorageNamespace->getOrCreateStorageArea(securityOriginData.securityOrigin()); + auto storageArea = sessionStorageNamespace->getOrCreateStorageArea(WTFMove(securityOriginData)); storageArea->addListener(connection, storageMapID); - result.iterator->value = storageArea.release(); + slot = WTFMove(storageArea); } -void StorageManager::destroyStorageMap(IPC::Connection* connection, uint64_t storageMapID) +void StorageManager::destroyStorageMap(IPC::Connection& connection, uint64_t storageMapID) { - std::pair<RefPtr<IPC::Connection>, uint64_t> connectionAndStorageMapIDPair(connection, storageMapID); + std::pair<RefPtr<IPC::Connection>, uint64_t> connectionAndStorageMapIDPair(&connection, storageMapID); // FIXME: This should be a message check. - ASSERT((HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair))); + ASSERT(m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair)); - HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::iterator it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair); + auto it = m_storageAreasByConnection.find(connectionAndStorageMapIDPair); if (it == m_storageAreasByConnection.end()) { // The connection has been removed because the last page was closed. return; } it->value->removeListener(connection, storageMapID); + + // Don't remove session storage maps. The web process may reconnect and expect the data to still be around. + if (it->value->isSessionStorage()) + return; + m_storageAreasByConnection.remove(connectionAndStorageMapIDPair); } -void StorageManager::getValues(IPC::Connection* connection, uint64_t storageMapID, uint64_t storageMapSeed, HashMap<String, String>& values) +void StorageManager::getValues(IPC::Connection& connection, uint64_t storageMapID, uint64_t storageMapSeed, HashMap<String, String>& values) { StorageArea* storageArea = findStorageArea(connection, storageMapID); if (!storageArea) { @@ -515,10 +776,10 @@ void StorageManager::getValues(IPC::Connection* connection, uint64_t storageMapI } values = storageArea->items(); - connection->send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID); + connection.send(Messages::StorageAreaMap::DidGetValues(storageMapSeed), storageMapID); } -void StorageManager::setItem(IPC::Connection* connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString) +void StorageManager::setItem(IPC::Connection& connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString) { StorageArea* storageArea = findStorageArea(connection, storageMapID); if (!storageArea) { @@ -527,11 +788,11 @@ void StorageManager::setItem(IPC::Connection* connection, uint64_t storageMapID, } bool quotaError; - storageArea->setItem(connection, sourceStorageAreaID, key, value, urlString, quotaError); - connection->send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID); + storageArea->setItem(&connection, sourceStorageAreaID, key, value, urlString, quotaError); + connection.send(Messages::StorageAreaMap::DidSetItem(storageMapSeed, key, quotaError), storageMapID); } -void StorageManager::removeItem(IPC::Connection* connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString) +void StorageManager::removeItem(IPC::Connection& connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString) { StorageArea* storageArea = findStorageArea(connection, storageMapID); if (!storageArea) { @@ -539,11 +800,11 @@ void StorageManager::removeItem(IPC::Connection* connection, uint64_t storageMap return; } - storageArea->removeItem(connection, sourceStorageAreaID, key, urlString); - connection->send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID); + storageArea->removeItem(&connection, sourceStorageAreaID, key, urlString); + connection.send(Messages::StorageAreaMap::DidRemoveItem(storageMapSeed, key), storageMapID); } -void StorageManager::clear(IPC::Connection* connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString) +void StorageManager::clear(IPC::Connection& connection, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString) { StorageArea* storageArea = findStorageArea(connection, storageMapID); if (!storageArea) { @@ -551,105 +812,60 @@ void StorageManager::clear(IPC::Connection* connection, uint64_t storageMapID, u return; } - storageArea->clear(connection, sourceStorageAreaID, urlString); - connection->send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID); -} - -void StorageManager::createSessionStorageNamespaceInternal(uint64_t storageNamespaceID, IPC::Connection* allowedConnection, unsigned quotaInBytes) -{ - ASSERT(!m_sessionStorageNamespaces.contains(storageNamespaceID)); - - m_sessionStorageNamespaces.set(storageNamespaceID, SessionStorageNamespace::create(allowedConnection, quotaInBytes)); + storageArea->clear(&connection, sourceStorageAreaID, urlString); + connection.send(Messages::StorageAreaMap::DidClear(storageMapSeed), storageMapID); } -void StorageManager::destroySessionStorageNamespaceInternal(uint64_t storageNamespaceID) +void StorageManager::applicationWillTerminate() { - ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID)); - m_sessionStorageNamespaces.remove(storageNamespaceID); -} - -void StorageManager::setAllowedSessionStorageNamespaceConnectionInternal(uint64_t storageNamespaceID, IPC::Connection* allowedConnection) -{ - ASSERT(m_sessionStorageNamespaces.contains(storageNamespaceID)); - - m_sessionStorageNamespaces.get(storageNamespaceID)->setAllowedConnection(allowedConnection); -} - -void StorageManager::cloneSessionStorageNamespaceInternal(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID) -{ - SessionStorageNamespace* sessionStorageNamespace = m_sessionStorageNamespaces.get(storageNamespaceID); - ASSERT(sessionStorageNamespace); + BinarySemaphore semaphore; + m_queue->dispatch([this, &semaphore] { + Vector<std::pair<RefPtr<IPC::Connection>, uint64_t>> connectionAndStorageMapIDPairsToRemove; + for (auto& connectionStorageAreaPair : m_storageAreasByConnection) { + connectionStorageAreaPair.value->removeListener(*connectionStorageAreaPair.key.first, connectionStorageAreaPair.key.second); + connectionAndStorageMapIDPairsToRemove.append(connectionStorageAreaPair.key); + } - SessionStorageNamespace* newSessionStorageNamespace = m_sessionStorageNamespaces.get(newStorageNamespaceID); - ASSERT(newSessionStorageNamespace); + for (auto& connectionStorageAreaPair : connectionAndStorageMapIDPairsToRemove) + m_storageAreasByConnection.remove(connectionStorageAreaPair); - sessionStorageNamespace->cloneTo(*newSessionStorageNamespace); + semaphore.signal(); + }); + semaphore.wait(WallTime::infinity()); } -void StorageManager::invalidateConnectionInternal(IPC::Connection* connection) +StorageManager::StorageArea* StorageManager::findStorageArea(IPC::Connection& connection, uint64_t storageMapID) const { - Vector<std::pair<RefPtr<IPC::Connection>, uint64_t>> connectionAndStorageMapIDPairsToRemove; - HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>> storageAreasByConnection = m_storageAreasByConnection; - for (HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::const_iterator it = storageAreasByConnection.begin(), end = storageAreasByConnection.end(); it != end; ++it) { - if (it->key.first != connection) - continue; - - it->value->removeListener(it->key.first.get(), it->key.second); - connectionAndStorageMapIDPairsToRemove.append(it->key); - } - - for (size_t i = 0; i < connectionAndStorageMapIDPairsToRemove.size(); ++i) - m_storageAreasByConnection.remove(connectionAndStorageMapIDPairsToRemove[i]); -} + std::pair<IPC::Connection*, uint64_t> connectionAndStorageMapIDPair(&connection, storageMapID); -StorageManager::StorageArea* StorageManager::findStorageArea(IPC::Connection* connection, uint64_t storageMapID) const -{ - std::pair<IPC::Connection*, uint64_t> connectionAndStorageMapIDPair(connection, storageMapID); - if (!HashMap<std::pair<RefPtr<IPC::Connection>, uint64_t>, RefPtr<StorageArea>>::isValidKey(connectionAndStorageMapIDPair)) - return 0; + if (!m_storageAreasByConnection.isValidKey(connectionAndStorageMapIDPair)) + return nullptr; return m_storageAreasByConnection.get(connectionAndStorageMapIDPair); } StorageManager::LocalStorageNamespace* StorageManager::getOrCreateLocalStorageNamespace(uint64_t storageNamespaceID) { - if (!HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::isValidKey(storageNamespaceID)) - return 0; - - HashMap<uint64_t, RefPtr<LocalStorageNamespace>>::AddResult result = m_localStorageNamespaces.add(storageNamespaceID, nullptr); - if (result.isNewEntry) - result.iterator->value = LocalStorageNamespace::create(this, storageNamespaceID); - - return result.iterator->value.get(); -} + if (!m_localStorageNamespaces.isValidKey(storageNamespaceID)) + return nullptr; -static void callCallbackFunction(void* context, void (*callbackFunction)(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context), Vector<RefPtr<WebCore::SecurityOrigin>>* securityOriginsPtr) -{ - OwnPtr<Vector<RefPtr<WebCore::SecurityOrigin>>> securityOrigins = adoptPtr(securityOriginsPtr); - callbackFunction(*securityOrigins, context); -} + auto& slot = m_localStorageNamespaces.add(storageNamespaceID, nullptr).iterator->value; + if (!slot) + slot = LocalStorageNamespace::create(this, storageNamespaceID); -void StorageManager::getOriginsInternal(FunctionDispatcher* dispatcher, void* context, void (*callbackFunction)(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context)) -{ - OwnPtr<Vector<RefPtr<WebCore::SecurityOrigin>>> securityOrigins = adoptPtr(new Vector<RefPtr<WebCore::SecurityOrigin>>(m_localStorageDatabaseTracker->origins())); - dispatcher->dispatch(bind(callCallbackFunction, context, callbackFunction, securityOrigins.leakPtr())); + return slot.get(); } -void StorageManager::deleteEntriesForOriginInternal(SecurityOrigin* securityOrigin) +StorageManager::TransientLocalStorageNamespace* StorageManager::getOrCreateTransientLocalStorageNamespace(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOrigin) { - for (auto it = m_localStorageNamespaces.begin(), end = m_localStorageNamespaces.end(); it != end; ++it) - it->value->clearStorageAreasMatchingOrigin(securityOrigin); + if (!m_transientLocalStorageNamespaces.isValidKey({ storageNamespaceID, topLevelOrigin })) + return nullptr; - m_localStorageDatabaseTracker->deleteDatabaseWithOrigin(securityOrigin); -} - -void StorageManager::deleteAllEntriesInternal() -{ - for (auto it = m_localStorageNamespaces.begin(), end = m_localStorageNamespaces.end(); it != end; ++it) - it->value->clearAllStorageAreas(); + auto& slot = m_transientLocalStorageNamespaces.add({ storageNamespaceID, WTFMove(topLevelOrigin) }, nullptr).iterator->value; + if (!slot) + slot = TransientLocalStorageNamespace::create(); - m_localStorageDatabaseTracker->deleteAllDatabases(); + return slot.get(); } - } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Storage/StorageManager.h b/Source/WebKit2/UIProcess/Storage/StorageManager.h index 93bb66c55..52f093e01 100644 --- a/Source/WebKit2/UIProcess/Storage/StorageManager.h +++ b/Source/WebKit2/UIProcess/Storage/StorageManager.h @@ -23,87 +23,87 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef StorageManager_h -#define StorageManager_h +#pragma once #include "Connection.h" +#include "LocalStorageDatabaseTracker.h" +#include <WebCore/SecurityOriginData.h> +#include <WebCore/SecurityOriginHash.h> +#include <chrono> #include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> +#include <wtf/HashSet.h> #include <wtf/ThreadSafeRefCounted.h> #include <wtf/text/StringHash.h> -class WorkQueue; - namespace WebCore { class SecurityOrigin; } namespace WebKit { -struct SecurityOriginData; class LocalStorageDatabaseTracker; class WebProcessProxy; class StorageManager : public IPC::Connection::WorkQueueMessageReceiver { public: - static PassRefPtr<StorageManager> create(); + static Ref<StorageManager> create(const String& localStorageDirectory); ~StorageManager(); - void setLocalStorageDirectory(const String&); - - void createSessionStorageNamespace(uint64_t storageNamespaceID, IPC::Connection* allowedConnection, unsigned quotaInBytes); + void createSessionStorageNamespace(uint64_t storageNamespaceID, unsigned quotaInBytes); void destroySessionStorageNamespace(uint64_t storageNamespaceID); void setAllowedSessionStorageNamespaceConnection(uint64_t storageNamespaceID, IPC::Connection* allowedConnection); void cloneSessionStorageNamespace(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID); - void processWillOpenConnection(WebProcessProxy*); - void processWillCloseConnection(WebProcessProxy*); + void processWillOpenConnection(WebProcessProxy&, IPC::Connection&); + void processDidCloseConnection(WebProcessProxy&, IPC::Connection&); + void applicationWillTerminate(); + + void getSessionStorageOrigins(std::function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler); + void deleteSessionStorageOrigins(std::function<void()>&& completionHandler); + void deleteSessionStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, std::function<void()>&& completionHandler); + + void getLocalStorageOrigins(std::function<void(HashSet<WebCore::SecurityOriginData>&&)>&& completionHandler); + void deleteLocalStorageEntriesForOrigin(WebCore::SecurityOriginData&&); + + void deleteLocalStorageOriginsModifiedSince(std::chrono::system_clock::time_point, std::function<void()>&& completionHandler); + void deleteLocalStorageEntriesForOrigins(const Vector<WebCore::SecurityOriginData>&, std::function<void()>&& completionHandler); - // FIXME: Instead of a context + C function, this should take a WTF::Function, but we currently don't - // support arguments in functions. - void getOrigins(FunctionDispatcher* callbackDispatcher, void* context, void (*callback)(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context)); - void deleteEntriesForOrigin(WebCore::SecurityOrigin*); - void deleteAllEntries(); + void getLocalStorageOriginDetails(std::function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>)>&& completionHandler); private: - StorageManager(); + explicit StorageManager(const String& localStorageDirectory); // IPC::Connection::WorkQueueMessageReceiver. - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>& replyEncoder) override; // Message handlers. - void createLocalStorageMap(IPC::Connection*, uint64_t storageMapID, uint64_t storageNamespaceID, const SecurityOriginData&); - void createSessionStorageMap(IPC::Connection*, uint64_t storageMapID, uint64_t storageNamespaceID, const SecurityOriginData&); - void destroyStorageMap(IPC::Connection*, uint64_t storageMapID); + void createLocalStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&&); + void createTransientLocalStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOriginData, WebCore::SecurityOriginData&&); + void createSessionStorageMap(IPC::Connection&, uint64_t storageMapID, uint64_t storageNamespaceID, WebCore::SecurityOriginData&&); + void destroyStorageMap(IPC::Connection&, uint64_t storageMapID); - void getValues(IPC::Connection*, uint64_t storageMapID, uint64_t storageMapSeed, HashMap<String, String>& values); - void setItem(IPC::Connection*, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString); - void removeItem(IPC::Connection*, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString); - void clear(IPC::Connection*, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString); - - void createSessionStorageNamespaceInternal(uint64_t storageNamespaceID, IPC::Connection* allowedConnection, unsigned quotaInBytes); - void destroySessionStorageNamespaceInternal(uint64_t storageNamespaceID); - void setAllowedSessionStorageNamespaceConnectionInternal(uint64_t storageNamespaceID, IPC::Connection* allowedConnection); - void cloneSessionStorageNamespaceInternal(uint64_t storageNamespaceID, uint64_t newStorageNamespaceID); - - void invalidateConnectionInternal(IPC::Connection*); + void getValues(IPC::Connection&, uint64_t storageMapID, uint64_t storageMapSeed, HashMap<String, String>& values); + void setItem(IPC::Connection&, uint64_t storageAreaID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& value, const String& urlString); + void removeItem(IPC::Connection&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& key, const String& urlString); + void clear(IPC::Connection&, uint64_t storageMapID, uint64_t sourceStorageAreaID, uint64_t storageMapSeed, const String& urlString); class StorageArea; - StorageArea* findStorageArea(IPC::Connection*, uint64_t) const; + StorageArea* findStorageArea(IPC::Connection&, uint64_t) const; class LocalStorageNamespace; LocalStorageNamespace* getOrCreateLocalStorageNamespace(uint64_t storageNamespaceID); - void getOriginsInternal(FunctionDispatcher* callbackDispatcher, void* context, void (*callback)(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context)); - void deleteEntriesForOriginInternal(WebCore::SecurityOrigin*); - void deleteAllEntriesInternal(); + class TransientLocalStorageNamespace; + TransientLocalStorageNamespace* getOrCreateTransientLocalStorageNamespace(uint64_t storageNamespaceID, WebCore::SecurityOriginData&& topLevelOrigin); - RefPtr<WorkQueue> m_queue; + Ref<WorkQueue> m_queue; - RefPtr<LocalStorageDatabaseTracker> m_localStorageDatabaseTracker; + Ref<LocalStorageDatabaseTracker> m_localStorageDatabaseTracker; HashMap<uint64_t, RefPtr<LocalStorageNamespace>> m_localStorageNamespaces; + HashMap<std::pair<uint64_t, WebCore::SecurityOriginData>, RefPtr<TransientLocalStorageNamespace>> m_transientLocalStorageNamespaces; + class SessionStorageNamespace; HashMap<uint64_t, RefPtr<SessionStorageNamespace>> m_sessionStorageNamespaces; @@ -111,5 +111,3 @@ private: }; } // namespace WebKit - -#endif // StorageManager_h diff --git a/Source/WebKit2/UIProcess/Storage/StorageManager.messages.in b/Source/WebKit2/UIProcess/Storage/StorageManager.messages.in index 59b8f3639..25789f74c 100644 --- a/Source/WebKit2/UIProcess/Storage/StorageManager.messages.in +++ b/Source/WebKit2/UIProcess/Storage/StorageManager.messages.in @@ -21,8 +21,9 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> StorageManager { - CreateLocalStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, WebKit::SecurityOriginData securityOriginData) WantsConnection - CreateSessionStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, WebKit::SecurityOriginData securityOriginData) WantsConnection + CreateLocalStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) WantsConnection + CreateTransientLocalStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData topLevelSecurityOriginData, struct WebCore::SecurityOriginData securityOriginData) WantsConnection + CreateSessionStorageMap(uint64_t storageMapID, uint64_t storageNamespaceID, struct WebCore::SecurityOriginData securityOriginData) WantsConnection DestroyStorageMap(uint64_t storageMapID) WantsConnection GetValues(uint64_t storageMapID, uint64_t storageMapSeed) -> (HashMap<String, String> values) WantsConnection diff --git a/Source/WebKit2/UIProcess/TextChecker.h b/Source/WebKit2/UIProcess/TextChecker.h index bd08d354d..41378c23f 100644 --- a/Source/WebKit2/UIProcess/TextChecker.h +++ b/Source/WebKit2/UIProcess/TextChecker.h @@ -42,8 +42,11 @@ public: static void setContinuousSpellCheckingEnabled(bool); static void setGrammarCheckingEnabled(bool); + + static void setTestingMode(bool); + static bool isTestingMode(); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) static void setAutomaticSpellingCorrectionEnabled(bool); static void setAutomaticQuoteSubstitutionEnabled(bool); static void setAutomaticDashSubstitutionEnabled(bool); @@ -62,23 +65,28 @@ public: static void toggleSubstitutionsPanelIsShowing(); #endif +#if PLATFORM(GTK) + static void setSpellCheckingLanguages(const Vector<String>&); + static Vector<String> loadedSpellCheckingLanguages(); +#endif + static void continuousSpellCheckingEnabledStateChanged(bool); static void grammarCheckingEnabledStateChanged(bool); static int64_t uniqueSpellDocumentTag(WebPageProxy*); static void closeSpellDocumentWithTag(int64_t); #if USE(UNIFIED_TEXT_CHECKING) - static Vector<WebCore::TextCheckingResult> checkTextOfParagraph(int64_t spellDocumentTag, const UChar* text, int length, uint64_t checkingTypes); + static Vector<WebCore::TextCheckingResult> checkTextOfParagraph(int64_t spellDocumentTag, StringView text, int32_t insertionPoint, uint64_t checkingTypes, bool initialCapitalizationEnabled); #endif - static void checkSpellingOfString(int64_t spellDocumentTag, const UChar* text, uint32_t length, int32_t& misspellingLocation, int32_t& misspellingLength); - static void checkGrammarOfString(int64_t spellDocumentTag, const UChar* text, uint32_t length, Vector<WebCore::GrammarDetail>&, int32_t& badGrammarLocation, int32_t& badGrammarLength); + static void checkSpellingOfString(int64_t spellDocumentTag, StringView text, int32_t& misspellingLocation, int32_t& misspellingLength); + static void checkGrammarOfString(int64_t spellDocumentTag, StringView text, Vector<WebCore::GrammarDetail>&, int32_t& badGrammarLocation, int32_t& badGrammarLength); static bool spellingUIIsShowing(); static void toggleSpellingUIIsShowing(); static void updateSpellingUIWithMisspelledWord(int64_t spellDocumentTag, const String& misspelledWord); static void updateSpellingUIWithGrammarString(int64_t spellDocumentTag, const String& badGrammarPhrase, const WebCore::GrammarDetail&); - static void getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, Vector<String>& guesses); + static void getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, int32_t insertionPoint, Vector<String>& guesses, bool initialCapitalizationEnabled); static void learnWord(int64_t spellDocumentTag, const String& word); static void ignoreWord(int64_t spellDocumentTag, const String& word); - static void requestCheckingOfString(PassRefPtr<TextCheckerCompletion>); + static void requestCheckingOfString(PassRefPtr<TextCheckerCompletion>, int32_t insertionPoint); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.cpp b/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.cpp new file mode 100644 index 000000000..7d86d67e3 --- /dev/null +++ b/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UnresponsiveWebProcessTerminator.h" + +#include "Logging.h" + +namespace WebKit { + +static const std::chrono::seconds initialInterval { 20s }; +static const std::chrono::seconds maximumInterval { 8h }; + +UnresponsiveWebProcessTerminator::UnresponsiveWebProcessTerminator(WebProcessProxy& webProcessProxy) + : m_webProcessProxy(webProcessProxy) + , m_interval(initialInterval) + , m_timer(RunLoop::main(), this, &UnresponsiveWebProcessTerminator::timerFired) +{ +} + +void UnresponsiveWebProcessTerminator::updateState() +{ + if (!shouldBeActive()) { + if (m_timer.isActive()) { + m_interval = initialInterval; + m_timer.stop(); + } + return; + } + + if (!m_timer.isActive()) + m_timer.startOneShot(m_interval); +} + +static Vector<RefPtr<WebPageProxy>> pagesCopy(WTF::IteratorRange<WebProcessProxy::WebPageProxyMap::const_iterator::Values> pages) +{ + Vector<RefPtr<WebPageProxy>> vector; + for (auto& page : pages) + vector.append(page); + return vector; +} + +void UnresponsiveWebProcessTerminator::timerFired() +{ + ASSERT(shouldBeActive()); + m_webProcessProxy.isResponsive([this](bool processIsResponsive) { + if (processIsResponsive) { + // Exponential backoff to avoid waking up the process too often. + m_interval = std::min(m_interval * 2, maximumInterval); + m_timer.startOneShot(m_interval); + return; + } + + RELEASE_LOG_ERROR(PerformanceLogging, "Killing a background WebProcess because it is not responsive"); + for (auto& page : pagesCopy(m_webProcessProxy.pages())) + page->terminateProcess(WebPageProxy::TerminationReason::UnresponsiveWhileInBackground); + }); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.h b/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.h new file mode 100644 index 000000000..8314dd649 --- /dev/null +++ b/Source/WebKit2/UIProcess/UnresponsiveWebProcessTerminator.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "WebProcessProxy.h" +#include <wtf/RunLoop.h> + +namespace WebKit { + +class UnresponsiveWebProcessTerminator { +public: + explicit UnresponsiveWebProcessTerminator(WebProcessProxy&); + void updateState(); + +private: + void timerFired(); + bool shouldBeActive() const { return !m_webProcessProxy.visiblePageCount() && m_webProcessProxy.pageCount(); } + + WebProcessProxy& m_webProcessProxy; + std::chrono::seconds m_interval; + RunLoop::Timer<UnresponsiveWebProcessTerminator> m_timer; +}; + +} diff --git a/Source/WebKit2/UIProcess/WebDatabaseManagerProxyClient.cpp b/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp index 4e932d218..91e5ceaf3 100644 --- a/Source/WebKit2/UIProcess/WebDatabaseManagerProxyClient.cpp +++ b/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,26 +24,34 @@ */ #include "config.h" -#include "WebDatabaseManagerProxyClient.h" +#include "WebScriptMessageHandler.h" -#include "WKAPICast.h" +#include "APIUserContentWorld.h" namespace WebKit { -void WebDatabaseManagerProxyClient::didModifyOrigin(WebDatabaseManagerProxy* databaseManager, WebSecurityOrigin* origin) +static uint64_t generateIdentifier() { - if (!m_client.didModifyOrigin) - return; + static uint64_t identifier; - m_client.didModifyOrigin(toAPI(databaseManager), toAPI(origin), m_client.base.clientInfo); + return ++identifier; } -void WebDatabaseManagerProxyClient::didModifyDatabase(WebDatabaseManagerProxy* databaseManager, WebSecurityOrigin* origin, const String& databaseIdentifier) +Ref<WebScriptMessageHandler> WebScriptMessageHandler::create(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world) { - if (!m_client.didModifyDatabase) - return; + return adoptRef(*new WebScriptMessageHandler(WTFMove(client), name, world)); +} - m_client.didModifyDatabase(toAPI(databaseManager), toAPI(origin), toAPI(databaseIdentifier.impl()), m_client.base.clientInfo); +WebScriptMessageHandler::WebScriptMessageHandler(std::unique_ptr<Client> client, const String& name, API::UserContentWorld& world) + : m_identifier(generateIdentifier()) + , m_client(WTFMove(client)) + , m_name(name) + , m_world(world) +{ +} + +WebScriptMessageHandler::~WebScriptMessageHandler() +{ } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/APISession.cpp b/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h index c2a2615ff..1c11a0a6a 100644 --- a/Source/WebKit2/UIProcess/APISession.cpp +++ b/Source/WebKit2/UIProcess/UserContent/WebScriptMessageHandler.h @@ -23,68 +23,58 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include "APISession.h" +#ifndef WebScriptMessageHandler_h +#define WebScriptMessageHandler_h -#include <wtf/MainThread.h> +#include "WebUserContentControllerDataTypes.h" +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> -namespace API { - -static uint64_t generateID(bool isEphemeral) -{ - ASSERT(isMainThread()); - - static uint64_t uniqueSessionID = WebKit::SessionTracker::legacyPrivateSessionID; - ASSERT(isEphemeral); - return ++uniqueSessionID; +namespace WebCore { +struct SecurityOriginData; +class SerializedScriptValue; } -Session& Session::defaultSession() -{ - ASSERT(isMainThread()); - - static Session* defaultSession = new Session(false, WebKit::SessionTracker::defaultSessionID); - return *defaultSession; +namespace API { +class UserContentWorld; } -Session& Session::legacyPrivateSession() -{ - ASSERT(isMainThread()); +namespace WebKit { - static Session* legacyPrivateSession = new Session(true, WebKit::SessionTracker::legacyPrivateSessionID); - return *legacyPrivateSession; -} +class WebPageProxy; +class WebFrameProxy; +struct FrameInfoData; -Session::Session(bool isEphemeral) - : m_isEphemeral(isEphemeral) - , m_sessionID(generateID(isEphemeral)) -{ -} +class WebScriptMessageHandler : public RefCounted<WebScriptMessageHandler> { +public: + class Client { + public: + virtual ~Client() { } + virtual void didPostMessage(WebPageProxy&, const FrameInfoData&, WebCore::SerializedScriptValue&) = 0; + }; -Session::Session(bool isEphemeral, uint64_t sessionID) - : m_isEphemeral(isEphemeral) - , m_sessionID(sessionID) -{ -} + static Ref<WebScriptMessageHandler> create(std::unique_ptr<Client>, const String& name, API::UserContentWorld&); + virtual ~WebScriptMessageHandler(); -PassRefPtr<Session> Session::create(bool isEphemeral) -{ - // FIXME: support creation of non-default, non-ephemeral sessions - return adoptRef(new Session(isEphemeral)); -} + uint64_t identifier() const { return m_identifier; } + String name() const { return m_name; } -bool Session::isEphemeral() const -{ - return m_isEphemeral; -} + const API::UserContentWorld& userContentWorld() const { return m_world; } + API::UserContentWorld& userContentWorld() { return m_world; } -uint64_t Session::getID() const -{ - return m_sessionID; -} + Client& client() const { return *m_client; } -Session::~Session() -{ -} +private: + WebScriptMessageHandler(std::unique_ptr<Client>, const String&, API::UserContentWorld&); + + uint64_t m_identifier; + + std::unique_ptr<Client> m_client; + String m_name; + Ref<API::UserContentWorld> m_world; +}; } // namespace API + +#endif // WebScriptMessageHandler_h diff --git a/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp new file mode 100644 index 000000000..b02622437 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebUserContentControllerProxy.h" + +#include "APIArray.h" +#include "APIUserContentWorld.h" +#include "APIUserScript.h" +#include "APIUserStyleSheet.h" +#include "DataReference.h" +#include "WebProcessProxy.h" +#include "WebScriptMessageHandler.h" +#include "WebUserContentControllerDataTypes.h" +#include "WebUserContentControllerMessages.h" +#include "WebUserContentControllerProxyMessages.h" +#include <WebCore/SerializedScriptValue.h> + +#if ENABLE(CONTENT_EXTENSIONS) +#include "APIUserContentExtension.h" +#include "WebCompiledContentExtension.h" +#endif + +namespace WebKit { + +static uint64_t generateIdentifier() +{ + static uint64_t identifier; + + return ++identifier; +} + +WebUserContentControllerProxy::WebUserContentControllerProxy() + : m_identifier(generateIdentifier()) + , m_userScripts(API::Array::create()) + , m_userStyleSheets(API::Array::create()) +{ +} + +WebUserContentControllerProxy::~WebUserContentControllerProxy() +{ + for (WebProcessProxy* process : m_processes) { + process->removeMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier); + process->didDestroyWebUserContentControllerProxy(*this); + } +} + +void WebUserContentControllerProxy::addProcess(WebProcessProxy& webProcessProxy) +{ + ASSERT(webProcessProxy.state() == WebProcessProxy::State::Running); + + if (!m_processes.add(&webProcessProxy).isNewEntry) + return; + + webProcessProxy.addMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier, *this); + + Vector<std::pair<uint64_t, String>> userContentWorlds; + for (const auto& world : m_userContentWorlds) + userContentWorlds.append(std::make_pair(world.key->identifier(), world.key->name())); + webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserContentWorlds(userContentWorlds), m_identifier); + + Vector<WebUserScriptData> userScripts; + for (const auto& userScript : m_userScripts->elementsOfType<API::UserScript>()) + userScripts.append({ userScript->identifier(), userScript->userContentWorld().identifier(), userScript->userScript() }); + webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScripts(userScripts), m_identifier); + + Vector<WebUserStyleSheetData> userStyleSheets; + for (const auto& userStyleSheet : m_userStyleSheets->elementsOfType<API::UserStyleSheet>()) + userStyleSheets.append({ userStyleSheet->identifier(), userStyleSheet->userContentWorld().identifier(), userStyleSheet->userStyleSheet() }); + webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserStyleSheets(userStyleSheets), m_identifier); + + Vector<WebScriptMessageHandlerData> messageHandlers; + for (auto& handler : m_scriptMessageHandlers.values()) + messageHandlers.append({ handler->identifier(), handler->userContentWorld().identifier(), handler->name() }); + webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers(messageHandlers), m_identifier); + +#if ENABLE(CONTENT_EXTENSIONS) + Vector<std::pair<String, WebCompiledContentExtensionData>> userContentExtensions; + for (const auto& userContentExtension : m_userContentExtensions.values()) + userContentExtensions.append(std::make_pair(userContentExtension->name(), userContentExtension->compiledExtension().data())); + webProcessProxy.connection()->send(Messages::WebUserContentController::AddUserContentExtensions(userContentExtensions), m_identifier); +#endif +} + +void WebUserContentControllerProxy::removeProcess(WebProcessProxy& webProcessProxy) +{ + ASSERT(m_processes.contains(&webProcessProxy)); + + m_processes.remove(&webProcessProxy); + webProcessProxy.removeMessageReceiver(Messages::WebUserContentControllerProxy::messageReceiverName(), m_identifier); +} + +void WebUserContentControllerProxy::addUserContentWorldUse(API::UserContentWorld& world) +{ + if (&world == &API::UserContentWorld::normalWorld()) + return; + + auto addResult = m_userContentWorlds.add(&world); + if (addResult.isNewEntry) { + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::AddUserContentWorlds({ std::make_pair(world.identifier(), world.name()) }), m_identifier); + } +} + +bool WebUserContentControllerProxy::shouldSendRemoveUserContentWorldsMessage(API::UserContentWorld& world, unsigned numberOfUsesToRemove) +{ + if (&world == &API::UserContentWorld::normalWorld()) + return false; + + auto it = m_userContentWorlds.find(&world); + for (unsigned i = 0; i < numberOfUsesToRemove; ++i) { + if (m_userContentWorlds.remove(it)) { + ASSERT(i == (numberOfUsesToRemove - 1)); + return true; + } + } + + return false; +} + +void WebUserContentControllerProxy::removeUserContentWorldUses(API::UserContentWorld& world, unsigned numberOfUsesToRemove) +{ + if (shouldSendRemoveUserContentWorldsMessage(world, numberOfUsesToRemove)) { + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserContentWorlds({ world.identifier() }), m_identifier); + } +} + +void WebUserContentControllerProxy::removeUserContentWorldUses(HashCountedSet<RefPtr<API::UserContentWorld>>& worlds) +{ + Vector<uint64_t> worldsToRemove; + for (auto& worldUsePair : worlds) { + if (shouldSendRemoveUserContentWorldsMessage(*worldUsePair.key.get(), worldUsePair.value)) + worldsToRemove.append(worldUsePair.key->identifier()); + } + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserContentWorlds(worldsToRemove), m_identifier); +} + +void WebUserContentControllerProxy::addUserScript(API::UserScript& userScript) +{ + Ref<API::UserContentWorld> world = userScript.userContentWorld(); + + addUserContentWorldUse(world.get()); + + m_userScripts->elements().append(&userScript); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::AddUserScripts({ { userScript.identifier(), world->identifier(), userScript.userScript() } }), m_identifier); +} + +void WebUserContentControllerProxy::removeUserScript(API::UserScript& userScript) +{ + Ref<API::UserContentWorld> world = userScript.userContentWorld(); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserScript(world->identifier(), userScript.identifier()), m_identifier); + + m_userScripts->elements().removeAll(&userScript); + + removeUserContentWorldUses(world.get(), 1); +} + +void WebUserContentControllerProxy::removeAllUserScripts(API::UserContentWorld& world) +{ + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserScripts({ world.identifier() }), m_identifier); + + unsigned userScriptsRemoved = m_userScripts->removeAllOfTypeMatching<API::UserScript>([&](const auto& userScript) { + return &userScript->userContentWorld() == &world; + }); + + removeUserContentWorldUses(world, userScriptsRemoved); +} + +void WebUserContentControllerProxy::removeAllUserScripts() +{ + HashCountedSet<RefPtr<API::UserContentWorld>> worlds; + for (const auto& userScript : m_userScripts->elementsOfType<API::UserScript>()) + worlds.add(const_cast<API::UserContentWorld*>(&userScript->userContentWorld())); + + Vector<uint64_t> worldIdentifiers; + worldIdentifiers.reserveInitialCapacity(worlds.size()); + for (const auto& worldCountPair : worlds) + worldIdentifiers.uncheckedAppend(worldCountPair.key->identifier()); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserScripts(worldIdentifiers), m_identifier); + + m_userScripts->elements().clear(); + + removeUserContentWorldUses(worlds); +} + +void WebUserContentControllerProxy::addUserStyleSheet(API::UserStyleSheet& userStyleSheet) +{ + Ref<API::UserContentWorld> world = userStyleSheet.userContentWorld(); + + addUserContentWorldUse(world.get()); + + m_userStyleSheets->elements().append(&userStyleSheet); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::AddUserStyleSheets({ { userStyleSheet.identifier(), world->identifier(), userStyleSheet.userStyleSheet() } }), m_identifier); +} + +void WebUserContentControllerProxy::removeUserStyleSheet(API::UserStyleSheet& userStyleSheet) +{ + Ref<API::UserContentWorld> world = userStyleSheet.userContentWorld(); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserStyleSheet(world->identifier(), userStyleSheet.identifier()), m_identifier); + + m_userStyleSheets->elements().removeAll(&userStyleSheet); + + removeUserContentWorldUses(world.get(), 1); +} + +void WebUserContentControllerProxy::removeAllUserStyleSheets(API::UserContentWorld& world) +{ + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserStyleSheets({ world.identifier() }), m_identifier); + + unsigned userStyleSheetsRemoved = m_userStyleSheets->removeAllOfTypeMatching<API::UserStyleSheet>([&](const auto& userStyleSheet) { + return &userStyleSheet->userContentWorld() == &world; + }); + + removeUserContentWorldUses(world, userStyleSheetsRemoved); +} + +void WebUserContentControllerProxy::removeAllUserStyleSheets() +{ + HashCountedSet<RefPtr<API::UserContentWorld>> worlds; + for (const auto& userStyleSheet : m_userStyleSheets->elementsOfType<API::UserStyleSheet>()) + worlds.add(const_cast<API::UserContentWorld*>(&userStyleSheet->userContentWorld())); + + Vector<uint64_t> worldIdentifiers; + worldIdentifiers.reserveInitialCapacity(worlds.size()); + for (const auto& worldCountPair : worlds) + worldIdentifiers.uncheckedAppend(worldCountPair.key->identifier()); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserStyleSheets(worldIdentifiers), m_identifier); + + m_userStyleSheets->elements().clear(); + + removeUserContentWorldUses(worlds); +} + +bool WebUserContentControllerProxy::addUserScriptMessageHandler(WebScriptMessageHandler& handler) +{ + Ref<API::UserContentWorld> world = handler.userContentWorld(); + + for (auto& existingHandler : m_scriptMessageHandlers.values()) { + if (existingHandler->name() == handler.name() && &existingHandler->userContentWorld() == world.ptr()) + return false; + } + + addUserContentWorldUse(world.get()); + + m_scriptMessageHandlers.add(handler.identifier(), &handler); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::AddUserScriptMessageHandlers({ { handler.identifier(), world->identifier(), handler.name() } }), m_identifier); + + return true; +} + +void WebUserContentControllerProxy::removeUserMessageHandlerForName(const String& name, API::UserContentWorld& world) +{ + for (auto it = m_scriptMessageHandlers.begin(), end = m_scriptMessageHandlers.end(); it != end; ++it) { + if (it->value->name() == name && &it->value->userContentWorld() == &world) { + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserScriptMessageHandler(world.identifier(), it->value->identifier()), m_identifier); + + m_scriptMessageHandlers.remove(it); + + removeUserContentWorldUses(world, 1); + return; + } + } +} + +void WebUserContentControllerProxy::removeAllUserMessageHandlers(API::UserContentWorld& world) +{ + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserScriptMessageHandlers({ world.identifier() }), m_identifier); + + unsigned numberRemoved = 0; + m_scriptMessageHandlers.removeIf([&](auto& entry) { + if (&entry.value->userContentWorld() == &world) { + ++numberRemoved; + return true; + } + return false; + }); + + removeUserContentWorldUses(world, numberRemoved); +} + +void WebUserContentControllerProxy::didPostMessage(IPC::Connection& connection, uint64_t pageID, const FrameInfoData& frameInfoData, uint64_t messageHandlerID, const IPC::DataReference& dataReference) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + if (!page) + return; + + if (!HashMap<uint64_t, RefPtr<WebScriptMessageHandler>>::isValidKey(messageHandlerID)) + return; + + RefPtr<WebScriptMessageHandler> handler = m_scriptMessageHandlers.get(messageHandlerID); + if (!handler) + return; + + handler->client().didPostMessage(*page, frameInfoData, WebCore::SerializedScriptValue::adopt(dataReference.vector())); +} + +#if ENABLE(CONTENT_EXTENSIONS) +void WebUserContentControllerProxy::addUserContentExtension(API::UserContentExtension& userContentExtension) +{ + m_userContentExtensions.set(userContentExtension.name(), &userContentExtension); + + auto pair = std::make_pair(userContentExtension.name(), userContentExtension.compiledExtension().data()); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::AddUserContentExtensions({ pair }), m_identifier); +} + +void WebUserContentControllerProxy::removeUserContentExtension(const String& name) +{ + m_userContentExtensions.remove(name); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveUserContentExtension(name), m_identifier); +} + +void WebUserContentControllerProxy::removeAllUserContentExtensions() +{ + m_userContentExtensions.clear(); + + for (WebProcessProxy* process : m_processes) + process->connection()->send(Messages::WebUserContentController::RemoveAllUserContentExtensions(), m_identifier); +} +#endif + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h new file mode 100644 index 000000000..9526207e9 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebUserContentControllerProxy_h +#define WebUserContentControllerProxy_h + +#include "APIObject.h" +#include "MessageReceiver.h" +#include <wtf/Forward.h> +#include <wtf/HashCountedSet.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/Ref.h> +#include <wtf/RefCounted.h> +#include <wtf/text/StringHash.h> + +namespace API { +class Array; +class UserContentWorld; +class UserContentExtension; +class UserScript; +class UserStyleSheet; +} + +namespace IPC { +class DataReference; +} + +namespace WebCore { +struct SecurityOriginData; +} + +namespace WebKit { + +class WebProcessProxy; +class WebScriptMessageHandler; +struct FrameInfoData; + +class WebUserContentControllerProxy : public API::ObjectImpl<API::Object::Type::UserContentController>, private IPC::MessageReceiver { +public: + static Ref<WebUserContentControllerProxy> create() + { + return adoptRef(*new WebUserContentControllerProxy); + } + explicit WebUserContentControllerProxy(); + ~WebUserContentControllerProxy(); + + uint64_t identifier() const { return m_identifier; } + + void addProcess(WebProcessProxy&); + void removeProcess(WebProcessProxy&); + + API::Array& userScripts() { return m_userScripts.get(); } + void addUserScript(API::UserScript&); + void removeUserScript(API::UserScript&); + void removeAllUserScripts(API::UserContentWorld&); + void removeAllUserScripts(); + + API::Array& userStyleSheets() { return m_userStyleSheets.get(); } + void addUserStyleSheet(API::UserStyleSheet&); + void removeUserStyleSheet(API::UserStyleSheet&); + void removeAllUserStyleSheets(API::UserContentWorld&); + void removeAllUserStyleSheets(); + + void removeAllUserContent(API::UserContentWorld&); + + // Returns false if there was a name conflict. + bool addUserScriptMessageHandler(WebScriptMessageHandler&); + void removeUserMessageHandlerForName(const String&, API::UserContentWorld&); + void removeAllUserMessageHandlers(API::UserContentWorld&); + +#if ENABLE(CONTENT_EXTENSIONS) + void addUserContentExtension(API::UserContentExtension&); + void removeUserContentExtension(const String&); + void removeAllUserContentExtensions(); +#endif + +private: + // IPC::MessageReceiver. + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + + void didPostMessage(IPC::Connection&, uint64_t pageID, const FrameInfoData&, uint64_t messageHandlerID, const IPC::DataReference&); + + void addUserContentWorldUse(API::UserContentWorld&); + void removeUserContentWorldUses(API::UserContentWorld&, unsigned numberOfUsesToRemove); + void removeUserContentWorldUses(HashCountedSet<RefPtr<API::UserContentWorld>>&); + bool shouldSendRemoveUserContentWorldsMessage(API::UserContentWorld&, unsigned numberOfUsesToRemove); + + uint64_t m_identifier; + HashSet<WebProcessProxy*> m_processes; + Ref<API::Array> m_userScripts; + Ref<API::Array> m_userStyleSheets; + HashMap<uint64_t, RefPtr<WebScriptMessageHandler>> m_scriptMessageHandlers; + HashCountedSet<RefPtr<API::UserContentWorld>> m_userContentWorlds; + +#if ENABLE(CONTENT_EXTENSIONS) + HashMap<String, RefPtr<API::UserContentExtension>> m_userContentExtensions; +#endif +}; + +} // namespace WebKit + +#endif // WebUserContentControllerProxy_h diff --git a/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.messages.in b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.messages.in new file mode 100644 index 000000000..81714351f --- /dev/null +++ b/Source/WebKit2/UIProcess/UserContent/WebUserContentControllerProxy.messages.in @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +messages -> WebUserContentControllerProxy { +DidPostMessage(uint64_t pageID, struct WebKit::FrameInfoData frameInfoData, uint64_t messageHandlerID, IPC::DataReference message) WantsConnection +} diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp b/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp new file mode 100644 index 000000000..7045f5aa0 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015-2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UserMediaPermissionCheckProxy.h" + +#include "UserMediaPermissionRequestManagerProxy.h" + +namespace WebKit { + +UserMediaPermissionCheckProxy::UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID) + : m_manager(&manager) + , m_userMediaID(userMediaID) +{ +} + +void UserMediaPermissionCheckProxy::setUserMediaAccessInfo(const String& mediaDeviceIdentifierHashSalt, bool allowed) +{ + ASSERT(m_manager); + if (!m_manager) + return; + + m_manager->didCompleteUserMediaPermissionCheck(m_userMediaID, mediaDeviceIdentifierHashSalt, allowed); + m_manager = nullptr; +} + +void UserMediaPermissionCheckProxy::invalidate() +{ + m_manager = nullptr; +} + +} // namespace WebKit + diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h b/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h new file mode 100644 index 000000000..bcce0a9b3 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionCheckProxy.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015-2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UserMediaPermissionCheckProxy_h +#define UserMediaPermissionCheckProxy_h + +#include "APIObject.h" +#include <wtf/text/WTFString.h> + +namespace WebKit { + +class UserMediaPermissionRequestManagerProxy; + +class UserMediaPermissionCheckProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionCheck> { +public: + static Ref<UserMediaPermissionCheckProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID) + { + return adoptRef(*new UserMediaPermissionCheckProxy(manager, userMediaID)); + } + + void setUserMediaAccessInfo(const String&, bool allowed); + void invalidate(); + +private: + UserMediaPermissionCheckProxy(UserMediaPermissionRequestManagerProxy&, uint64_t); + + UserMediaPermissionRequestManagerProxy* m_manager; + uint64_t m_userMediaID; +}; + +} // namespace WebKit + +#endif // UserMediaPermissionCheckProxy_h diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp b/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp new file mode 100644 index 000000000..af584dc49 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.cpp @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "UserMediaPermissionRequestManagerProxy.h" + +#include "APISecurityOrigin.h" +#include "APIUIClient.h" +#include "UserMediaProcessManager.h" +#include "WebPageMessages.h" +#include "WebPageProxy.h" +#include "WebProcessProxy.h" +#include <WebCore/MediaConstraintsImpl.h> +#include <WebCore/MockRealtimeMediaSourceCenter.h> +#include <WebCore/RealtimeMediaSource.h> +#include <WebCore/SecurityOriginData.h> + +using namespace WebCore; + +namespace WebKit { + +FrameAuthorizationState::FrameAuthorizationState(UserMediaPermissionRequestProxy& request) + : m_userMediaDocumentSecurityOrigin(request.userMediaDocumentSecurityOrigin()) + , m_topLevelDocumentSecurityOrigin(request.topLevelDocumentSecurityOrigin()) +{ +} + +bool FrameAuthorizationState::hasPermissionToUseCaptureDevice(const String& deviceUID) +{ + return m_authorizedDeviceUIDs.find(deviceUID) != notFound; +} + +void FrameAuthorizationState::setHasPermissionToUseCaptureDevice(const String& deviceUID, bool hasPermission) +{ + if (deviceUID.isEmpty()) + return; + + size_t index = m_authorizedDeviceUIDs.find(deviceUID); + if (hasPermission == (index != notFound)) + return; + + if (hasPermission) + m_authorizedDeviceUIDs.append(deviceUID); + else + m_authorizedDeviceUIDs.remove(index); +} + +void FrameAuthorizationState::ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy& request) +{ + do { + if (!m_userMediaDocumentSecurityOrigin || !m_userMediaDocumentSecurityOrigin->equal(request.userMediaDocumentSecurityOrigin())) + break; + + if (!m_topLevelDocumentSecurityOrigin || !m_topLevelDocumentSecurityOrigin->equal(request.topLevelDocumentSecurityOrigin())) + break; + + return; + } while (0); + + m_userMediaDocumentSecurityOrigin = request.userMediaDocumentSecurityOrigin(); + m_topLevelDocumentSecurityOrigin = request.topLevelDocumentSecurityOrigin(); + m_authorizedDeviceUIDs.clear(); +} + +FrameAuthorizationState& UserMediaPermissionRequestManagerProxy::stateForRequest(UserMediaPermissionRequestProxy& request) +{ + auto& state = m_frameStates.add(request.frameID(), nullptr).iterator->value; + if (state) { + state->ensureSecurityOriginsAreEqual(request); + return *state; + } + + state = std::make_unique<FrameAuthorizationState>(request); + return *state; +} + +UserMediaPermissionRequestManagerProxy::UserMediaPermissionRequestManagerProxy(WebPageProxy& page) + : m_page(page) +{ +#if ENABLE(MEDIA_STREAM) + UserMediaProcessManager::singleton().addUserMediaPermissionRequestManagerProxy(*this); +#endif +} + +UserMediaPermissionRequestManagerProxy::~UserMediaPermissionRequestManagerProxy() +{ +#if ENABLE(MEDIA_STREAM) + UserMediaProcessManager::singleton().removeUserMediaPermissionRequestManagerProxy(*this); +#endif + invalidateRequests(); +} + +void UserMediaPermissionRequestManagerProxy::invalidateRequests() +{ + for (auto& request : m_pendingUserMediaRequests.values()) + request->invalidate(); + m_pendingUserMediaRequests.clear(); + + for (auto& request : m_pendingDeviceRequests.values()) + request->invalidate(); + m_pendingDeviceRequests.clear(); + + m_frameStates.clear(); +} + +void UserMediaPermissionRequestManagerProxy::clearCachedState() +{ + invalidateRequests(); +} + +Ref<UserMediaPermissionRequestProxy> UserMediaPermissionRequestManagerProxy::createRequest(uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs) +{ + auto request = UserMediaPermissionRequestProxy::create(*this, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioDeviceUIDs, videoDeviceUIDs); + m_pendingUserMediaRequests.add(userMediaID, request.ptr()); + return request; +} + +#if ENABLE(MEDIA_STREAM) +static uint64_t toWebCore(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason) +{ + switch (reason) { + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::NoConstraints); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::UserMediaDisabled); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoCaptureDevices: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::NoCaptureDevices); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::InvalidConstraint); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::HardwareError: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::HardwareError); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::PermissionDenied); + break; + case UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::OtherFailure: + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::OtherFailure); + break; + } + + ASSERT_NOT_REACHED(); + return static_cast<uint64_t>(UserMediaRequest::MediaAccessDenialReason::OtherFailure); +} +#endif + +void UserMediaPermissionRequestManagerProxy::userMediaAccessWasDenied(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason) +{ + if (!m_page.isValid()) + return; + + auto request = m_pendingUserMediaRequests.take(userMediaID); + if (!request) + return; + + auto fameState = stateForRequest(*request); + for (const auto& deviceUID : request->videoDeviceUIDs()) + fameState.setHasPermissionToUseCaptureDevice(deviceUID, false); + for (const auto& deviceUID : request->audioDeviceUIDs()) + fameState.setHasPermissionToUseCaptureDevice(deviceUID, false); + + denyRequest(userMediaID, reason, emptyString()); +} + +void UserMediaPermissionRequestManagerProxy::denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason reason, const String& invalidConstraint) +{ + ASSERT(m_page.isValid()); + +#if ENABLE(MEDIA_STREAM) + m_page.process().send(Messages::WebPage::UserMediaAccessWasDenied(userMediaID, toWebCore(reason), invalidConstraint), m_page.pageID()); +#else + UNUSED_PARAM(reason); + UNUSED_PARAM(invalidConstraint); +#endif +} + +void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t userMediaID, const String& audioDeviceUID, const String& videoDeviceUID) +{ + ASSERT(!audioDeviceUID.isEmpty() || !videoDeviceUID.isEmpty()); + + if (!m_page.isValid()) + return; + +#if ENABLE(MEDIA_STREAM) + auto request = m_pendingUserMediaRequests.take(userMediaID); + if (!request) + return; + + auto& fameState = stateForRequest(*request); + fameState.setHasPermissionToUseCaptureDevice(audioDeviceUID, true); + fameState.setHasPermissionToUseCaptureDevice(videoDeviceUID, true); + + UserMediaProcessManager::singleton().willCreateMediaStream(*this, !audioDeviceUID.isEmpty(), !videoDeviceUID.isEmpty()); + + m_page.process().send(Messages::WebPage::UserMediaAccessWasGranted(userMediaID, audioDeviceUID, videoDeviceUID), m_page.pageID()); +#else + UNUSED_PARAM(userMediaID); + UNUSED_PARAM(audioDeviceUID); + UNUSED_PARAM(videoDeviceUID); +#endif +} + +void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraintsData, const WebCore::MediaConstraintsData& videoConstraintsData) +{ +#if ENABLE(MEDIA_STREAM) + auto invalidHandler = [this, userMediaID](const String& invalidConstraint) { + if (!m_page.isValid()) + return; + + denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::InvalidConstraint, invalidConstraint); + }; + + auto validHandler = [this, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier](const Vector<String>&& audioDeviceUIDs, const Vector<String>&& videoDeviceUIDs) { + if (!m_page.isValid()) + return; + + if (videoDeviceUIDs.isEmpty() && audioDeviceUIDs.isEmpty()) { + denyRequest(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints, emptyString()); + return; + } + + auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin()); + auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin()); + auto request = createRequest(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioDeviceUIDs, videoDeviceUIDs); + + String authorizedAudioDevice; + String authorizedVideoDevice; + auto& fameState = stateForRequest(request); + for (auto deviceUID : audioDeviceUIDs) { + if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) { + authorizedAudioDevice = deviceUID; + break; + } + } + for (auto deviceUID : videoDeviceUIDs) { + if (fameState.hasPermissionToUseCaptureDevice(deviceUID)) { + authorizedVideoDevice = deviceUID; + break; + } + } + + if (audioDeviceUIDs.isEmpty() == authorizedAudioDevice.isEmpty() && videoDeviceUIDs.isEmpty() == authorizedVideoDevice.isEmpty()) { + userMediaAccessWasGranted(userMediaID, authorizedAudioDevice, authorizedVideoDevice); + return; + } + + if (!m_page.uiClient().decidePolicyForUserMediaPermissionRequest(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) + userMediaAccessWasDenied(userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled); + + }; + + auto audioConstraints = MediaConstraintsImpl::create(audioConstraintsData); + auto videoConstraints = MediaConstraintsImpl::create(videoConstraintsData); + + syncWithWebCorePrefs(); + RealtimeMediaSourceCenter::singleton().validateRequestConstraints(validHandler, invalidHandler, audioConstraints, videoConstraints); +#else + UNUSED_PARAM(userMediaID); + UNUSED_PARAM(frameID); + UNUSED_PARAM(userMediaDocumentOriginIdentifier); + UNUSED_PARAM(topLevelDocumentOriginIdentifier); + UNUSED_PARAM(audioConstraintsData); + UNUSED_PARAM(videoConstraintsData); +#endif +} + +void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier) +{ +#if ENABLE(MEDIA_STREAM) + auto request = UserMediaPermissionCheckProxy::create(*this, userMediaID); + m_pendingDeviceRequests.add(userMediaID, request.ptr()); + + auto userMediaOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin()); + auto topLevelOrigin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier).value_or(SecurityOriginData()).securityOrigin()); + + if (!m_page.uiClient().checkUserMediaPermissionForOrigin(m_page, *m_page.process().webFrame(frameID), *userMediaOrigin.get(), *topLevelOrigin.get(), request.get())) { + m_pendingDeviceRequests.take(userMediaID); + m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, Vector<WebCore::CaptureDevice>(), emptyString(), false), m_page.pageID()); + } +#else + UNUSED_PARAM(userMediaID); + UNUSED_PARAM(frameID); + UNUSED_PARAM(userMediaDocumentOriginIdentifier); + UNUSED_PARAM(topLevelDocumentOriginIdentifier); +#endif +} + +void UserMediaPermissionRequestManagerProxy::didCompleteUserMediaPermissionCheck(uint64_t userMediaID, const String& deviceIdentifierHashSalt, bool originHasPersistentAccess) +{ + if (!m_page.isValid()) + return; + + if (!m_pendingDeviceRequests.take(userMediaID)) + return; + +#if ENABLE(MEDIA_STREAM) + syncWithWebCorePrefs(); + auto deviceInfo = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices(); + m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, deviceInfo, deviceIdentifierHashSalt, originHasPersistentAccess), m_page.pageID()); +#else + UNUSED_PARAM(deviceIdentifierHashSalt); + UNUSED_PARAM(originHasPersistentAccess); +#endif +} + +void UserMediaPermissionRequestManagerProxy::syncWithWebCorePrefs() const +{ +#if ENABLE(MEDIA_STREAM) + // Enable/disable the mock capture devices for the UI process as per the WebCore preferences. Note that + // this is a noop if the preference hasn't changed since the last time this was called. + bool mockDevicesEnabled = m_page.preferences().mockCaptureDevicesEnabled(); + WebCore::MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(mockDevicesEnabled); +#endif +} + +void UserMediaPermissionRequestManagerProxy::stopCapture() +{ + if (!m_page.isValid()) + return; + +#if ENABLE(MEDIA_STREAM) + m_page.setMuted(WebCore::MediaProducer::CaptureDevicesAreMuted); +#endif +} + +void UserMediaPermissionRequestManagerProxy::startedCaptureSession() +{ + if (!m_page.isValid()) + return; + +#if ENABLE(MEDIA_STREAM) + UserMediaProcessManager::singleton().startedCaptureSession(*this); +#endif +} + +void UserMediaPermissionRequestManagerProxy::endedCaptureSession() +{ + if (!m_page.isValid()) + return; + +#if ENABLE(MEDIA_STREAM) + UserMediaProcessManager::singleton().endedCaptureSession(*this); +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h b/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h new file mode 100644 index 000000000..e5fd48acf --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionRequestManagerProxy.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UserMediaPermissionRequestManagerProxy_h +#define UserMediaPermissionRequestManagerProxy_h + +#include "UserMediaPermissionCheckProxy.h" +#include "UserMediaPermissionRequestProxy.h" +#include <WebCore/SecurityOrigin.h> +#include <WebCore/UserMediaRequest.h> +#include <wtf/HashMap.h> + +namespace WebCore { +class CaptureDevice; +struct MediaConstraintsData; +}; + +namespace WebKit { + +class WebPageProxy; + +class FrameAuthorizationState { +public: + explicit FrameAuthorizationState(UserMediaPermissionRequestProxy&); + + bool hasPermissionToUseCaptureDevice(const String& deviceUID); + void setHasPermissionToUseCaptureDevice(const String&, bool); + + void ensureSecurityOriginsAreEqual(UserMediaPermissionRequestProxy&); + +private: + RefPtr<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin; + RefPtr<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin; + Vector<String> m_authorizedDeviceUIDs; +}; + +class UserMediaPermissionRequestManagerProxy { +public: + explicit UserMediaPermissionRequestManagerProxy(WebPageProxy&); + ~UserMediaPermissionRequestManagerProxy(); + + WebPageProxy& page() const { return m_page; } + + void invalidateRequests(); + + void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraintsData, const WebCore::MediaConstraintsData& videoConstraintsData); + + void userMediaAccessWasGranted(uint64_t, const String& audioDeviceUID, const String& videoDeviceUID); + void userMediaAccessWasDenied(uint64_t, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason); + FrameAuthorizationState& stateForRequest(UserMediaPermissionRequestProxy&); + + void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier); + + void didCompleteUserMediaPermissionCheck(uint64_t, const String&, bool allow); + + void clearCachedState(); + + void startedCaptureSession(); + void endedCaptureSession(); + void stopCapture(); + +private: + Ref<UserMediaPermissionRequestProxy> createRequest(uint64_t userMediaID, uint64_t frameID, const String&userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs); + void denyRequest(uint64_t userMediaID, UserMediaPermissionRequestProxy::UserMediaAccessDenialReason, const String& invalidConstraint); + Ref<UserMediaPermissionCheckProxy> createUserMediaPermissionCheck(uint64_t userMediaID); + void syncWithWebCorePrefs() const; + + HashMap<uint64_t, RefPtr<UserMediaPermissionRequestProxy>> m_pendingUserMediaRequests; + HashMap<uint64_t, RefPtr<UserMediaPermissionCheckProxy>> m_pendingDeviceRequests; + HashMap<uint64_t, std::unique_ptr<FrameAuthorizationState>> m_frameStates; + + WebPageProxy& m_page; +}; + +} // namespace WebKit + +#endif // UserMediaPermissionRequestManagerProxy_h diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp b/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp new file mode 100644 index 000000000..9037d5a87 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "UserMediaPermissionRequestProxy.h" + +#include "UserMediaPermissionRequestManagerProxy.h" +#include <WebCore/RealtimeMediaSourceCenter.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginData.h> +#include <wtf/text/StringHash.h> + +using namespace WebCore; + +namespace WebKit { + +UserMediaPermissionRequestProxy::UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& audioDeviceUIDs, const Vector<String>& videoDeviceUIDs) + : m_manager(&manager) + , m_userMediaID(userMediaID) + , m_frameID(frameID) + , m_userMediaDocumentSecurityOrigin((SecurityOriginData::fromDatabaseIdentifier(userMediaDocumentOriginIdentifier)->securityOrigin())) + , m_topLevelDocumentSecurityOrigin(SecurityOriginData::fromDatabaseIdentifier(topLevelDocumentOriginIdentifier)->securityOrigin()) + , m_videoDeviceUIDs(videoDeviceUIDs) + , m_audioDeviceUIDs(audioDeviceUIDs) +{ +} + +void UserMediaPermissionRequestProxy::allow(const String& audioDeviceUID, const String& videoDeviceUID) +{ + ASSERT(m_manager); + if (!m_manager) + return; + + m_manager->userMediaAccessWasGranted(m_userMediaID, audioDeviceUID, videoDeviceUID); + invalidate(); +} + +void UserMediaPermissionRequestProxy::deny(UserMediaAccessDenialReason reason) +{ + if (!m_manager) + return; + + m_manager->userMediaAccessWasDenied(m_userMediaID, reason); + invalidate(); +} + +void UserMediaPermissionRequestProxy::invalidate() +{ + m_manager = nullptr; +} + +} // namespace WebKit + diff --git a/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h b/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h new file mode 100644 index 000000000..b2c25c5c6 --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaPermissionRequestProxy.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UserMediaPermissionRequestProxy_h +#define UserMediaPermissionRequestProxy_h + +#include "APIObject.h" +#include <WebCore/UserMediaRequest.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class SecurityOrigin; +} + +namespace WebKit { + +class UserMediaPermissionRequestManagerProxy; + +class UserMediaPermissionRequestProxy : public API::ObjectImpl<API::Object::Type::UserMediaPermissionRequest> { +public: + static Ref<UserMediaPermissionRequestProxy> create(UserMediaPermissionRequestManagerProxy& manager, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs) + { + return adoptRef(*new UserMediaPermissionRequestProxy(manager, userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, videoDeviceUIDs, audioDeviceUIDs)); + } + + void allow(const String& videoDeviceUID, const String& audioDeviceUID); + + enum class UserMediaAccessDenialReason { NoConstraints, UserMediaDisabled, NoCaptureDevices, InvalidConstraint, HardwareError, PermissionDenied, OtherFailure }; + void deny(UserMediaAccessDenialReason); + + void invalidate(); + + bool requiresAudio() const { return m_audioDeviceUIDs.size(); } + bool requiresVideo() const { return m_videoDeviceUIDs.size(); } + + const Vector<String>& videoDeviceUIDs() const { return m_videoDeviceUIDs; } + const Vector<String>& audioDeviceUIDs() const { return m_audioDeviceUIDs; } + + uint64_t frameID() const { return m_frameID; } + WebCore::SecurityOrigin* userMediaDocumentSecurityOrigin() { return &m_userMediaDocumentSecurityOrigin.get(); } + WebCore::SecurityOrigin* topLevelDocumentSecurityOrigin() { return &m_topLevelDocumentSecurityOrigin.get(); } + +private: + UserMediaPermissionRequestProxy(UserMediaPermissionRequestManagerProxy&, uint64_t userMediaID, uint64_t frameID, const String& userMediaDocumentOriginIdentifier, const String& topLevelDocumentOriginIdentifier, const Vector<String>& videoDeviceUIDs, const Vector<String>& audioDeviceUIDs); + + UserMediaPermissionRequestManagerProxy* m_manager; + uint64_t m_userMediaID; + uint64_t m_frameID; + Ref<WebCore::SecurityOrigin> m_userMediaDocumentSecurityOrigin; + Ref<WebCore::SecurityOrigin> m_topLevelDocumentSecurityOrigin; + Vector<String> m_videoDeviceUIDs; + Vector<String> m_audioDeviceUIDs; +}; + +} // namespace WebKit + +#endif // UserMediaPermissionRequestProxy_h diff --git a/Source/WebKit2/UIProcess/UserMediaProcessManager.cpp b/Source/WebKit2/UIProcess/UserMediaProcessManager.cpp new file mode 100644 index 000000000..a0af85f6e --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaProcessManager.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "UserMediaProcessManager.h" + +#if ENABLE(MEDIA_STREAM) + +#include "MediaDeviceSandboxExtensions.h" +#include "WebPageMessages.h" +#include "WebPageProxy.h" +#include "WebProcessProxy.h" +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> + +namespace WebKit { + +static const char* const audioExtensionPath = "com.apple.webkit.microphone"; +static const char* const videoExtensionPath = "com.apple.webkit.camera"; + +class ProcessState { +public: + ProcessState() { } + ProcessState(const ProcessState&) = delete; + + void addRequestManager(UserMediaPermissionRequestManagerProxy&); + void removeRequestManager(UserMediaPermissionRequestManagerProxy&); + Vector<UserMediaPermissionRequestManagerProxy*>& managers() { return m_managers; } + + enum SandboxExtensionsGranted { + None = 0, + Video = 1 << 0, + Audio = 1 << 1 + }; + + SandboxExtensionsGranted sandboxExtensionsGranted() { return m_pageSandboxExtensionsGranted; } + void setSandboxExtensionsGranted(unsigned granted) { m_pageSandboxExtensionsGranted = static_cast<SandboxExtensionsGranted>(granted); } + +private: + Vector<UserMediaPermissionRequestManagerProxy*> m_managers; + SandboxExtensionsGranted m_pageSandboxExtensionsGranted { SandboxExtensionsGranted::None }; +}; + +static HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>& stateMap() +{ + static NeverDestroyed<HashMap<WebProcessProxy*, std::unique_ptr<ProcessState>>> map; + return map; +} + +static ProcessState& processState(WebProcessProxy& process) +{ + auto& state = stateMap().add(&process, nullptr).iterator->value; + if (state) + return *state; + + state = std::make_unique<ProcessState>(); + return *state; +} + +void ProcessState::addRequestManager(UserMediaPermissionRequestManagerProxy& proxy) +{ + ASSERT(!m_managers.contains(&proxy)); + m_managers.append(&proxy); +} + +void ProcessState::removeRequestManager(UserMediaPermissionRequestManagerProxy& proxy) +{ + ASSERT(m_managers.contains(&proxy)); + m_managers.removeFirstMatching([&proxy](auto other) { + return other == &proxy; + }); +} + +UserMediaProcessManager& UserMediaProcessManager::singleton() +{ + static NeverDestroyed<UserMediaProcessManager> manager; + return manager; +} + +void UserMediaProcessManager::addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy) +{ + processState(proxy.page().process()).addRequestManager(proxy); +} + +void UserMediaProcessManager::removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy& proxy) +{ + endedCaptureSession(proxy); + + auto& state = processState(proxy.page().process()); + state.removeRequestManager(proxy); + if (state.managers().isEmpty()) { + auto it = stateMap().find(&proxy.page().process()); + stateMap().remove(it); + } +} + +void UserMediaProcessManager::willCreateMediaStream(UserMediaPermissionRequestManagerProxy& proxy, bool withAudio, bool withVideo) +{ +#if ENABLE(SANDBOX_EXTENSIONS) + ASSERT(stateMap().contains(&proxy.page().process())); + + auto& state = processState(proxy.page().process()); + size_t extensionCount = 0; + unsigned requiredExtensions = ProcessState::SandboxExtensionsGranted::None; + + if (withAudio) { + requiredExtensions |= ProcessState::SandboxExtensionsGranted::Audio; + extensionCount++; + } + if (withVideo) { + requiredExtensions |= ProcessState::SandboxExtensionsGranted::Video; + extensionCount++; + } + + unsigned currentExtensions = state.sandboxExtensionsGranted(); + if (!(requiredExtensions & currentExtensions)) { + SandboxExtension::HandleArray handles; + handles.allocate(extensionCount); + + Vector<String> ids; + ids.reserveCapacity(extensionCount); + + if (withAudio && requiredExtensions & ProcessState::SandboxExtensionsGranted::Audio) { + if (SandboxExtension::createHandleForGenericExtension(audioExtensionPath, handles[--extensionCount])) { + ids.append(ASCIILiteral(audioExtensionPath)); + currentExtensions |= ProcessState::SandboxExtensionsGranted::Audio; + } + } + + if (withVideo && requiredExtensions & ProcessState::SandboxExtensionsGranted::Video) { + if (SandboxExtension::createHandleForGenericExtension(videoExtensionPath, handles[--extensionCount])) { + ids.append(ASCIILiteral(videoExtensionPath)); + currentExtensions |= ProcessState::SandboxExtensionsGranted::Video; + } + } + + state.setSandboxExtensionsGranted(currentExtensions); + proxy.page().process().send(Messages::WebPage::GrantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions(ids, WTFMove(handles))), proxy.page().pageID()); + } +#endif +} + +void UserMediaProcessManager::startedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy) +{ + ASSERT(stateMap().contains(&proxy.page().process())); +} + +void UserMediaProcessManager::endedCaptureSession(UserMediaPermissionRequestManagerProxy& proxy) +{ +#if ENABLE(SANDBOX_EXTENSIONS) + ASSERT(stateMap().contains(&proxy.page().process())); + + auto& state = processState(proxy.page().process()); + bool hasAudioCapture = false; + bool hasVideoCapture = false; + for (auto& manager : state.managers()) { + if (manager->page().hasActiveAudioStream()) + hasAudioCapture = true; + if (manager->page().hasActiveVideoStream()) + hasVideoCapture = true; + } + + if (hasAudioCapture && hasVideoCapture) + return; + + Vector<String> params; + unsigned currentExtensions = state.sandboxExtensionsGranted(); + if (!hasAudioCapture && currentExtensions & ProcessState::SandboxExtensionsGranted::Audio) { + params.append(ASCIILiteral(audioExtensionPath)); + currentExtensions &= ~ProcessState::SandboxExtensionsGranted::Audio; + } + if (!hasVideoCapture && currentExtensions & ProcessState::SandboxExtensionsGranted::Video) { + params.append(ASCIILiteral(videoExtensionPath)); + currentExtensions &= ~ProcessState::SandboxExtensionsGranted::Video; + } + + if (params.isEmpty()) + return; + + state.setSandboxExtensionsGranted(currentExtensions); + proxy.page().process().send(Messages::WebPage::RevokeUserMediaDeviceSandboxExtensions(params), proxy.page().pageID()); +#endif +} + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/UIProcess/UserMediaProcessManager.h b/Source/WebKit2/UIProcess/UserMediaProcessManager.h new file mode 100644 index 000000000..4e450bc9f --- /dev/null +++ b/Source/WebKit2/UIProcess/UserMediaProcessManager.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#if ENABLE(MEDIA_STREAM) + +#include "UserMediaPermissionRequestManagerProxy.h" + +namespace WebKit { + +class WebProcessProxy; + +class UserMediaProcessManager { +public: + + static UserMediaProcessManager& singleton(); + + void addUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&); + void removeUserMediaPermissionRequestManagerProxy(UserMediaPermissionRequestManagerProxy&); + + void willCreateMediaStream(UserMediaPermissionRequestManagerProxy&, bool withAudio, bool withVideo); + + void startedCaptureSession(UserMediaPermissionRequestManagerProxy&); + void endedCaptureSession(UserMediaPermissionRequestManagerProxy&); +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/UIProcess/VisitedLinkProvider.cpp b/Source/WebKit2/UIProcess/VisitedLinkProvider.cpp deleted file mode 100644 index 7ecae847c..000000000 --- a/Source/WebKit2/UIProcess/VisitedLinkProvider.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "VisitedLinkProvider.h" - -#include "SharedMemory.h" -#include "VisitedLinkTable.h" -#include "WebContext.h" -#include "WebProcessMessages.h" - -using namespace WebCore; - -namespace WebKit { - -static const int VisitedLinkTableMaxLoad = 2; - -VisitedLinkProvider::VisitedLinkProvider(WebContext* context) - : m_context(context) - , m_visitedLinksPopulated(false) - , m_keyCount(0) - , m_tableSize(0) - , m_pendingVisitedLinksTimer(RunLoop::main(), this, &VisitedLinkProvider::pendingVisitedLinksTimerFired) -{ -} - -void VisitedLinkProvider::processDidFinishLaunching(WebProcessProxy* process) -{ - m_processesWithoutVisitedLinkState.add(process); - - if (m_keyCount) - m_pendingVisitedLinksTimer.startOneShot(0); - - if (m_visitedLinksPopulated) - return; - - m_context->populateVisitedLinks(); - - m_visitedLinksPopulated = true; -} - -void VisitedLinkProvider::addVisitedLink(LinkHash linkHash) -{ - m_pendingVisitedLinks.add(linkHash); - - if (!m_pendingVisitedLinksTimer.isActive()) - m_pendingVisitedLinksTimer.startOneShot(0); -} - -void VisitedLinkProvider::processDidClose(WebProcessProxy* process) -{ - m_processesWithVisitedLinkState.remove(process); - m_processesWithoutVisitedLinkState.remove(process); -} - -static unsigned nextPowerOf2(unsigned v) -{ - // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html - // Devised by Sean Anderson, Sepember 14, 2001 - - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - - return v; -} - -static unsigned tableSizeForKeyCount(unsigned keyCount) -{ - // We want the table to be at least half empty. - unsigned tableSize = nextPowerOf2(keyCount * VisitedLinkTableMaxLoad); - - // Ensure that the table size is at least the size of a page. - size_t minimumTableSize = SharedMemory::systemPageSize() / sizeof(LinkHash); - if (tableSize < minimumTableSize) - return minimumTableSize; - - return tableSize; -} - -void VisitedLinkProvider::pendingVisitedLinksTimerFired() -{ - Vector<WebCore::LinkHash> pendingVisitedLinks; - copyToVector(m_pendingVisitedLinks, pendingVisitedLinks); - m_pendingVisitedLinks.clear(); - - unsigned currentTableSize = m_tableSize; - - // Upper bound on needed size - some of the links may be duplicates, in which case we could have done with less. - unsigned newTableSize = tableSizeForKeyCount(m_keyCount + pendingVisitedLinks.size()); - - // Never decrease table size when adding to it, to avoid unneeded churn. - newTableSize = std::max(currentTableSize, newTableSize); - - // Links that were added. - Vector<WebCore::LinkHash> addedVisitedLinks; - - // VisitedLinkTable remains internally consistent when adding, so it's OK to modify it in place - // even if a web process is accessing it at the same time. - if (currentTableSize != newTableSize) { - RefPtr<SharedMemory> newTableMemory = SharedMemory::create(newTableSize * sizeof(LinkHash)); - - // We failed to create the shared memory. - if (!newTableMemory) { - LOG_ERROR("Could not allocate shared memory for visited link table"); - return; - } - - memset(newTableMemory->data(), 0, newTableMemory->size()); - - RefPtr<SharedMemory> currentTableMemory = m_table.sharedMemory(); - - m_table.setSharedMemory(newTableMemory); - m_tableSize = newTableSize; - - if (currentTableMemory) { - ASSERT(currentTableMemory->size() == currentTableSize * sizeof(LinkHash)); - - // Go through the current hash table and re-add all entries to the new hash table. - const LinkHash* currentLinkHashes = static_cast<const LinkHash*>(currentTableMemory->data()); - for (unsigned i = 0; i < currentTableSize; ++i) { - LinkHash linkHash = currentLinkHashes[i]; - - if (!linkHash) - continue; - - // It should always be possible to add the link hash to a new table. - if (!m_table.addLinkHash(linkHash)) - ASSERT_NOT_REACHED(); - } - } - } - - for (size_t i = 0; i < pendingVisitedLinks.size(); ++i) { - if (m_table.addLinkHash(pendingVisitedLinks[i])) - addedVisitedLinks.append(pendingVisitedLinks[i]); - } - - m_keyCount += pendingVisitedLinks.size(); - - - for (HashSet<WebProcessProxy*>::iterator iter = m_processesWithVisitedLinkState.begin(); iter != m_processesWithVisitedLinkState.end(); ++iter) { - WebProcessProxy* process = *iter; - if (currentTableSize != newTableSize) { - // In the rare case of needing to resize the table, we'll bypass the VisitedLinkStateChanged optimization, - // and unconditionally use AllVisitedLinkStateChanged for the process. - m_processesWithoutVisitedLinkState.add(process); - continue; - } - - if (addedVisitedLinks.size() <= 20) - process->send(Messages::WebProcess::VisitedLinkStateChanged(addedVisitedLinks), 0); - else - process->send(Messages::WebProcess::AllVisitedLinkStateChanged(), 0); - } - - for (HashSet<WebProcessProxy*>::iterator iter = m_processesWithoutVisitedLinkState.begin(); iter != m_processesWithoutVisitedLinkState.end(); ++iter) { - WebProcessProxy* process = *iter; - - SharedMemory::Handle handle; - if (!m_table.sharedMemory()->createHandle(handle, SharedMemory::ReadOnly)) - return; - - process->send(Messages::WebProcess::SetVisitedLinkTable(handle), 0); - process->send(Messages::WebProcess::AllVisitedLinkStateChanged(), 0); - - m_processesWithVisitedLinkState.add(process); - } - - m_processesWithoutVisitedLinkState.clear(); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/VisitedLinkStore.cpp b/Source/WebKit2/UIProcess/VisitedLinkStore.cpp new file mode 100644 index 000000000..a3fb770f5 --- /dev/null +++ b/Source/WebKit2/UIProcess/VisitedLinkStore.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "VisitedLinkStore.h" + +#include "SharedMemory.h" +#include "VisitedLinkStoreMessages.h" +#include "VisitedLinkTable.h" +#include "VisitedLinkTableControllerMessages.h" +#include "WebProcessMessages.h" +#include "WebProcessPool.h" +#include "WebProcessProxy.h" + +using namespace WebCore; + +namespace WebKit { + +static const int visitedLinkTableMaxLoad = 2; + +static uint64_t generateIdentifier() +{ + static uint64_t identifier; + + return ++identifier; +} + +Ref<VisitedLinkStore> VisitedLinkStore::create() +{ + return adoptRef(*new VisitedLinkStore); +} + +VisitedLinkStore::~VisitedLinkStore() +{ + for (WebProcessProxy* process : m_processes) { + process->removeMessageReceiver(Messages::VisitedLinkStore::messageReceiverName(), m_identifier); + process->didDestroyVisitedLinkStore(*this); + } +} + +VisitedLinkStore::VisitedLinkStore() + : m_identifier(generateIdentifier()) + , m_keyCount(0) + , m_tableSize(0) + , m_pendingVisitedLinksTimer(RunLoop::main(), this, &VisitedLinkStore::pendingVisitedLinksTimerFired) +{ +} + +void VisitedLinkStore::addProcess(WebProcessProxy& process) +{ + ASSERT(process.state() == WebProcessProxy::State::Running); + + if (!m_processes.add(&process).isNewEntry) + return; + + process.addMessageReceiver(Messages::VisitedLinkStore::messageReceiverName(), m_identifier, *this); + + if (!m_keyCount) + return; + + ASSERT(m_table.sharedMemory()); + + sendTable(process); +} + +void VisitedLinkStore::removeProcess(WebProcessProxy& process) +{ + ASSERT(m_processes.contains(&process)); + + m_processes.remove(&process); + process.removeMessageReceiver(Messages::VisitedLinkStore::messageReceiverName(), m_identifier); +} + +void VisitedLinkStore::addVisitedLinkHash(LinkHash linkHash) +{ + m_pendingVisitedLinks.add(linkHash); + + if (!m_pendingVisitedLinksTimer.isActive()) + m_pendingVisitedLinksTimer.startOneShot(0); +} + +void VisitedLinkStore::removeAll() +{ + m_pendingVisitedLinksTimer.stop(); + m_pendingVisitedLinks.clear(); + m_keyCount = 0; + m_tableSize = 0; + m_table.clear(); + + for (WebProcessProxy* process : m_processes) { + ASSERT(process->processPool().processes().contains(process)); + process->connection()->send(Messages::VisitedLinkTableController::RemoveAllVisitedLinks(), m_identifier); + } +} + +void VisitedLinkStore::webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) +{ + // FIXME: Implement. +} + +void VisitedLinkStore::webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) +{ + // FIXME: Implement. +} + +void VisitedLinkStore::addVisitedLinkHashFromPage(uint64_t pageID, LinkHash linkHash) +{ + if (WebPageProxy* webPageProxy = WebProcessProxy::webPage(pageID)) { + if (!webPageProxy->addsVisitedLinks()) + return; + } + + addVisitedLinkHash(linkHash); +} + +static unsigned nextPowerOf2(unsigned v) +{ + // Taken from http://www.cs.utk.edu/~vose/c-stuff/bithacks.html + // Devised by Sean Anderson, Sepember 14, 2001 + + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + + return v; +} + +static unsigned tableSizeForKeyCount(unsigned keyCount) +{ + // We want the table to be at least half empty. + unsigned tableSize = nextPowerOf2(keyCount * visitedLinkTableMaxLoad); + + // Ensure that the table size is at least the size of a page. + size_t minimumTableSize = SharedMemory::systemPageSize() / sizeof(LinkHash); + if (tableSize < minimumTableSize) + return minimumTableSize; + + return tableSize; +} + +void VisitedLinkStore::pendingVisitedLinksTimerFired() +{ + unsigned currentTableSize = m_tableSize; + unsigned newTableSize = tableSizeForKeyCount(m_keyCount + m_pendingVisitedLinks.size()); + + newTableSize = std::max(currentTableSize, newTableSize); + + if (currentTableSize != newTableSize) { + resizeTable(newTableSize); + return; + } + + Vector<WebCore::LinkHash> addedVisitedLinks; + + for (auto& linkHash : m_pendingVisitedLinks) { + if (m_table.addLinkHash(linkHash)) { + addedVisitedLinks.append(linkHash); + ++m_keyCount; + } + } + + m_pendingVisitedLinks.clear(); + + if (addedVisitedLinks.isEmpty()) + return; + + for (WebProcessProxy* process : m_processes) { + ASSERT(process->processPool().processes().contains(process)); + + if (addedVisitedLinks.size() > 20) + process->connection()->send(Messages::VisitedLinkTableController::AllVisitedLinkStateChanged(), m_identifier); + else + process->connection()->send(Messages::VisitedLinkTableController::VisitedLinkStateChanged(addedVisitedLinks), m_identifier); + } +} + +void VisitedLinkStore::resizeTable(unsigned newTableSize) +{ + RefPtr<SharedMemory> newTableMemory = SharedMemory::allocate(newTableSize * sizeof(LinkHash)); + + if (!newTableMemory) { + LOG_ERROR("Could not allocate shared memory for visited link table"); + return; + } + + memset(newTableMemory->data(), 0, newTableMemory->size()); + + RefPtr<SharedMemory> currentTableMemory = m_table.sharedMemory(); + unsigned currentTableSize = m_tableSize; + + m_table.setSharedMemory(newTableMemory); + m_tableSize = newTableSize; + + if (currentTableMemory) { + ASSERT_UNUSED(currentTableSize, currentTableMemory->size() == currentTableSize * sizeof(LinkHash)); + + // Go through the current hash table and re-add all entries to the new hash table. + const LinkHash* currentLinkHashes = static_cast<const LinkHash*>(currentTableMemory->data()); + for (unsigned i = 0; i < currentTableSize; ++i) { + LinkHash linkHash = currentLinkHashes[i]; + + if (!linkHash) + continue; + + bool didAddLinkHash = m_table.addLinkHash(linkHash); + + // It should always be possible to add the link hash to a new table. + ASSERT_UNUSED(didAddLinkHash, didAddLinkHash); + } + } + + for (auto& linkHash : m_pendingVisitedLinks) { + if (m_table.addLinkHash(linkHash)) + m_keyCount++; + } + m_pendingVisitedLinks.clear(); + + for (WebProcessProxy* process : m_processes) + sendTable(*process); +} + +void VisitedLinkStore::sendTable(WebProcessProxy& process) +{ + ASSERT(process.processPool().processes().contains(&process)); + + SharedMemory::Handle handle; + if (!m_table.sharedMemory()->createHandle(handle, SharedMemory::Protection::ReadOnly)) + return; + + process.connection()->send(Messages::VisitedLinkTableController::SetVisitedLinkTable(handle), m_identifier); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/VisitedLinkProvider.h b/Source/WebKit2/UIProcess/VisitedLinkStore.h index c0d4ec963..d5334dbea 100644 --- a/Source/WebKit2/UIProcess/VisitedLinkProvider.h +++ b/Source/WebKit2/UIProcess/VisitedLinkStore.h @@ -23,46 +23,66 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef VisitedLinkProvider_h -#define VisitedLinkProvider_h +#ifndef VisitedLinkStore_h +#define VisitedLinkStore_h +#include "APIObject.h" +#include "MessageReceiver.h" #include "VisitedLinkTable.h" +#include "WebProcessLifetimeObserver.h" #include <WebCore/LinkHash.h> #include <wtf/Forward.h> #include <wtf/HashSet.h> +#include <wtf/RefCounted.h> #include <wtf/RunLoop.h> namespace WebKit { -class WebContext; +class WebPageProxy; class WebProcessProxy; -class VisitedLinkProvider { - WTF_MAKE_NONCOPYABLE(VisitedLinkProvider); +class VisitedLinkStore final : public API::ObjectImpl<API::Object::Type::VisitedLinkStore>, private IPC::MessageReceiver, public WebProcessLifetimeObserver { public: - explicit VisitedLinkProvider(WebContext*); + static Ref<VisitedLinkStore> create(); - void addVisitedLink(WebCore::LinkHash); + explicit VisitedLinkStore(); + virtual ~VisitedLinkStore(); - void processDidFinishLaunching(WebProcessProxy*); - void processDidClose(WebProcessProxy*); + uint64_t identifier() const { return m_identifier; } + + void addProcess(WebProcessProxy&); + void removeProcess(WebProcessProxy&); + + void addVisitedLinkHash(WebCore::LinkHash); + void removeAll(); private: + // IPC::MessageReceiver + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + + // WebProcessLifetimeObserver + void webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) override; + void webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) override; + + void addVisitedLinkHashFromPage(uint64_t pageID, WebCore::LinkHash); + void pendingVisitedLinksTimerFired(); - WebContext* m_context; - bool m_visitedLinksPopulated; - HashSet<WebProcessProxy*> m_processesWithVisitedLinkState; - HashSet<WebProcessProxy*> m_processesWithoutVisitedLinkState; + void resizeTable(unsigned newTableSize); + void sendTable(WebProcessProxy&); + + HashSet<WebProcessProxy*> m_processes; + + uint64_t m_identifier; unsigned m_keyCount; unsigned m_tableSize; VisitedLinkTable m_table; HashSet<WebCore::LinkHash, WebCore::LinkHashHash> m_pendingVisitedLinks; - RunLoop::Timer<VisitedLinkProvider> m_pendingVisitedLinksTimer; + RunLoop::Timer<VisitedLinkStore> m_pendingVisitedLinksTimer; }; } // namespace WebKit -#endif // VisitedLinkProvider_h +#endif // VisitedLinkStore_h diff --git a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in b/Source/WebKit2/UIProcess/VisitedLinkStore.messages.in index 18058f5c7..e7862e365 100644 --- a/Source/WebKit2/UIProcess/soup/WebSoupRequestManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/VisitedLinkStore.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Igalia S.L. +# Copyright (C) 2014 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,6 +20,6 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -messages -> WebSoupRequestManagerProxy { - DidFailToLoadURIRequest(uint64_t requestID); +messages -> VisitedLinkStore { + AddVisitedLinkHashFromPage(uint64_t pageID, uint64_t linkHash) } diff --git a/Source/WebKit2/UIProcess/WKImagePreviewViewController.h b/Source/WebKit2/UIProcess/WKImagePreviewViewController.h new file mode 100644 index 000000000..852931b6b --- /dev/null +++ b/Source/WebKit2/UIProcess/WKImagePreviewViewController.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if PLATFORM(IOS) + +#import <UIKit/UIKit.h> + +#import <wtf/RetainPtr.h> + +@class _WKActivatedElementInfo; +@class _WKElementAction; + +@interface WKImagePreviewViewController : UIViewController { +@private + RetainPtr<NSArray> _imageActions; + RetainPtr<_WKActivatedElementInfo> _activatedElementInfo; +} + +- (id)initWithCGImage:(RetainPtr<CGImageRef>)image defaultActions:(RetainPtr<NSArray>)actions elementInfo:(RetainPtr<_WKActivatedElementInfo>)elementInfo; +@end + +#endif // PLATFORM(IOS) diff --git a/Source/WebKit2/UIProcess/WKInspectorHighlightView.h b/Source/WebKit2/UIProcess/WKInspectorHighlightView.h new file mode 100644 index 000000000..117660cb3 --- /dev/null +++ b/Source/WebKit2/UIProcess/WKInspectorHighlightView.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if PLATFORM(IOS) + +#import <UIKit/UIKit.h> + +namespace WebCore { +struct Highlight; +} + +@interface WKInspectorHighlightView : UIView { + NSMutableArray *_layers; // CAShapeLayers. +} +- (void)update:(const WebCore::Highlight&)highlight; +@end + +#endif diff --git a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.cpp b/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.cpp deleted file mode 100644 index dcb8137eb..000000000 --- a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebApplicationCacheManagerProxy.h" - -#include "SecurityOriginData.h" -#include "WebApplicationCacheManagerMessages.h" -#include "WebApplicationCacheManagerProxyMessages.h" -#include "WebContext.h" -#include "WebSecurityOrigin.h" - -namespace WebKit { - -const char* WebApplicationCacheManagerProxy::supplementName() -{ - return "WebApplicationCacheManagerProxy"; -} - -PassRefPtr<WebApplicationCacheManagerProxy> WebApplicationCacheManagerProxy::create(WebContext* context) -{ - return adoptRef(new WebApplicationCacheManagerProxy(context)); -} - -WebApplicationCacheManagerProxy::WebApplicationCacheManagerProxy(WebContext* context) - : WebContextSupplement(context) -{ - context->addMessageReceiver(Messages::WebApplicationCacheManagerProxy::messageReceiverName(), *this); -} - -WebApplicationCacheManagerProxy::~WebApplicationCacheManagerProxy() -{ -} - - -void WebApplicationCacheManagerProxy::contextDestroyed() -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -void WebApplicationCacheManagerProxy::processDidClose(WebProcessProxy*) -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -bool WebApplicationCacheManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return m_arrayCallbacks.isEmpty(); -} - -void WebApplicationCacheManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebApplicationCacheManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebApplicationCacheManagerProxy::getApplicationCacheOrigins(PassRefPtr<ArrayCallback> prpCallback) -{ - if (!context()) - return; - - RefPtr<ArrayCallback> callback = prpCallback; - - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebApplicationCacheManager::GetApplicationCacheOrigins(callbackID)); -} - -void WebApplicationCacheManagerProxy::didGetApplicationCacheOrigins(const Vector<SecurityOriginData>& originDatas, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - performAPICallbackWithSecurityOriginDataVector(originDatas, callback.get()); -} - -void WebApplicationCacheManagerProxy::deleteEntriesForOrigin(WebSecurityOrigin* origin) -{ - if (!context()) - return; - - SecurityOriginData securityOriginData; - securityOriginData.protocol = origin->protocol(); - securityOriginData.host = origin->host(); - securityOriginData.port = origin->port(); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebApplicationCacheManager::DeleteEntriesForOrigin(securityOriginData)); -} - -void WebApplicationCacheManagerProxy::deleteAllEntries() -{ - if (!context()) - return; - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebApplicationCacheManager::DeleteAllEntries()); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.h b/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.h deleted file mode 100644 index 824c21110..000000000 --- a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebApplicationCacheManagerProxy_h -#define WebApplicationCacheManagerProxy_h - -#include "APIObject.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "WebContextSupplement.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace IPC { - class Connection; -} - -namespace WebKit { - -class WebSecurityOrigin; -struct SecurityOriginData; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebApplicationCacheManagerProxy : public API::ObjectImpl<API::Object::Type::ApplicationCacheManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebApplicationCacheManagerProxy> create(WebContext*); - virtual ~WebApplicationCacheManagerProxy(); - - void getApplicationCacheOrigins(PassRefPtr<ArrayCallback>); - void deleteEntriesForOrigin(WebSecurityOrigin*); - void deleteAllEntries(); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebApplicationCacheManagerProxy(WebContext*); - - void didGetApplicationCacheOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; -}; - -} // namespace WebKit - -#endif // WebApplicationCacheManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.messages.in deleted file mode 100644 index 2aa0f670e..000000000 --- a/Source/WebKit2/UIProcess/WebApplicationCacheManagerProxy.messages.in +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2011 Apple Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -messages -> WebApplicationCacheManagerProxy { - DidGetApplicationCacheOrigins(Vector<WebKit::SecurityOriginData> originIdentifiers, uint64_t callbackID); -} diff --git a/Source/WebKit2/UIProcess/WebBackForwardList.cpp b/Source/WebKit2/UIProcess/WebBackForwardList.cpp index 411ea56c4..c88e68c95 100644 --- a/Source/WebKit2/UIProcess/WebBackForwardList.cpp +++ b/Source/WebKit2/UIProcess/WebBackForwardList.cpp @@ -27,10 +27,28 @@ #include "WebBackForwardList.h" #include "APIArray.h" +#include "SessionState.h" #include "WebPageProxy.h" +#include <WebCore/DiagnosticLoggingClient.h> +#include <WebCore/DiagnosticLoggingKeys.h> namespace WebKit { +using namespace WebCore; + +// FIXME: Make this static once WebBackForwardListCF.cpp is no longer using it. +uint64_t generateWebBackForwardItemID(); + +uint64_t generateWebBackForwardItemID() +{ + // These IDs exist in the UIProcess for items created by the UIProcess. + // The IDs generated here need to never collide with the IDs created in WebBackForwardListProxy in the WebProcess. + // We accomplish this by starting from 2, and only ever using even ids. + static uint64_t uniqueHistoryItemID = 0; + uniqueHistoryItemID += 2; + return uniqueHistoryItemID; +} + static const unsigned DefaultCapacity = 100; WebBackForwardList::WebBackForwardList(WebPageProxy& page) @@ -58,7 +76,8 @@ void WebBackForwardList::pageClosed() ASSERT(m_entries[i]); if (!m_entries[i]) continue; - m_page->backForwardRemovedItem(m_entries[i]->itemID()); + + didRemoveItem(*m_entries[i]); } } @@ -74,23 +93,25 @@ void WebBackForwardList::addItem(WebBackForwardListItem* newItem) if (!m_capacity || !newItem || !m_page) return; - Vector<RefPtr<API::Object>> removedItems; + Vector<RefPtr<WebBackForwardListItem>> removedItems; if (m_hasCurrentIndex) { + m_page->recordAutomaticNavigationSnapshot(); + // Toss everything in the forward list. unsigned targetSize = m_currentIndex + 1; removedItems.reserveCapacity(m_entries.size() - targetSize); while (m_entries.size() > targetSize) { - m_page->backForwardRemovedItem(m_entries.last()->itemID()); - removedItems.append(m_entries.last().release()); + didRemoveItem(*m_entries.last()); + removedItems.append(WTFMove(m_entries.last())); m_entries.removeLast(); } // Toss the first item if the list is getting too big, as long as we're not using it // (or even if we are, if we only want 1 entry). if (m_entries.size() == m_capacity && (m_currentIndex || m_capacity == 1)) { - m_page->backForwardRemovedItem(m_entries[0]->itemID()); - removedItems.append(m_entries[0].release()); + didRemoveItem(*m_entries[0]); + removedItems.append(WTFMove(m_entries[0])); m_entries.remove(0); if (m_entries.isEmpty()) @@ -108,26 +129,41 @@ void WebBackForwardList::addItem(WebBackForwardListItem* newItem) ASSERT(m_entries[i]); if (!m_entries[i]) continue; - m_page->backForwardRemovedItem(m_entries[i]->itemID()); - removedItems.append(m_entries[i].release()); + didRemoveItem(*m_entries[i]); + removedItems.append(WTFMove(m_entries[i])); } m_entries.clear(); } - + + bool shouldKeepCurrentItem = true; + if (!m_hasCurrentIndex) { ASSERT(m_entries.isEmpty()); m_currentIndex = 0; m_hasCurrentIndex = true; - } else - m_currentIndex++; + } else { + shouldKeepCurrentItem = m_page->shouldKeepCurrentBackForwardListItemInList(m_entries[m_currentIndex].get()); + if (shouldKeepCurrentItem) + m_currentIndex++; + } - // m_current never be pointing more than 1 past the end of the entries Vector. - // If it is, something has gone wrong and we should not try to insert the new item. - ASSERT(m_currentIndex <= m_entries.size()); - if (m_currentIndex <= m_entries.size()) - m_entries.insert(m_currentIndex, newItem); + if (!shouldKeepCurrentItem) { + // m_current should never be pointing past the end of the entries Vector. + // If it is, something has gone wrong and we should not try to swap in the new item. + ASSERT(m_currentIndex < m_entries.size()); + + removedItems.append(m_entries[m_currentIndex]); + m_entries[m_currentIndex] = newItem; + } else { + // m_current should never be pointing more than 1 past the end of the entries Vector. + // If it is, something has gone wrong and we should not try to insert the new item. + ASSERT(m_currentIndex <= m_entries.size()); - m_page->didChangeBackForwardList(newItem, &removedItems); + if (m_currentIndex <= m_entries.size()) + m_entries.insert(m_currentIndex, newItem); + } + + m_page->didChangeBackForwardList(newItem, WTFMove(removedItems)); } void WebBackForwardList::goToItem(WebBackForwardListItem* item) @@ -136,16 +172,40 @@ void WebBackForwardList::goToItem(WebBackForwardListItem* item) if (!m_entries.size() || !item || !m_page || !m_hasCurrentIndex) return; - - unsigned index = 0; - for (; index < m_entries.size(); ++index) { - if (m_entries[index] == item) - break; + + size_t targetIndex = m_entries.find(item); + + // If the target item wasn't even in the list, there's nothing else to do. + if (targetIndex == notFound) + return; + + if (targetIndex < m_currentIndex) { + unsigned delta = m_entries.size() - targetIndex - 1; + String deltaValue = delta > 10 ? ASCIILiteral("over10") : String::number(delta); + m_page->logDiagnosticMessage(WebCore::DiagnosticLoggingKeys::backNavigationDeltaKey(), deltaValue, ShouldSample::No); } - if (index < m_entries.size()) { - m_currentIndex = index; - m_page->didChangeBackForwardList(0, 0); + + // If we're going to an item different from the current item, ask the client if the current + // item should remain in the list. + WebBackForwardListItem* currentItem = m_entries[m_currentIndex].get(); + bool shouldKeepCurrentItem = true; + if (currentItem != item) { + m_page->recordAutomaticNavigationSnapshot(); + shouldKeepCurrentItem = m_page->shouldKeepCurrentBackForwardListItemInList(m_entries[m_currentIndex].get()); } + + // If the client said to remove the current item, remove it and then update the target index. + Vector<RefPtr<WebBackForwardListItem>> removedItems; + if (!shouldKeepCurrentItem) { + removedItems.append(currentItem); + m_entries.remove(m_currentIndex); + targetIndex = m_entries.find(item); + + ASSERT(targetIndex != notFound); + } + + m_currentIndex = targetIndex; + m_page->didChangeBackForwardList(nullptr, removedItems); } WebBackForwardListItem* WebBackForwardList::currentItem() const @@ -200,7 +260,17 @@ int WebBackForwardList::forwardListCount() const return m_page && m_hasCurrentIndex ? m_entries.size() - (m_currentIndex + 1) : 0; } -PassRefPtr<API::Array> WebBackForwardList::backListAsAPIArrayWithLimit(unsigned limit) const +Ref<API::Array> WebBackForwardList::backList() const +{ + return backListAsAPIArrayWithLimit(backListCount()); +} + +Ref<API::Array> WebBackForwardList::forwardList() const +{ + return forwardListAsAPIArrayWithLimit(forwardListCount()); +} + +Ref<API::Array> WebBackForwardList::backListAsAPIArrayWithLimit(unsigned limit) const { ASSERT(!m_hasCurrentIndex || m_currentIndex < m_entries.size()); @@ -221,10 +291,10 @@ PassRefPtr<API::Array> WebBackForwardList::backListAsAPIArrayWithLimit(unsigned vector.uncheckedAppend(m_entries[i].get()); } - return API::Array::create(std::move(vector)); + return API::Array::create(WTFMove(vector)); } -PassRefPtr<API::Array> WebBackForwardList::forwardListAsAPIArrayWithLimit(unsigned limit) const +Ref<API::Array> WebBackForwardList::forwardListAsAPIArrayWithLimit(unsigned limit) const { ASSERT(!m_hasCurrentIndex || m_currentIndex < m_entries.size()); @@ -245,7 +315,27 @@ PassRefPtr<API::Array> WebBackForwardList::forwardListAsAPIArrayWithLimit(unsign vector.uncheckedAppend(m_entries[i].get()); } - return API::Array::create(std::move(vector)); + return API::Array::create(WTFMove(vector)); +} + +void WebBackForwardList::removeAllItems() +{ + ASSERT(!m_hasCurrentIndex || m_currentIndex < m_entries.size()); + + Vector<RefPtr<WebBackForwardListItem>> removedItems; + + for (auto& entry : m_entries) { + ASSERT(entry); + if (!entry) + continue; + + didRemoveItem(*entry); + removedItems.append(WTFMove(entry)); + } + + m_entries.clear(); + m_hasCurrentIndex = false; + m_page->didChangeBackForwardList(nullptr, WTFMove(removedItems)); } void WebBackForwardList::clear() @@ -257,7 +347,7 @@ void WebBackForwardList::clear() return; RefPtr<WebBackForwardListItem> currentItem = this->currentItem(); - Vector<RefPtr<API::Object>> removedItems; + Vector<RefPtr<WebBackForwardListItem>> removedItems; if (!currentItem) { // We should only ever have no current item if we also have no current item index. @@ -269,13 +359,13 @@ void WebBackForwardList::clear() if (!m_entries[i]) continue; - m_page->backForwardRemovedItem(m_entries[i]->itemID()); - removedItems.append(m_entries[i].release()); + didRemoveItem(*m_entries[i]); + removedItems.append(WTFMove(m_entries[i])); } m_entries.clear(); m_hasCurrentIndex = false; - m_page->didChangeBackForwardList(0, &removedItems); + m_page->didChangeBackForwardList(nullptr, WTFMove(removedItems)); return; } @@ -283,26 +373,90 @@ void WebBackForwardList::clear() for (size_t i = 0; i < size; ++i) { ASSERT(m_entries[i]); if (m_entries[i] && m_entries[i] != currentItem) - m_page->backForwardRemovedItem(m_entries[i]->itemID()); + didRemoveItem(*m_entries[i]); } removedItems.reserveCapacity(size - 1); for (size_t i = 0; i < size; ++i) { if (i != m_currentIndex && m_hasCurrentIndex && m_entries[i]) - removedItems.append(m_entries[i].release()); + removedItems.append(WTFMove(m_entries[i])); } m_currentIndex = 0; if (currentItem) { m_entries.shrink(1); - m_entries[0] = currentItem.release(); + m_entries[0] = WTFMove(currentItem); } else { m_entries.clear(); m_hasCurrentIndex = false; } - m_page->didChangeBackForwardList(0, &removedItems); + m_page->didChangeBackForwardList(nullptr, WTFMove(removedItems)); +} + +BackForwardListState WebBackForwardList::backForwardListState(const std::function<bool (WebBackForwardListItem&)>& filter) const +{ + ASSERT(!m_hasCurrentIndex || m_currentIndex < m_entries.size()); + + BackForwardListState backForwardListState; + if (m_hasCurrentIndex) + backForwardListState.currentIndex = m_currentIndex; + + for (size_t i = 0; i < m_entries.size(); ++i) { + auto& entry = *m_entries[i]; + + if (filter && !filter(entry)) { + auto& currentIndex = backForwardListState.currentIndex; + if (currentIndex && i <= currentIndex.value() && currentIndex.value()) + --currentIndex.value(); + + continue; + } + + backForwardListState.items.append(entry.itemState()); + } + + if (backForwardListState.items.isEmpty()) + backForwardListState.currentIndex = std::nullopt; + else if (backForwardListState.items.size() <= backForwardListState.currentIndex.value()) + backForwardListState.currentIndex = backForwardListState.items.size() - 1; + + return backForwardListState; +} + +void WebBackForwardList::restoreFromState(BackForwardListState backForwardListState) +{ + Vector<RefPtr<WebBackForwardListItem>> items; + items.reserveInitialCapacity(backForwardListState.items.size()); + + for (auto& backForwardListItemState : backForwardListState.items) { + backForwardListItemState.identifier = generateWebBackForwardItemID(); + items.uncheckedAppend(WebBackForwardListItem::create(WTFMove(backForwardListItemState), m_page->pageID())); + } + m_hasCurrentIndex = !!backForwardListState.currentIndex; + m_currentIndex = backForwardListState.currentIndex.value_or(0); + m_entries = WTFMove(items); +} + +Vector<BackForwardListItemState> WebBackForwardList::itemStates() const +{ + Vector<BackForwardListItemState> itemStates; + itemStates.reserveInitialCapacity(m_entries.size()); + + for (const auto& entry : m_entries) + itemStates.uncheckedAppend(entry->itemState()); + + return itemStates; +} + +void WebBackForwardList::didRemoveItem(WebBackForwardListItem& backForwardListItem) +{ + m_page->backForwardRemovedItem(backForwardListItem.itemID()); + +#if PLATFORM(COCOA) + backForwardListItem.setSnapshot(nullptr); +#endif } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebBackForwardList.h b/Source/WebKit2/UIProcess/WebBackForwardList.h index bf13d3b59..178f07e87 100644 --- a/Source/WebKit2/UIProcess/WebBackForwardList.h +++ b/Source/WebKit2/UIProcess/WebBackForwardList.h @@ -29,7 +29,7 @@ #include "APIObject.h" #include "WebBackForwardListItem.h" #include "WebPageProxy.h" -#include <wtf/PassRef.h> +#include <wtf/Ref.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> #if USE(CF) @@ -38,15 +38,11 @@ namespace WebKit { -/* - * Current - * |---------*--------------| Entries - * Back Forward - */ +struct BackForwardListState; class WebBackForwardList : public API::ObjectImpl<API::Object::Type::BackForwardList> { public: - static PassRef<WebBackForwardList> create(WebPageProxy& page) + static Ref<WebBackForwardList> create(WebPageProxy& page) { return adoptRef(*new WebBackForwardList(page)); } @@ -56,32 +52,36 @@ public: void addItem(WebBackForwardListItem*); void goToItem(WebBackForwardListItem*); + void removeAllItems(); void clear(); WebBackForwardListItem* currentItem() const; WebBackForwardListItem* backItem() const; WebBackForwardListItem* forwardItem() const; WebBackForwardListItem* itemAtIndex(int) const; - + const BackForwardListItemVector& entries() const { return m_entries; } uint32_t currentIndex() const { return m_currentIndex; } int backListCount() const; int forwardListCount() const; - PassRefPtr<API::Array> backListAsAPIArrayWithLimit(unsigned limit) const; - PassRefPtr<API::Array> forwardListAsAPIArrayWithLimit(unsigned limit) const; + Ref<API::Array> backList() const; + Ref<API::Array> forwardList() const; -#if USE(CF) - CFDictionaryRef createCFDictionaryRepresentation(WebPageProxy::WebPageProxySessionStateFilterCallback, void* context) const; - bool restoreFromCFDictionaryRepresentation(CFDictionaryRef); - bool restoreFromV0CFDictionaryRepresentation(CFDictionaryRef); - bool restoreFromV1CFDictionaryRepresentation(CFDictionaryRef); -#endif + Ref<API::Array> backListAsAPIArrayWithLimit(unsigned limit) const; + Ref<API::Array> forwardListAsAPIArrayWithLimit(unsigned limit) const; + + BackForwardListState backForwardListState(const std::function<bool (WebBackForwardListItem&)>&) const; + void restoreFromState(BackForwardListState); + + Vector<BackForwardListItemState> itemStates() const; private: explicit WebBackForwardList(WebPageProxy&); + void didRemoveItem(WebBackForwardListItem&); + WebPageProxy* m_page; BackForwardListItemVector m_entries; diff --git a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.cpp b/Source/WebKit2/UIProcess/WebBatteryManagerProxy.cpp deleted file mode 100644 index 00075daae..000000000 --- a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebBatteryManagerProxy.h" - -#if ENABLE(BATTERY_STATUS) - -#include "WebBatteryManagerMessages.h" -#include "WebBatteryManagerProxyMessages.h" -#include "WebContext.h" - -namespace WebKit { - -const char* WebBatteryManagerProxy::supplementName() -{ - return "WebBatteryManagerProxy"; -} - -PassRefPtr<WebBatteryManagerProxy> WebBatteryManagerProxy::create(WebContext* context) -{ - return adoptRef(new WebBatteryManagerProxy(context)); -} - -WebBatteryManagerProxy::WebBatteryManagerProxy(WebContext* context) - : WebContextSupplement(context) - , m_isUpdating(false) -{ - WebContextSupplement::context()->addMessageReceiver(Messages::WebBatteryManagerProxy::messageReceiverName(), *this); -} - -WebBatteryManagerProxy::~WebBatteryManagerProxy() -{ -} - -void WebBatteryManagerProxy::initializeProvider(const WKBatteryProviderBase* provider) -{ - m_provider.initialize(provider); -} - - -void WebBatteryManagerProxy::providerDidChangeBatteryStatus(const WTF::AtomicString& eventType, WebBatteryStatus* status) -{ - if (!context()) - return; - - context()->sendToAllProcesses(Messages::WebBatteryManager::DidChangeBatteryStatus(eventType, status->data())); -} - -void WebBatteryManagerProxy::providerUpdateBatteryStatus(WebBatteryStatus* status) -{ - if (!context()) - return; - - context()->sendToAllProcesses(Messages::WebBatteryManager::UpdateBatteryStatus(status->data())); -} - -// WebContextSupplement - -void WebBatteryManagerProxy::contextDestroyed() -{ - stopUpdating(); -} - -void WebBatteryManagerProxy::processDidClose(WebProcessProxy*) -{ - stopUpdating(); -} - -void WebBatteryManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebBatteryManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebBatteryManagerProxy::startUpdating() -{ - if (m_isUpdating) - return; - - m_provider.startUpdating(this); - m_isUpdating = true; -} - -void WebBatteryManagerProxy::stopUpdating() -{ - if (!m_isUpdating) - return; - - m_provider.stopUpdating(this); - m_isUpdating = false; -} - -} // namespace WebKit - -#endif // ENABLE(BATTERY_STATUS) diff --git a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp index d3aa27e1c..e8e08500f 100644 --- a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp +++ b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp @@ -27,7 +27,6 @@ #include "WebConnectionToWebProcess.h" #include "WebConnectionMessages.h" -#include "WebContextUserMessageCoders.h" #include "WebProcessProxy.h" namespace WebKit { @@ -45,20 +44,21 @@ WebConnectionToWebProcess::WebConnectionToWebProcess(WebProcessProxy* process) void WebConnectionToWebProcess::invalidate() { + m_process->removeMessageReceiver(Messages::WebConnection::messageReceiverName()); + m_process = 0; } // WebConnection -void WebConnectionToWebProcess::encodeMessageBody(IPC::ArgumentEncoder& encoder, API::Object* messageBody) +RefPtr<API::Object> WebConnectionToWebProcess::transformHandlesToObjects(API::Object* object) { - encoder << WebContextUserMessageEncoder(messageBody, *m_process); + return m_process->transformHandlesToObjects(object); } -bool WebConnectionToWebProcess::decodeMessageBody(IPC::ArgumentDecoder& decoder, RefPtr<API::Object>& messageBody) +RefPtr<API::Object> WebConnectionToWebProcess::transformObjectsToHandles(API::Object* object) { - WebContextUserMessageDecoder messageBodyDecoder(messageBody, *m_process); - return decoder.decode(messageBodyDecoder); + return m_process->transformObjectsToHandles(object); } bool WebConnectionToWebProcess::hasValidConnection() const diff --git a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.h b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.h index a13c5872f..a97ec2ad5 100644 --- a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.h +++ b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.h @@ -44,13 +44,13 @@ private: WebConnectionToWebProcess(WebProcessProxy*); // WebConnection - virtual void encodeMessageBody(IPC::ArgumentEncoder&, API::Object*) override; - virtual bool decodeMessageBody(IPC::ArgumentDecoder&, RefPtr<API::Object>&) override; - virtual bool hasValidConnection() const override; + RefPtr<API::Object> transformHandlesToObjects(API::Object*) override; + RefPtr<API::Object> transformObjectsToHandles(API::Object*) override; + bool hasValidConnection() const override; // IPC::MessageSender - virtual IPC::Connection* messageSenderConnection() override; - virtual uint64_t messageSenderDestinationID() override; + IPC::Connection* messageSenderConnection() override; + uint64_t messageSenderDestinationID() override; WebProcessProxy* m_process; }; diff --git a/Source/WebKit2/UIProcess/WebContext.cpp b/Source/WebKit2/UIProcess/WebContext.cpp deleted file mode 100644 index a463498ca..000000000 --- a/Source/WebKit2/UIProcess/WebContext.cpp +++ /dev/null @@ -1,1380 +0,0 @@ -/* - * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebContext.h" - -#include "APIArray.h" -#include "DownloadProxy.h" -#include "DownloadProxyMessages.h" -#include "Logging.h" -#include "MutableDictionary.h" -#include "SandboxExtension.h" -#include "SessionTracker.h" -#include "StatisticsData.h" -#include "TextChecker.h" -#include "WKContextPrivate.h" -#include "WebApplicationCacheManagerProxy.h" -#include "WebContextMessageKinds.h" -#include "WebContextMessages.h" -#include "WebContextSupplement.h" -#include "WebContextUserMessageCoders.h" -#include "WebCookieManagerProxy.h" -#include "WebCoreArgumentCoders.h" -#include "WebDatabaseManagerProxy.h" -#include "WebGeolocationManagerProxy.h" -#include "WebIconDatabase.h" -#include "WebKeyValueStorageManager.h" -#include "WebKit2Initialize.h" -#include "WebMediaCacheManagerProxy.h" -#include "WebNotificationManagerProxy.h" -#include "WebPluginSiteDataManager.h" -#include "WebPageGroup.h" -#include "WebPreferences.h" -#include "WebMemorySampler.h" -#include "WebProcessCreationParameters.h" -#include "WebProcessMessages.h" -#include "WebProcessProxy.h" -#include "WebResourceCacheManagerProxy.h" -#include <WebCore/Language.h> -#include <WebCore/LinkHash.h> -#include <WebCore/Logging.h> -#include <WebCore/ResourceRequest.h> -#include <runtime/Operations.h> -#include <wtf/CurrentTime.h> -#include <wtf/MainThread.h> -#include <wtf/NeverDestroyed.h> -#include <wtf/RunLoop.h> - -#if ENABLE(BATTERY_STATUS) -#include "WebBatteryManagerProxy.h" -#endif - -#if ENABLE(NETWORK_INFO) -#include "WebNetworkInfoManagerProxy.h" -#endif - -#if ENABLE(DATABASE_PROCESS) -#include "DatabaseProcessCreationParameters.h" -#include "DatabaseProcessMessages.h" -#endif - -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessCreationParameters.h" -#include "NetworkProcessMessages.h" -#include "NetworkProcessProxy.h" -#endif - -#if ENABLE(CUSTOM_PROTOCOLS) -#include "CustomProtocolManagerMessages.h" -#endif - -#if USE(SOUP) -#if ENABLE(CUSTOM_PROTOCOLS) -#include "WebSoupCustomProtocolRequestManager.h" -#else -#include "WebSoupRequestManagerProxy.h" -#endif -#endif - -#ifndef NDEBUG -#include <wtf/RefCountedLeakCounter.h> -#endif - -using namespace WebCore; - -namespace WebKit { - -static const double sharedSecondaryProcessShutdownTimeout = 60; - -DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webContextCounter, ("WebContext")); - -PassRefPtr<WebContext> WebContext::create(const String& injectedBundlePath) -{ - InitializeWebKit2(); - return adoptRef(new WebContext(injectedBundlePath)); -} - -static Vector<WebContext*>& contexts() -{ - static NeverDestroyed<Vector<WebContext*>> contexts; - return contexts; -} - -const Vector<WebContext*>& WebContext::allContexts() -{ - return contexts(); -} - -WebContext::WebContext(const String& injectedBundlePath) - : m_processModel(ProcessModelSharedSecondaryProcess) - , m_webProcessCountLimit(UINT_MAX) - , m_haveInitialEmptyProcess(false) - , m_processWithPageCache(0) - , m_defaultPageGroup(WebPageGroup::createNonNull()) - , m_injectedBundlePath(injectedBundlePath) - , m_visitedLinkProvider(this) - , m_plugInAutoStartProvider(this) - , m_alwaysUsesComplexTextCodePath(false) - , m_shouldUseFontSmoothing(true) - , m_cacheModel(CacheModelDocumentViewer) - , m_memorySamplerEnabled(false) - , m_memorySamplerInterval(1400.0) - , m_storageManager(StorageManager::create()) -#if USE(SOUP) - , m_initialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain) -#endif - , m_shouldUseTestingNetworkSession(false) - , m_processTerminationEnabled(true) -#if ENABLE(NETWORK_PROCESS) - , m_usesNetworkProcess(false) -#endif -#if USE(SOUP) - , m_ignoreTLSErrors(true) -#endif - , m_memoryCacheDisabled(false) -{ - platformInitialize(); - - addMessageReceiver(Messages::WebContext::messageReceiverName(), *this); - addMessageReceiver(WebContextLegacyMessages::messageReceiverName(), *this); - - // NOTE: These sub-objects must be initialized after m_messageReceiverMap.. - m_iconDatabase = WebIconDatabase::create(this); -#if ENABLE(NETSCAPE_PLUGIN_API) - m_pluginSiteDataManager = WebPluginSiteDataManager::create(this); -#endif // ENABLE(NETSCAPE_PLUGIN_API) - - addSupplement<WebApplicationCacheManagerProxy>(); - addSupplement<WebCookieManagerProxy>(); - addSupplement<WebGeolocationManagerProxy>(); - addSupplement<WebKeyValueStorageManager>(); - addSupplement<WebMediaCacheManagerProxy>(); - addSupplement<WebNotificationManagerProxy>(); - addSupplement<WebResourceCacheManagerProxy>(); -#if ENABLE(SQL_DATABASE) - addSupplement<WebDatabaseManagerProxy>(); -#endif -#if USE(SOUP) -#if ENABLE(CUSTOM_PROTOCOLS) - addSupplement<WebSoupCustomProtocolRequestManager>(); -#else - addSupplement<WebSoupRequestManagerProxy>(); -#endif -#endif -#if ENABLE(BATTERY_STATUS) - addSupplement<WebBatteryManagerProxy>(); -#endif -#if ENABLE(NETWORK_INFO) - addSupplement<WebNetworkInfoManagerProxy>(); -#endif - - contexts().append(this); - - addLanguageChangeObserver(this, languageChanged); - -#if !LOG_DISABLED - WebCore::initializeLoggingChannelsIfNecessary(); - WebKit::initializeLogChannelsIfNecessary(); -#endif // !LOG_DISABLED - -#if ENABLE(NETSCAPE_PLUGIN_API) - m_pluginInfoStore.setClient(this); -#endif - -#ifndef NDEBUG - webContextCounter.increment(); -#endif - - m_storageManager->setLocalStorageDirectory(localStorageDirectory()); -} - -#if !PLATFORM(MAC) -void WebContext::platformInitialize() -{ -} -#endif - -WebContext::~WebContext() -{ - ASSERT(contexts().find(this) != notFound); - contexts().remove(contexts().find(this)); - - removeLanguageChangeObserver(this); - - m_messageReceiverMap.invalidate(); - - WebContextSupplementMap::const_iterator it = m_supplements.begin(); - WebContextSupplementMap::const_iterator end = m_supplements.end(); - for (; it != end; ++it) { - it->value->contextDestroyed(); - it->value->clearContext(); - } - - m_iconDatabase->invalidate(); - m_iconDatabase->clearContext(); - -#if ENABLE(NETSCAPE_PLUGIN_API) - m_pluginSiteDataManager->invalidate(); - m_pluginSiteDataManager->clearContext(); -#endif - - invalidateCallbackMap(m_dictionaryCallbacks); - - platformInvalidateContext(); - -#if ENABLE(NETSCAPE_PLUGIN_API) - m_pluginInfoStore.setClient(0); -#endif - -#ifndef NDEBUG - webContextCounter.decrement(); -#endif -} - -void WebContext::initializeClient(const WKContextClientBase* client) -{ - m_client.initialize(client); -} - -void WebContext::initializeInjectedBundleClient(const WKContextInjectedBundleClientBase* client) -{ - m_injectedBundleClient.initialize(client); -} - -void WebContext::initializeConnectionClient(const WKContextConnectionClientBase* client) -{ - m_connectionClient.initialize(client); -} - -void WebContext::initializeHistoryClient(const WKContextHistoryClientBase* client) -{ - m_historyClient.initialize(client); - - sendToAllProcesses(Messages::WebProcess::SetShouldTrackVisitedLinks(m_historyClient.shouldTrackVisitedLinks())); -} - -void WebContext::initializeDownloadClient(const WKContextDownloadClientBase* client) -{ - m_downloadClient.initialize(client); -} - -void WebContext::setProcessModel(ProcessModel processModel) -{ - // Guard against API misuse. - if (!m_processes.isEmpty()) - CRASH(); - if (processModel != ProcessModelSharedSecondaryProcess && !m_messagesToInjectedBundlePostedToEmptyContext.isEmpty()) - CRASH(); - - m_processModel = processModel; -} - -void WebContext::setMaximumNumberOfProcesses(unsigned maximumNumberOfProcesses) -{ - // Guard against API misuse. - if (!m_processes.isEmpty()) - CRASH(); - - if (maximumNumberOfProcesses == 0) - m_webProcessCountLimit = UINT_MAX; - else - m_webProcessCountLimit = maximumNumberOfProcesses; -} - -IPC::Connection* WebContext::networkingProcessConnection() -{ - switch (m_processModel) { - case ProcessModelSharedSecondaryProcess: -#if ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess) - return m_networkProcess->connection(); -#endif - return m_processes[0]->connection(); - case ProcessModelMultipleSecondaryProcesses: -#if ENABLE(NETWORK_PROCESS) - ASSERT(m_usesNetworkProcess); - return m_networkProcess->connection(); -#else - break; -#endif - } - ASSERT_NOT_REACHED(); - return 0; -} - -void WebContext::languageChanged(void* context) -{ - static_cast<WebContext*>(context)->languageChanged(); -} - -void WebContext::languageChanged() -{ - sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(userPreferredLanguages())); -#if USE(SOUP) && ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess && m_networkProcess) - m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(userPreferredLanguages()), 0); -#endif -} - -void WebContext::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) -{ - sendToAllProcesses(Messages::WebProcess::FullKeyboardAccessModeChanged(fullKeyboardAccessEnabled)); -} - -void WebContext::textCheckerStateChanged() -{ - sendToAllProcesses(Messages::WebProcess::SetTextCheckerState(TextChecker::state())); -} - -void WebContext::setUsesNetworkProcess(bool usesNetworkProcess) -{ -#if ENABLE(NETWORK_PROCESS) - m_usesNetworkProcess = usesNetworkProcess; -#else - UNUSED_PARAM(usesNetworkProcess); -#endif -} - -bool WebContext::usesNetworkProcess() const -{ -#if ENABLE(NETWORK_PROCESS) - return m_usesNetworkProcess; -#else - return false; -#endif -} - -#if ENABLE(NETWORK_PROCESS) -void WebContext::ensureNetworkProcess() -{ - if (m_networkProcess) - return; - - m_networkProcess = NetworkProcessProxy::create(*this); - - NetworkProcessCreationParameters parameters; - - parameters.privateBrowsingEnabled = WebPreferences::anyPageGroupsAreUsingPrivateBrowsing(); - - parameters.cacheModel = m_cacheModel; - - parameters.diskCacheDirectory = diskCacheDirectory(); - if (!parameters.diskCacheDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle); - - parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession; - - // Add any platform specific parameters - platformInitializeNetworkProcess(parameters); - - // Initialize the network process. - m_networkProcess->send(Messages::NetworkProcess::InitializeNetworkProcess(parameters), 0); - -#if PLATFORM(MAC) - m_networkProcess->send(Messages::NetworkProcess::SetQOS(networkProcessLatencyQOS(), networkProcessThroughputQOS()), 0); -#endif -} - -void WebContext::networkProcessCrashed(NetworkProcessProxy* networkProcessProxy) -{ - ASSERT(m_networkProcess); - ASSERT(networkProcessProxy == m_networkProcess.get()); - - WebContextSupplementMap::const_iterator it = m_supplements.begin(); - WebContextSupplementMap::const_iterator end = m_supplements.end(); - for (; it != end; ++it) - it->value->processDidClose(networkProcessProxy); - - m_networkProcess = nullptr; - - m_client.networkProcessDidCrash(this); -} - -void WebContext::getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply) -{ - ASSERT(reply); - - ensureNetworkProcess(); - ASSERT(m_networkProcess); - - m_networkProcess->getNetworkProcessConnection(reply); -} -#endif - -#if ENABLE(DATABASE_PROCESS) -void WebContext::ensureDatabaseProcess() -{ - if (m_databaseProcess) - return; - - m_databaseProcess = DatabaseProcessProxy::create(this); - - DatabaseProcessCreationParameters parameters; - - // Indexed databases exist in a subdirectory of the "database directory path." - // Currently, the top level of that directory contains entities related to WebSQL databases. - // We should fix this, and move WebSQL into a subdirectory (https://bugs.webkit.org/show_bug.cgi?id=124807) - // In the meantime, an entity name prefixed with three underscores will not conflict with any WebSQL entities. - parameters.indexedDatabaseDirectory = pathByAppendingComponent(databaseDirectory(), "___IndexedDB"); - - m_databaseProcess->send(Messages::DatabaseProcess::InitializeDatabaseProcess(parameters), 0); -} - -void WebContext::getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply> reply) -{ - ASSERT(reply); - - ensureDatabaseProcess(); - - m_databaseProcess->getDatabaseProcessConnection(reply); -} -#endif - -void WebContext::willStartUsingPrivateBrowsing() -{ - const Vector<WebContext*>& contexts = allContexts(); - for (size_t i = 0, count = contexts.size(); i < count; ++i) - contexts[i]->setAnyPageGroupMightHavePrivateBrowsingEnabled(true); -} - -void WebContext::willStopUsingPrivateBrowsing() -{ - const Vector<WebContext*>& contexts = allContexts(); - for (size_t i = 0, count = contexts.size(); i < count; ++i) - contexts[i]->setAnyPageGroupMightHavePrivateBrowsingEnabled(false); -} - -void WebContext::windowServerConnectionStateChanged() -{ - size_t processCount = m_processes.size(); - for (size_t i = 0; i < processCount; ++i) - m_processes[i]->windowServerConnectionStateChanged(); -} - -void WebContext::setAnyPageGroupMightHavePrivateBrowsingEnabled(bool privateBrowsingEnabled) -{ - m_iconDatabase->setPrivateBrowsingEnabled(privateBrowsingEnabled); - -#if ENABLE(NETWORK_PROCESS) - if (usesNetworkProcess() && networkProcess()) { - if (privateBrowsingEnabled) - networkProcess()->send(Messages::NetworkProcess::EnsurePrivateBrowsingSession(SessionTracker::legacyPrivateSessionID), 0); - else - networkProcess()->send(Messages::NetworkProcess::DestroyPrivateBrowsingSession(SessionTracker::legacyPrivateSessionID), 0); - } -#endif // ENABLED(NETWORK_PROCESS) - - if (privateBrowsingEnabled) - sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionTracker::legacyPrivateSessionID)); - else - sendToAllProcesses(Messages::WebProcess::DestroyPrivateBrowsingSession(SessionTracker::legacyPrivateSessionID)); -} - -void (*s_invalidMessageCallback)(WKStringRef messageName); - -void WebContext::setInvalidMessageCallback(void (*invalidMessageCallback)(WKStringRef messageName)) -{ - s_invalidMessageCallback = invalidMessageCallback; -} - -void WebContext::didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName) -{ - if (!s_invalidMessageCallback) - return; - - StringBuilder messageNameStringBuilder; - messageNameStringBuilder.append(messageReceiverName.data(), messageReceiverName.size()); - messageNameStringBuilder.append("."); - messageNameStringBuilder.append(messageName.data(), messageName.size()); - - s_invalidMessageCallback(toAPI(API::String::create(messageNameStringBuilder.toString()).get())); -} - -void WebContext::processDidCachePage(WebProcessProxy* process) -{ - if (m_processWithPageCache && m_processWithPageCache != process) - m_processWithPageCache->releasePageCache(); - m_processWithPageCache = process; -} - -WebProcessProxy& WebContext::ensureSharedWebProcess() -{ - ASSERT(m_processModel == ProcessModelSharedSecondaryProcess); - if (m_processes.isEmpty()) - createNewWebProcess(); - return *m_processes[0]; -} - -WebProcessProxy& WebContext::createNewWebProcess() -{ -#if ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess) - ensureNetworkProcess(); -#endif - - RefPtr<WebProcessProxy> process = WebProcessProxy::create(*this); - - WebProcessCreationParameters parameters; - - parameters.injectedBundlePath = injectedBundlePath(); - if (!parameters.injectedBundlePath.isEmpty()) - SandboxExtension::createHandle(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle); - - parameters.applicationCacheDirectory = applicationCacheDirectory(); - if (!parameters.applicationCacheDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.applicationCacheDirectory, parameters.applicationCacheDirectoryExtensionHandle); - - parameters.databaseDirectory = databaseDirectory(); - if (!parameters.databaseDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.databaseDirectory, parameters.databaseDirectoryExtensionHandle); - - parameters.localStorageDirectory = localStorageDirectory(); - if (!parameters.localStorageDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle); - - parameters.diskCacheDirectory = diskCacheDirectory(); - if (!parameters.diskCacheDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle); - - parameters.cookieStorageDirectory = cookieStorageDirectory(); - if (!parameters.cookieStorageDirectory.isEmpty()) - SandboxExtension::createHandleForReadWriteDirectory(parameters.cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle); - - parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession; - - parameters.shouldTrackVisitedLinks = m_historyClient.shouldTrackVisitedLinks(); - parameters.cacheModel = m_cacheModel; - parameters.languages = userPreferredLanguages(); - - copyToVector(m_schemesToRegisterAsEmptyDocument, parameters.urlSchemesRegistererdAsEmptyDocument); - copyToVector(m_schemesToRegisterAsSecure, parameters.urlSchemesRegisteredAsSecure); - copyToVector(m_schemesToSetDomainRelaxationForbiddenFor, parameters.urlSchemesForWhichDomainRelaxationIsForbidden); - copyToVector(m_schemesToRegisterAsLocal, parameters.urlSchemesRegisteredAsLocal); - copyToVector(m_schemesToRegisterAsNoAccess, parameters.urlSchemesRegisteredAsNoAccess); - copyToVector(m_schemesToRegisterAsDisplayIsolated, parameters.urlSchemesRegisteredAsDisplayIsolated); - copyToVector(m_schemesToRegisterAsCORSEnabled, parameters.urlSchemesRegisteredAsCORSEnabled); - - parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath; - parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing; - - parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty(); - - parameters.terminationTimeout = (m_processModel == ProcessModelSharedSecondaryProcess) ? sharedSecondaryProcessShutdownTimeout : 0; - - parameters.textCheckerState = TextChecker::state(); - - parameters.fullKeyboardAccessEnabled = WebProcessProxy::fullKeyboardAccessEnabled(); - - parameters.defaultRequestTimeoutInterval = API::URLRequest::defaultTimeoutInterval(); - -#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) - // FIXME: There should be a generic way for supplements to add to the intialization parameters. - supplement<WebNotificationManagerProxy>()->populateCopyOfNotificationPermissions(parameters.notificationPermissions); -#endif - -#if ENABLE(NETWORK_PROCESS) - parameters.usesNetworkProcess = m_usesNetworkProcess; -#endif - - parameters.plugInAutoStartOriginHashes = m_plugInAutoStartProvider.autoStartOriginHashesCopy(); - copyToVector(m_plugInAutoStartProvider.autoStartOrigins(), parameters.plugInAutoStartOrigins); - - parameters.memoryCacheDisabled = m_memoryCacheDisabled; - - // Add any platform specific parameters - platformInitializeWebProcess(parameters); - - RefPtr<API::Object> injectedBundleInitializationUserData = m_injectedBundleClient.getInjectedBundleInitializationUserData(this); - if (!injectedBundleInitializationUserData) - injectedBundleInitializationUserData = m_injectedBundleInitializationUserData; - process->send(Messages::WebProcess::InitializeWebProcess(parameters, WebContextUserMessageEncoder(injectedBundleInitializationUserData.get(), *process)), 0); - -#if PLATFORM(MAC) - process->send(Messages::WebProcess::SetQOS(webProcessLatencyQOS(), webProcessThroughputQOS()), 0); -#endif - - if (WebPreferences::anyPageGroupsAreUsingPrivateBrowsing()) - process->send(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionTracker::legacyPrivateSessionID), 0); - - m_processes.append(process); - - if (m_processModel == ProcessModelSharedSecondaryProcess) { - for (size_t i = 0; i != m_messagesToInjectedBundlePostedToEmptyContext.size(); ++i) { - std::pair<String, RefPtr<API::Object>>& message = m_messagesToInjectedBundlePostedToEmptyContext[i]; - - IPC::ArgumentEncoder messageData; - - messageData.encode(message.first); - messageData.encode(WebContextUserMessageEncoder(message.second.get(), *process)); - process->send(Messages::WebProcess::PostInjectedBundleMessage(IPC::DataReference(messageData.buffer(), messageData.bufferSize())), 0); - } - m_messagesToInjectedBundlePostedToEmptyContext.clear(); - } else - ASSERT(m_messagesToInjectedBundlePostedToEmptyContext.isEmpty()); - - return *process; -} - -void WebContext::warmInitialProcess() -{ - if (m_haveInitialEmptyProcess) { - ASSERT(!m_processes.isEmpty()); - return; - } - - if (m_processes.size() >= m_webProcessCountLimit) - return; - - createNewWebProcess(); - m_haveInitialEmptyProcess = true; -} - -void WebContext::enableProcessTermination() -{ - m_processTerminationEnabled = true; - Vector<RefPtr<WebProcessProxy>> processes = m_processes; - for (size_t i = 0; i < processes.size(); ++i) { - if (shouldTerminate(processes[i].get())) - processes[i]->terminate(); - } -} - -bool WebContext::shouldTerminate(WebProcessProxy* process) -{ - ASSERT(m_processes.contains(process)); - - if (!m_processTerminationEnabled) - return false; - - for (const auto& supplement : m_supplements.values()) { - if (!supplement->shouldTerminate(process)) - return false; - } - - return true; -} - -void WebContext::processWillOpenConnection(WebProcessProxy* process) -{ - m_storageManager->processWillOpenConnection(process); -} - -void WebContext::processWillCloseConnection(WebProcessProxy* process) -{ - m_storageManager->processWillCloseConnection(process); -} - -void WebContext::processDidFinishLaunching(WebProcessProxy* process) -{ - ASSERT(m_processes.contains(process)); - - m_visitedLinkProvider.processDidFinishLaunching(process); - - // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching - // so check if it needs to be started here - if (m_memorySamplerEnabled) { - SandboxExtension::Handle sampleLogSandboxHandle; - double now = WTF::currentTime(); - String sampleLogFilePath = String::format("WebProcess%llupid%d", static_cast<unsigned long long>(now), process->processIdentifier()); - sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle); - - process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0); - } - - m_connectionClient.didCreateConnection(this, process->webConnection()); -} - -void WebContext::disconnectProcess(WebProcessProxy* process) -{ - ASSERT(m_processes.contains(process)); - - m_visitedLinkProvider.processDidClose(process); - - if (m_haveInitialEmptyProcess && process == m_processes.last()) - m_haveInitialEmptyProcess = false; - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Some of the invalidation calls below are still necessary in multi-process mode, but they should only affect data structures pertaining to the process being disconnected. - // Clearing everything causes assertion failures, so it's less trouble to skip that for now. - if (m_processModel != ProcessModelSharedSecondaryProcess) { - RefPtr<WebProcessProxy> protect(process); - if (m_processWithPageCache == process) - m_processWithPageCache = 0; - - static_cast<WebContextSupplement*>(supplement<WebGeolocationManagerProxy>())->processDidClose(process); - - m_processes.remove(m_processes.find(process)); - return; - } - - WebContextSupplementMap::const_iterator it = m_supplements.begin(); - WebContextSupplementMap::const_iterator end = m_supplements.end(); - for (; it != end; ++it) - it->value->processDidClose(process); - - // The vector may have the last reference to process proxy, which in turn may have the last reference to the context. - // Since vector elements are destroyed in place, we would recurse into WebProcessProxy destructor - // if it were invoked from Vector::remove(). RefPtr delays destruction until it's safe. - RefPtr<WebProcessProxy> protect(process); - if (m_processWithPageCache == process) - m_processWithPageCache = 0; - m_processes.remove(m_processes.find(process)); -} - -WebProcessProxy& WebContext::createNewWebProcessRespectingProcessCountLimit() -{ - if (m_processes.size() < m_webProcessCountLimit) - return createNewWebProcess(); - - // Choose a process with fewest pages, to achieve flat distribution. - WebProcessProxy* result = nullptr; - unsigned fewestPagesSeen = UINT_MAX; - for (unsigned i = 0; i < m_processes.size(); ++i) { - if (fewestPagesSeen > m_processes[i]->pages().size()) { - result = m_processes[i].get(); - fewestPagesSeen = m_processes[i]->pages().size(); - } - } - return *result; -} - -PassRefPtr<WebPageProxy> WebContext::createWebPage(PageClient& pageClient, WebPageConfiguration configuration) -{ - if (!configuration.pageGroup) - configuration.pageGroup = &m_defaultPageGroup.get(); - if (!configuration.session) - configuration.session = configuration.pageGroup->preferences()->privateBrowsingEnabled() ? &API::Session::legacyPrivateSession() : &API::Session::defaultSession(); - - RefPtr<WebProcessProxy> process; - if (m_processModel == ProcessModelSharedSecondaryProcess) { - process = &ensureSharedWebProcess(); - } else { - if (m_haveInitialEmptyProcess) { - process = m_processes.last(); - m_haveInitialEmptyProcess = false; - } else if (configuration.relatedPage) { - // Sharing processes, e.g. when creating the page via window.open(). - process = &configuration.relatedPage->process(); - } else - process = &createNewWebProcessRespectingProcessCountLimit(); - } - - return process->createWebPage(pageClient, std::move(configuration)); -} - -DownloadProxy* WebContext::download(WebPageProxy* initiatingPage, const ResourceRequest& request) -{ - DownloadProxy* downloadProxy = createDownloadProxy(); - uint64_t initiatingPageID = initiatingPage ? initiatingPage->pageID() : 0; - -#if ENABLE(NETWORK_PROCESS) - if (usesNetworkProcess() && networkProcess()) { - // FIXME (NetworkProcess): Replicate whatever FrameLoader::setOriginalURLForDownloadRequest does with the request here. - networkProcess()->send(Messages::NetworkProcess::DownloadRequest(downloadProxy->downloadID(), request), 0); - return downloadProxy; - } -#endif - - m_processes[0]->send(Messages::WebProcess::DownloadRequest(downloadProxy->downloadID(), initiatingPageID, request), 0); - return downloadProxy; -} - -void WebContext::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody) -{ - if (m_processes.isEmpty()) { - if (m_processModel == ProcessModelSharedSecondaryProcess) - m_messagesToInjectedBundlePostedToEmptyContext.append(std::make_pair(messageName, messageBody)); - return; - } - - for (auto process : m_processes) { - // FIXME: Return early if the message body contains any references to WKPageRefs/WKFrameRefs etc. since they're local to a process. - IPC::ArgumentEncoder messageData; - messageData.encode(messageName); - messageData.encode(WebContextUserMessageEncoder(messageBody, *process.get())); - - process->send(Messages::WebProcess::PostInjectedBundleMessage(IPC::DataReference(messageData.buffer(), messageData.bufferSize())), 0); - } -} - -// InjectedBundle client - -void WebContext::didReceiveMessageFromInjectedBundle(const String& messageName, API::Object* messageBody) -{ - m_injectedBundleClient.didReceiveMessageFromInjectedBundle(this, messageName, messageBody); -} - -void WebContext::didReceiveSynchronousMessageFromInjectedBundle(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) -{ - m_injectedBundleClient.didReceiveSynchronousMessageFromInjectedBundle(this, messageName, messageBody, returnData); -} - -void WebContext::populateVisitedLinks() -{ - m_historyClient.populateVisitedLinks(this); -} - -WebContext::Statistics& WebContext::statistics() -{ - static Statistics statistics = Statistics(); - - return statistics; -} - -#if ENABLE(NETSCAPE_PLUGIN_API) -void WebContext::setAdditionalPluginsDirectory(const String& directory) -{ - Vector<String> directories; - directories.append(directory); - - m_pluginInfoStore.setAdditionalPluginsDirectories(directories); -} -#endif // ENABLE(NETSCAPE_PLUGIN_API) - -void WebContext::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) -{ - m_alwaysUsesComplexTextCodePath = alwaysUseComplexText; - sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText)); -} - -void WebContext::setShouldUseFontSmoothing(bool useFontSmoothing) -{ - m_shouldUseFontSmoothing = useFontSmoothing; - sendToAllProcesses(Messages::WebProcess::SetShouldUseFontSmoothing(useFontSmoothing)); -} - -void WebContext::registerURLSchemeAsEmptyDocument(const String& urlScheme) -{ - m_schemesToRegisterAsEmptyDocument.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme)); -} - -void WebContext::registerURLSchemeAsSecure(const String& urlScheme) -{ - m_schemesToRegisterAsSecure.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme)); -} - -void WebContext::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) -{ - m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme)); -} - -void WebContext::registerURLSchemeAsLocal(const String& urlScheme) -{ - m_schemesToRegisterAsLocal.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsLocal(urlScheme)); -} - -void WebContext::registerURLSchemeAsNoAccess(const String& urlScheme) -{ - m_schemesToRegisterAsNoAccess.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsNoAccess(urlScheme)); -} - -void WebContext::registerURLSchemeAsDisplayIsolated(const String& urlScheme) -{ - m_schemesToRegisterAsDisplayIsolated.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsDisplayIsolated(urlScheme)); -} - -void WebContext::registerURLSchemeAsCORSEnabled(const String& urlScheme) -{ - m_schemesToRegisterAsCORSEnabled.add(urlScheme); - sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCORSEnabled(urlScheme)); -} - -#if ENABLE(CUSTOM_PROTOCOLS) -HashSet<String>& WebContext::globalURLSchemesWithCustomProtocolHandlers() -{ - static NeverDestroyed<HashSet<String>> set; - return set; -} - -void WebContext::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme) -{ - if (!urlScheme) - return; - - String schemeLower = urlScheme.lower(); - globalURLSchemesWithCustomProtocolHandlers().add(schemeLower); - for (auto* context : allContexts()) - context->registerSchemeForCustomProtocol(schemeLower); -} - -void WebContext::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme) -{ - if (!urlScheme) - return; - - String schemeLower = urlScheme.lower(); - globalURLSchemesWithCustomProtocolHandlers().remove(schemeLower); - for (auto* context : allContexts()) - context->unregisterSchemeForCustomProtocol(schemeLower); -} -#endif - -void WebContext::setCacheModel(CacheModel cacheModel) -{ - m_cacheModel = cacheModel; - sendToAllProcesses(Messages::WebProcess::SetCacheModel(static_cast<uint32_t>(m_cacheModel))); - - // FIXME: Inform the Network Process if in use. -} - -void WebContext::setDefaultRequestTimeoutInterval(double timeoutInterval) -{ - sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval)); -} - -void WebContext::addVisitedLink(const String& visitedURL) -{ - if (visitedURL.isEmpty()) - return; - - LinkHash linkHash = visitedLinkHash(visitedURL); - addVisitedLinkHash(linkHash); -} - -void WebContext::addVisitedLinkHash(LinkHash linkHash) -{ - m_visitedLinkProvider.addVisitedLink(linkHash); -} - -DownloadProxy* WebContext::createDownloadProxy() -{ -#if ENABLE(NETWORK_PROCESS) - if (usesNetworkProcess()) { - ensureNetworkProcess(); - ASSERT(m_networkProcess); - return m_networkProcess->createDownloadProxy(); - } -#endif - - return ensureSharedWebProcess().createDownloadProxy(); -} - -void WebContext::addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver& messageReceiver) -{ - m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver); -} - -void WebContext::addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver& messageReceiver) -{ - m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver); -} - -void WebContext::removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID) -{ - m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID); -} - -bool WebContext::dispatchMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) -{ - return m_messageReceiverMap.dispatchMessage(connection, decoder); -} - -bool WebContext::dispatchSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) -{ - return m_messageReceiverMap.dispatchSyncMessage(connection, decoder, replyEncoder); -} - -void WebContext::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) -{ - if (decoder.messageReceiverName() == Messages::WebContext::messageReceiverName()) { - didReceiveWebContextMessage(connection, decoder); - return; - } - - if (decoder.messageReceiverName() == WebContextLegacyMessages::messageReceiverName() - && decoder.messageName() == WebContextLegacyMessages::postMessageMessageName()) { - String messageName; - RefPtr<API::Object> messageBody; - WebContextUserMessageDecoder messageBodyDecoder(messageBody, *WebProcessProxy::fromConnection(connection)); - if (!decoder.decode(messageName)) - return; - if (!decoder.decode(messageBodyDecoder)) - return; - - didReceiveMessageFromInjectedBundle(messageName, messageBody.get()); - return; - } - - ASSERT_NOT_REACHED(); -} - -void WebContext::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) -{ - if (decoder.messageReceiverName() == Messages::WebContext::messageReceiverName()) { - didReceiveSyncWebContextMessage(connection, decoder, replyEncoder); - return; - } - - if (decoder.messageReceiverName() == WebContextLegacyMessages::messageReceiverName() - && decoder.messageName() == WebContextLegacyMessages::postSynchronousMessageMessageName()) { - // FIXME: We should probably encode something in the case that the arguments do not decode correctly. - - WebProcessProxy* process = WebProcessProxy::fromConnection(connection); - - String messageName; - RefPtr<API::Object> messageBody; - WebContextUserMessageDecoder messageBodyDecoder(messageBody, *process); - if (!decoder.decode(messageName)) - return; - if (!decoder.decode(messageBodyDecoder)) - return; - - RefPtr<API::Object> returnData; - didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody.get(), returnData); - replyEncoder->encode(WebContextUserMessageEncoder(returnData.get(), *process)); - return; - } - - ASSERT_NOT_REACHED(); -} - -void WebContext::setEnhancedAccessibility(bool flag) -{ - sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag)); -} - -void WebContext::startMemorySampler(const double interval) -{ - // For new WebProcesses we will also want to start the Memory Sampler - m_memorySamplerEnabled = true; - m_memorySamplerInterval = interval; - - // For UIProcess -#if ENABLE(MEMORY_SAMPLER) - WebMemorySampler::shared()->start(interval); -#endif - - // For WebProcess - SandboxExtension::Handle sampleLogSandboxHandle; - double now = WTF::currentTime(); - String sampleLogFilePath = String::format("WebProcess%llu", static_cast<unsigned long long>(now)); - sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle); - - sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval)); -} - -void WebContext::stopMemorySampler() -{ - // For WebProcess - m_memorySamplerEnabled = false; - - // For UIProcess -#if ENABLE(MEMORY_SAMPLER) - WebMemorySampler::shared()->stop(); -#endif - - sendToAllProcesses(Messages::WebProcess::StopMemorySampler()); -} - -String WebContext::applicationCacheDirectory() const -{ - if (!m_overrideApplicationCacheDirectory.isEmpty()) - return m_overrideApplicationCacheDirectory; - - return platformDefaultApplicationCacheDirectory(); -} - -String WebContext::databaseDirectory() const -{ - if (!m_overrideDatabaseDirectory.isEmpty()) - return m_overrideDatabaseDirectory; - - return platformDefaultDatabaseDirectory(); -} - -void WebContext::setIconDatabasePath(const String& path) -{ - m_overrideIconDatabasePath = path; - m_iconDatabase->setDatabasePath(path); -} - -String WebContext::iconDatabasePath() const -{ - if (!m_overrideIconDatabasePath.isEmpty()) - return m_overrideIconDatabasePath; - - return platformDefaultIconDatabasePath(); -} - -void WebContext::setLocalStorageDirectory(const String& directory) -{ - m_overrideLocalStorageDirectory = directory; - m_storageManager->setLocalStorageDirectory(localStorageDirectory()); -} - -String WebContext::localStorageDirectory() const -{ - if (!m_overrideLocalStorageDirectory.isEmpty()) - return m_overrideLocalStorageDirectory; - - return platformDefaultLocalStorageDirectory(); -} - -String WebContext::diskCacheDirectory() const -{ - if (!m_overrideDiskCacheDirectory.isEmpty()) - return m_overrideDiskCacheDirectory; - - return platformDefaultDiskCacheDirectory(); -} - -String WebContext::cookieStorageDirectory() const -{ - if (!m_overrideCookieStorageDirectory.isEmpty()) - return m_overrideCookieStorageDirectory; - - return platformDefaultCookieStorageDirectory(); -} - -void WebContext::useTestingNetworkSession() -{ - ASSERT(m_processes.isEmpty()); -#if ENABLE(NETWORK_PROCESS) - ASSERT(!m_networkProcess); - - if (m_networkProcess) - return; -#endif - - if (!m_processes.isEmpty()) - return; - - m_shouldUseTestingNetworkSession = true; -} - -void WebContext::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host) -{ -#if ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess && m_networkProcess) { - m_networkProcess->send(Messages::NetworkProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0); - return; - } -#endif - -#if USE(SOUP) - m_processes[0]->send(Messages::WebProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0); - return; -#else - UNUSED_PARAM(certificate); - UNUSED_PARAM(host); -#endif - -#if !PLATFORM(IOS) - ASSERT_NOT_REACHED(); -#endif -} - -void WebContext::setHTTPPipeliningEnabled(bool enabled) -{ -#if PLATFORM(MAC) - ResourceRequest::setHTTPPipeliningEnabled(enabled); -#else - UNUSED_PARAM(enabled); -#endif -} - -bool WebContext::httpPipeliningEnabled() const -{ -#if PLATFORM(MAC) - return ResourceRequest::httpPipeliningEnabled(); -#else - return false; -#endif -} - -void WebContext::getStatistics(uint32_t statisticsMask, PassRefPtr<DictionaryCallback> callback) -{ - if (!statisticsMask) { - callback->invalidate(); - return; - } - - RefPtr<StatisticsRequest> request = StatisticsRequest::create(callback); - - if (statisticsMask & StatisticsRequestTypeWebContent) - requestWebContentStatistics(request.get()); - - if (statisticsMask & StatisticsRequestTypeNetworking) - requestNetworkingStatistics(request.get()); -} - -void WebContext::requestWebContentStatistics(StatisticsRequest* request) -{ - if (m_processModel == ProcessModelSharedSecondaryProcess) { - if (m_processes.isEmpty()) - return; - - uint64_t requestID = request->addOutstandingRequest(); - m_statisticsRequests.set(requestID, request); - m_processes[0]->send(Messages::WebProcess::GetWebCoreStatistics(requestID), 0); - - } else { - // FIXME (Multi-WebProcess) <rdar://problem/13200059>: Make getting statistics from multiple WebProcesses work. - } -} - -void WebContext::requestNetworkingStatistics(StatisticsRequest* request) -{ - bool networkProcessUnavailable; -#if ENABLE(NETWORK_PROCESS) - networkProcessUnavailable = !m_usesNetworkProcess || !m_networkProcess; -#else - networkProcessUnavailable = true; -#endif - - if (networkProcessUnavailable) { - LOG_ERROR("Attempt to get NetworkProcess statistics but the NetworkProcess is unavailable"); - return; - } - -#if ENABLE(NETWORK_PROCESS) - uint64_t requestID = request->addOutstandingRequest(); - m_statisticsRequests.set(requestID, request); - m_networkProcess->send(Messages::NetworkProcess::GetNetworkProcessStatistics(requestID), 0); -#else - UNUSED_PARAM(request); -#endif -} - -#if !PLATFORM(MAC) -void WebContext::dummy(bool&) -{ -} -#endif - -void WebContext::didGetStatistics(const StatisticsData& statisticsData, uint64_t requestID) -{ - RefPtr<StatisticsRequest> request = m_statisticsRequests.take(requestID); - if (!request) { - LOG_ERROR("Cannot report networking statistics."); - return; - } - - request->completedRequest(requestID, statisticsData); -} - -void WebContext::garbageCollectJavaScriptObjects() -{ - sendToAllProcesses(Messages::WebProcess::GarbageCollectJavaScriptObjects()); -} - -void WebContext::setJavaScriptGarbageCollectorTimerEnabled(bool flag) -{ - sendToAllProcesses(Messages::WebProcess::SetJavaScriptGarbageCollectorTimerEnabled(flag)); -} - -void WebContext::addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash) -{ - m_plugInAutoStartProvider.addAutoStartOriginHash(pageOrigin, plugInOriginHash); -} - -void WebContext::plugInDidReceiveUserInteraction(unsigned plugInOriginHash) -{ - m_plugInAutoStartProvider.didReceiveUserInteraction(plugInOriginHash); -} - -PassRefPtr<ImmutableDictionary> WebContext::plugInAutoStartOriginHashes() const -{ - return m_plugInAutoStartProvider.autoStartOriginsTableCopy(); -} - -void WebContext::setPlugInAutoStartOriginHashes(ImmutableDictionary& dictionary) -{ - m_plugInAutoStartProvider.setAutoStartOriginsTable(dictionary); -} - -void WebContext::setPlugInAutoStartOrigins(API::Array& array) -{ - m_plugInAutoStartProvider.setAutoStartOriginsArray(array); -} - -void WebContext::setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(ImmutableDictionary& dictionary, double time) -{ - m_plugInAutoStartProvider.setAutoStartOriginsFilteringOutEntriesAddedAfterTime(dictionary, time); -} - -#if ENABLE(CUSTOM_PROTOCOLS) -void WebContext::registerSchemeForCustomProtocol(const String& scheme) -{ - sendToNetworkingProcess(Messages::CustomProtocolManager::RegisterScheme(scheme)); -} - -void WebContext::unregisterSchemeForCustomProtocol(const String& scheme) -{ - sendToNetworkingProcess(Messages::CustomProtocolManager::UnregisterScheme(scheme)); -} -#endif - -#if ENABLE(NETSCAPE_PLUGIN_API) -void WebContext::pluginInfoStoreDidLoadPlugins(PluginInfoStore* store) -{ -#ifdef NDEBUG - UNUSED_PARAM(store); -#endif - ASSERT(store == &m_pluginInfoStore); - - Vector<PluginModuleInfo> pluginModules = m_pluginInfoStore.plugins(); - - Vector<RefPtr<API::Object>> plugins; - plugins.reserveInitialCapacity(pluginModules.size()); - - for (const auto& pluginModule : pluginModules) { - ImmutableDictionary::MapType map; - map.set(ASCIILiteral("path"), API::String::create(pluginModule.path)); - map.set(ASCIILiteral("name"), API::String::create(pluginModule.info.name)); - map.set(ASCIILiteral("file"), API::String::create(pluginModule.info.file)); - map.set(ASCIILiteral("desc"), API::String::create(pluginModule.info.desc)); - - Vector<RefPtr<API::Object>> mimeTypes; - mimeTypes.reserveInitialCapacity(pluginModule.info.mimes.size()); - for (const auto& mimeClassInfo : pluginModule.info.mimes) - mimeTypes.uncheckedAppend(API::String::create(mimeClassInfo.type)); - map.set(ASCIILiteral("mimes"), API::Array::create(std::move(mimeTypes))); - -#if PLATFORM(MAC) - map.set(ASCIILiteral("bundleId"), API::String::create(pluginModule.bundleIdentifier)); - map.set(ASCIILiteral("version"), API::String::create(pluginModule.versionString)); -#endif - - plugins.uncheckedAppend(ImmutableDictionary::create(std::move(map))); - } - - m_client.plugInInformationBecameAvailable(this, API::Array::create(std::move(plugins)).get()); -} -#endif - -void WebContext::setMemoryCacheDisabled(bool disabled) -{ - m_memoryCacheDisabled = disabled; - sendToAllProcesses(Messages::WebProcess::SetMemoryCacheDisabled(disabled)); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextClient.cpp b/Source/WebKit2/UIProcess/WebContextClient.cpp index fc718d92a..64dbdefaf 100644 --- a/Source/WebKit2/UIProcess/WebContextClient.cpp +++ b/Source/WebKit2/UIProcess/WebContextClient.cpp @@ -26,36 +26,32 @@ #include "config.h" #include "WebContextClient.h" -#include "APIArray.h" -#include "WebContext.h" +#include "WebProcessPool.h" namespace WebKit { -void WebContextClient::plugInAutoStartOriginHashesChanged(WebContext* context) +void WebContextClient::plugInAutoStartOriginHashesChanged(WebProcessPool* processPool) { if (!m_client.plugInAutoStartOriginHashesChanged) return; - m_client.plugInAutoStartOriginHashesChanged(toAPI(context), m_client.base.clientInfo); + m_client.plugInAutoStartOriginHashesChanged(toAPI(processPool), m_client.base.clientInfo); } -void WebContextClient::networkProcessDidCrash(WebContext* context) +void WebContextClient::networkProcessDidCrash(WebProcessPool* processPool) { if (!m_client.networkProcessDidCrash) return; - m_client.networkProcessDidCrash(toAPI(context), m_client.base.clientInfo); + m_client.networkProcessDidCrash(toAPI(processPool), m_client.base.clientInfo); } -void WebContextClient::plugInInformationBecameAvailable(WebContext* context, API::Array* plugInInfo) +void WebContextClient::databaseProcessDidCrash(WebProcessPool* processPool) { - if (!m_client.plugInInformationBecameAvailable) + if (!m_client.databaseProcessDidCrash) return; - // FIXME: The API contract expects us to hand a reference to the array here. This is wrong. - plugInInfo->ref(); - - m_client.plugInInformationBecameAvailable(toAPI(context), toAPI(plugInInfo), m_client.base.clientInfo); + m_client.databaseProcessDidCrash(toAPI(processPool), m_client.base.clientInfo); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextClient.h b/Source/WebKit2/UIProcess/WebContextClient.h index 03cdf5132..b25c4d3b9 100644 --- a/Source/WebKit2/UIProcess/WebContextClient.h +++ b/Source/WebKit2/UIProcess/WebContextClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2012, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,25 +27,25 @@ #define WebContextClient_h #include "APIClient.h" +#include "APIData.h" #include "WKContext.h" namespace API { -class Array; - template<> struct ClientTraits<WKContextClientBase> { - typedef std::tuple<WKContextClientV0> Versions; + typedef std::tuple<WKContextClientV0, WKContextClientV1, WKContextClientV2> Versions; }; } + namespace WebKit { -class WebContext; +class WebProcessPool; class WebContextClient : public API::Client<WKContextClientBase> { public: - void plugInAutoStartOriginHashesChanged(WebContext*); - void networkProcessDidCrash(WebContext*); - void plugInInformationBecameAvailable(WebContext*, API::Array*); + void plugInAutoStartOriginHashesChanged(WebProcessPool*); + void networkProcessDidCrash(WebProcessPool*); + void databaseProcessDidCrash(WebProcessPool*); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextConnectionClient.cpp b/Source/WebKit2/UIProcess/WebContextConnectionClient.cpp index 336e44967..3b47d0e13 100644 --- a/Source/WebKit2/UIProcess/WebContextConnectionClient.cpp +++ b/Source/WebKit2/UIProcess/WebContextConnectionClient.cpp @@ -27,15 +27,16 @@ #include "WebContextConnectionClient.h" #include "WKAPICast.h" +#include "WebProcessPool.h" namespace WebKit { -void WebContextConnectionClient::didCreateConnection(WebContext* context, WebConnection* connection) +void WebContextConnectionClient::didCreateConnection(WebProcessPool* processPool, WebConnection* connection) { if (!m_client.didCreateConnection) return; - m_client.didCreateConnection(toAPI(context), toAPI(connection), m_client.base.clientInfo); + m_client.didCreateConnection(toAPI(processPool), toAPI(connection), m_client.base.clientInfo); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextConnectionClient.h b/Source/WebKit2/UIProcess/WebContextConnectionClient.h index 11e1ccf2c..23bddf0a6 100644 --- a/Source/WebKit2/UIProcess/WebContextConnectionClient.h +++ b/Source/WebKit2/UIProcess/WebContextConnectionClient.h @@ -38,11 +38,11 @@ template<> struct ClientTraits<WKContextConnectionClientBase> { namespace WebKit { class WebConnection; -class WebContext; +class WebProcessPool; class WebContextConnectionClient : public API::Client<WKContextConnectionClientBase> { public: - void didCreateConnection(WebContext*, WebConnection*); + void didCreateConnection(WebProcessPool*, WebConnection*); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.cpp b/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.cpp index 9baf4f71b..c68a163ee 100644 --- a/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.cpp +++ b/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.cpp @@ -27,36 +27,37 @@ #include "WebContextInjectedBundleClient.h" #include "WKAPICast.h" +#include "WebProcessPool.h" #include <wtf/text/WTFString.h> using namespace WebCore; namespace WebKit { -void WebContextInjectedBundleClient::didReceiveMessageFromInjectedBundle(WebContext* context, const String& messageName, API::Object* messageBody) +void WebContextInjectedBundleClient::didReceiveMessageFromInjectedBundle(WebProcessPool* processPool, const String& messageName, API::Object* messageBody) { if (!m_client.didReceiveMessageFromInjectedBundle) return; - m_client.didReceiveMessageFromInjectedBundle(toAPI(context), toAPI(messageName.impl()), toAPI(messageBody), m_client.base.clientInfo); + m_client.didReceiveMessageFromInjectedBundle(toAPI(processPool), toAPI(messageName.impl()), toAPI(messageBody), m_client.base.clientInfo); } -void WebContextInjectedBundleClient::didReceiveSynchronousMessageFromInjectedBundle(WebContext* context, const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) +void WebContextInjectedBundleClient::didReceiveSynchronousMessageFromInjectedBundle(WebProcessPool* processPool, const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) { if (!m_client.didReceiveSynchronousMessageFromInjectedBundle) return; WKTypeRef returnDataRef = 0; - m_client.didReceiveSynchronousMessageFromInjectedBundle(toAPI(context), toAPI(messageName.impl()), toAPI(messageBody), &returnDataRef, m_client.base.clientInfo); + m_client.didReceiveSynchronousMessageFromInjectedBundle(toAPI(processPool), toAPI(messageName.impl()), toAPI(messageBody), &returnDataRef, m_client.base.clientInfo); returnData = adoptRef(toImpl(returnDataRef)); } -PassRefPtr<API::Object> WebContextInjectedBundleClient::getInjectedBundleInitializationUserData(WebContext* context) +PassRefPtr<API::Object> WebContextInjectedBundleClient::getInjectedBundleInitializationUserData(WebProcessPool* processPool) { if (!m_client.getInjectedBundleInitializationUserData) return 0; - return toImpl(m_client.getInjectedBundleInitializationUserData(toAPI(context), m_client.base.clientInfo)); + return adoptRef(toImpl(m_client.getInjectedBundleInitializationUserData(toAPI(processPool), m_client.base.clientInfo))); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.h b/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.h index f24c66f8e..c934fe8b7 100644 --- a/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.h +++ b/Source/WebKit2/UIProcess/WebContextInjectedBundleClient.h @@ -40,13 +40,13 @@ template<> struct ClientTraits<WKContextInjectedBundleClientBase> { namespace WebKit { -class WebContext; +class WebProcessPool; class WebContextInjectedBundleClient : public API::Client<WKContextInjectedBundleClientBase> { public: - void didReceiveMessageFromInjectedBundle(WebContext*, const String&, API::Object*); - void didReceiveSynchronousMessageFromInjectedBundle(WebContext*, const String&, API::Object*, RefPtr<API::Object>& returnData); - PassRefPtr<API::Object> getInjectedBundleInitializationUserData(WebContext*); + void didReceiveMessageFromInjectedBundle(WebProcessPool*, const String&, API::Object*); + void didReceiveSynchronousMessageFromInjectedBundle(WebProcessPool*, const String&, API::Object*, RefPtr<API::Object>& returnData); + PassRefPtr<API::Object> getInjectedBundleInitializationUserData(WebProcessPool*); }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextMenuListenerProxy.cpp b/Source/WebKit2/UIProcess/WebContextMenuListenerProxy.cpp new file mode 100644 index 000000000..d90270c4d --- /dev/null +++ b/Source/WebKit2/UIProcess/WebContextMenuListenerProxy.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if ENABLE(CONTEXT_MENUS) + +#include "config.h" +#include "WebContextMenuListenerProxy.h" + +#include "WKAPICast.h" +#include "WKArray.h" +#include "WebContextMenuItem.h" +#include "WebContextMenuItemData.h" + +using namespace WebCore; + +namespace WebKit { + +WebContextMenuListenerProxy::WebContextMenuListenerProxy(WebContextMenuProxy* contextMenuMac) + : m_contextMenuMac(contextMenuMac) +{ +} + +WebContextMenuListenerProxy::~WebContextMenuListenerProxy() +{ +} + +void WebContextMenuListenerProxy::useContextMenuItems(WKArrayRef items) +{ + if (!m_contextMenuMac) + return; + + RefPtr<API::Array> array = toImpl(items); + Vector<WebContextMenuItemData> dataItems; + + size_t newSize = array ? array->size() : 0; + for (size_t i = 0; i < newSize; ++i) { + WebContextMenuItem* item = array->at<WebContextMenuItem>(i); + if (!item) + continue; + + dataItems.append(item->data()); + } + + m_contextMenuMac->showContextMenuWithItems(dataItems); +} + +void WebContextMenuListenerProxy::invalidate() +{ + m_contextMenuMac = nullptr; +} + +} // namespace WebKit + +#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebKit2/UIProcess/WebColorPickerResultListenerProxy.h b/Source/WebKit2/UIProcess/WebContextMenuListenerProxy.h index 58268c6cc..a35847060 100644 --- a/Source/WebKit2/UIProcess/WebColorPickerResultListenerProxy.h +++ b/Source/WebKit2/UIProcess/WebContextMenuListenerProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS @@ -23,40 +23,37 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebColorPickerResultListenerProxy_h -#define WebColorPickerResultListenerProxy_h +#pragma once -#if ENABLE(INPUT_TYPE_COLOR) +#if ENABLE(CONTEXT_MENUS) #include "APIObject.h" +#include "WKArray.h" +#include "WebContextMenuProxy.h" #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> -#include <wtf/text/WTFString.h> namespace WebKit { +class WebContextMenuProxyMac; -class WebPageProxy; - -class WebColorPickerResultListenerProxy : public API::ObjectImpl<API::Object::Type::ColorPickerResultListener> { +class WebContextMenuListenerProxy : public API::ObjectImpl<API::Object::Type::ContextMenuListener> { public: - static PassRefPtr<WebColorPickerResultListenerProxy> create(WebPageProxy* page) + static PassRefPtr<WebContextMenuListenerProxy> create(WebContextMenuProxy* contextMenuMac) { - return adoptRef(new WebColorPickerResultListenerProxy(page)); + return adoptRef(new WebContextMenuListenerProxy(contextMenuMac)); } - virtual ~WebColorPickerResultListenerProxy(); + virtual ~WebContextMenuListenerProxy(); - void invalidate(); - void setColor(const String&); + void useContextMenuItems(WKArrayRef items); + void invalidate(); private: - explicit WebColorPickerResultListenerProxy(WebPageProxy*); + explicit WebContextMenuListenerProxy(WebContextMenuProxy*); - RefPtr<WebPageProxy> m_page; + WebContextMenuProxy* m_contextMenuMac; }; - + } // namespace WebKit -#endif // ENABLE(INPUT_TYPE_COLOR) - -#endif // WebColorPickerResultListenerProxy_h +#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebKit2/UIProcess/WebContextMenuProxy.cpp b/Source/WebKit2/UIProcess/WebContextMenuProxy.cpp index 4c4cb26c0..1764c4615 100644 --- a/Source/WebKit2/UIProcess/WebContextMenuProxy.cpp +++ b/Source/WebKit2/UIProcess/WebContextMenuProxy.cpp @@ -26,9 +26,13 @@ #include "config.h" #include "WebContextMenuProxy.h" +#if ENABLE(CONTEXT_MENUS) + namespace WebKit { -WebContextMenuProxy::WebContextMenuProxy() +WebContextMenuProxy::WebContextMenuProxy(const ContextMenuContextData& context, const UserData& userData) + : m_context(context) + , m_userData(userData) { } @@ -37,3 +41,5 @@ WebContextMenuProxy::~WebContextMenuProxy() } } // namespace WebKit + +#endif diff --git a/Source/WebKit2/UIProcess/WebContextMenuProxy.h b/Source/WebKit2/UIProcess/WebContextMenuProxy.h index 098552d3a..f45a50472 100644 --- a/Source/WebKit2/UIProcess/WebContextMenuProxy.h +++ b/Source/WebKit2/UIProcess/WebContextMenuProxy.h @@ -26,29 +26,33 @@ #ifndef WebContextMenuProxy_h #define WebContextMenuProxy_h -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/Vector.h> +#if ENABLE(CONTEXT_MENUS) -namespace WebCore { - class IntPoint; -} +#include "ContextMenuContextData.h" +#include "UserData.h" +#include <wtf/RefCounted.h> namespace WebKit { -class WebContextMenuItemData; +class WebContextMenuItem; -class WebContextMenuProxy : public RefCounted<WebContextMenuProxy> { +class WebContextMenuProxy { public: virtual ~WebContextMenuProxy(); - virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>& items) = 0; - virtual void hideContextMenu() = 0; + virtual void show() = 0; + + virtual void showContextMenuWithItems(const Vector<WebContextMenuItemData>& items) = 0; protected: - WebContextMenuProxy(); + WebContextMenuProxy(const ContextMenuContextData&, const UserData&); + + const ContextMenuContextData m_context; + const UserData m_userData; }; } // namespace WebKit +#endif + #endif // WebPopupMenuProxy_h diff --git a/Source/WebKit2/UIProcess/WebContextSupplement.h b/Source/WebKit2/UIProcess/WebContextSupplement.h index 69f87e4e4..31fe9c4a0 100644 --- a/Source/WebKit2/UIProcess/WebContextSupplement.h +++ b/Source/WebKit2/UIProcess/WebContextSupplement.h @@ -28,14 +28,15 @@ namespace WebKit { +class DatabaseProcessProxy; class NetworkProcessProxy; -class WebContext; +class WebProcessPool; class WebProcessProxy; class WebContextSupplement { public: - WebContextSupplement(WebContext* context) - : m_context(context) + WebContextSupplement(WebProcessPool* processPool) + : m_processPool(processPool) { } @@ -43,7 +44,7 @@ public: { } - virtual void contextDestroyed() + virtual void processPoolDestroyed() { } @@ -55,13 +56,12 @@ public: { } - virtual bool shouldTerminate(WebProcessProxy*) const + virtual void processDidClose(DatabaseProcessProxy*) { - return true; } - WebContext* context() const { return m_context; } - void clearContext() { m_context = 0; } + WebProcessPool* processPool() const { return m_processPool; } + void clearProcessPool() { m_processPool = nullptr; } void ref() { refWebContextSupplement(); } void deref() { derefWebContextSupplement(); } @@ -70,7 +70,7 @@ private: virtual void refWebContextSupplement() = 0; virtual void derefWebContextSupplement() = 0; - WebContext* m_context; + WebProcessPool* m_processPool; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContextUserMessageCoders.h b/Source/WebKit2/UIProcess/WebContextUserMessageCoders.h deleted file mode 100644 index f3c147a1e..000000000 --- a/Source/WebKit2/UIProcess/WebContextUserMessageCoders.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "UserMessageCoders.h" -#include "WebContext.h" -#include "WebFrameProxy.h" -#include "WebPageGroup.h" -#include "WebPageGroupData.h" -#include "WebPageProxy.h" - -#if PLATFORM(MAC) -#include "ObjCObjectGraphCoders.h" -#endif - -namespace WebKit { - -// Adds -// - Page -> BundlePage -// - Frame -> BundleFrame -// - PageGroup -> BundlePageGroup - -class WebContextUserMessageEncoder : public UserMessageEncoder<WebContextUserMessageEncoder> { -public: - typedef UserMessageEncoder<WebContextUserMessageEncoder> Base; - - explicit WebContextUserMessageEncoder(API::Object* root, WebProcessProxy& process) - : Base(root) - , m_process(process) - { - } - - WebContextUserMessageEncoder(const WebContextUserMessageEncoder& userMessageEncoder, API::Object* root) - : Base(root) - , m_process(userMessageEncoder.m_process) - { - } - - void encode(IPC::ArgumentEncoder& encoder) const - { - API::Object::Type type = API::Object::Type::Null; - if (baseEncode(encoder, *this, type)) - return; - - switch (type) { - case API::Object::Type::Page: { - WebPageProxy* page = static_cast<WebPageProxy*>(m_root); - encoder << page->pageID(); - break; - } - case API::Object::Type::Frame: { - WebFrameProxy* frame = static_cast<WebFrameProxy*>(m_root); - encoder << frame->frameID(); - break; - } - case API::Object::Type::PageGroup: { - WebPageGroup* pageGroup = static_cast<WebPageGroup*>(m_root); - encoder << pageGroup->data(); - break; - } -#if PLATFORM(MAC) - case API::Object::Type::ObjCObjectGraph: { - ObjCObjectGraph* objectGraph = static_cast<ObjCObjectGraph*>(m_root); - encoder << WebContextObjCObjectGraphEncoder(objectGraph, m_process); - break; - } -#endif - default: - ASSERT_NOT_REACHED(); - break; - } - } - -private: - WebProcessProxy& m_process; -}; - -// Adds -// - Page -> BundlePage -// - Frame -> BundleFrame -// - PageGroup -> BundlePageGroup - -class WebContextUserMessageDecoder : public UserMessageDecoder<WebContextUserMessageDecoder> { -public: - typedef UserMessageDecoder<WebContextUserMessageDecoder> Base; - - WebContextUserMessageDecoder(RefPtr<API::Object>& root, WebProcessProxy& process) - : Base(root) - , m_process(process) - { - } - - WebContextUserMessageDecoder(WebContextUserMessageDecoder& userMessageDecoder, RefPtr<API::Object>& root) - : Base(root) - , m_process(userMessageDecoder.m_process) - { - } - - static bool decode(IPC::ArgumentDecoder& decoder, WebContextUserMessageDecoder& coder) - { - API::Object::Type type = API::Object::Type::Null; - if (!Base::baseDecode(decoder, coder, type)) - return false; - - if (coder.m_root || type == API::Object::Type::Null) - return true; - - switch (type) { - case API::Object::Type::BundlePage: { - uint64_t pageID; - if (!decoder.decode(pageID)) - return false; - coder.m_root = coder.m_process.webPage(pageID); - break; - } - case API::Object::Type::BundleFrame: { - uint64_t frameID; - if (!decoder.decode(frameID)) - return false; - coder.m_root = coder.m_process.webFrame(frameID); - break; - } - case API::Object::Type::BundlePageGroup: { - uint64_t pageGroupID; - if (!decoder.decode(pageGroupID)) - return false; - coder.m_root = WebPageGroup::get(pageGroupID); - break; - } -#if PLATFORM(MAC) - case API::Object::Type::ObjCObjectGraph: { - RefPtr<ObjCObjectGraph> objectGraph; - WebContextObjCObjectGraphDecoder objectGraphDecoder(objectGraph, coder.m_process); - if (!decoder.decode(objectGraphDecoder)) - return false; - coder.m_root = objectGraph.get(); - break; - } -#endif - default: - return false; - } - - return true; - } - -private: - WebProcessProxy& m_process; -}; - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp b/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp index 091b96549..2a9b0dd4c 100644 --- a/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebCookieManagerProxy.cpp @@ -27,11 +27,11 @@ #include "WebCookieManagerProxy.h" #include "APIArray.h" -#include "SecurityOriginData.h" -#include "WebContext.h" +#include "APISecurityOrigin.h" #include "WebCookieManagerMessages.h" #include "WebCookieManagerProxyMessages.h" -#include "WebSecurityOrigin.h" +#include "WebProcessPool.h" +#include <WebCore/SecurityOriginData.h> namespace WebKit { @@ -40,18 +40,18 @@ const char* WebCookieManagerProxy::supplementName() return "WebCookieManagerProxy"; } -PassRefPtr<WebCookieManagerProxy> WebCookieManagerProxy::create(WebContext* context) +PassRefPtr<WebCookieManagerProxy> WebCookieManagerProxy::create(WebProcessPool* processPool) { - return adoptRef(new WebCookieManagerProxy(context)); + return adoptRef(new WebCookieManagerProxy(processPool)); } -WebCookieManagerProxy::WebCookieManagerProxy(WebContext* context) - : WebContextSupplement(context) +WebCookieManagerProxy::WebCookieManagerProxy(WebProcessPool* processPool) + : WebContextSupplement(processPool) #if USE(SOUP) , m_cookiePersistentStorageType(SoupCookiePersistentStorageSQLite) #endif { - WebContextSupplement::context()->addMessageReceiver(Messages::WebCookieManagerProxy::messageReceiverName(), *this); + WebContextSupplement::processPool()->addMessageReceiver(Messages::WebCookieManagerProxy::messageReceiverName(), *this); } WebCookieManagerProxy::~WebCookieManagerProxy() @@ -65,28 +65,22 @@ void WebCookieManagerProxy::initializeClient(const WKCookieManagerClientBase* cl // WebContextSupplement -void WebCookieManagerProxy::contextDestroyed() +void WebCookieManagerProxy::processPoolDestroyed() { - invalidateCallbackMap(m_arrayCallbacks); - invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks); + invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::OwnerWasInvalidated); + invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks, CallbackBase::Error::OwnerWasInvalidated); } void WebCookieManagerProxy::processDidClose(WebProcessProxy*) { - invalidateCallbackMap(m_arrayCallbacks); - invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks); + invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::ProcessExited); + invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks, CallbackBase::Error::ProcessExited); } void WebCookieManagerProxy::processDidClose(NetworkProcessProxy*) { - invalidateCallbackMap(m_arrayCallbacks); - invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks); -} - -bool WebCookieManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return context()->processModel() != ProcessModelSharedSecondaryProcess - || (m_arrayCallbacks.isEmpty() && m_httpCookieAcceptPolicyCallbacks.isEmpty()); + invalidateCallbackMap(m_arrayCallbacks, CallbackBase::Error::ProcessExited); + invalidateCallbackMap(m_httpCookieAcceptPolicyCallbacks, CallbackBase::Error::ProcessExited); } void WebCookieManagerProxy::refWebContextSupplement() @@ -99,15 +93,15 @@ void WebCookieManagerProxy::derefWebContextSupplement() API::Object::deref(); } -void WebCookieManagerProxy::getHostnamesWithCookies(PassRefPtr<ArrayCallback> prpCallback) +void WebCookieManagerProxy::getHostnamesWithCookies(WebCore::SessionID sessionID, std::function<void (API::Array*, CallbackBase::Error)> callbackFunction) { - RefPtr<ArrayCallback> callback = prpCallback; + auto callback = ArrayCallback::create(WTFMove(callbackFunction)); uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); + m_arrayCallbacks.set(callbackID, WTFMove(callback)); - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::GetHostnamesWithCookies(callbackID)); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::GetHostnamesWithCookies(sessionID, callbackID)); } - + void WebCookieManagerProxy::didGetHostnamesWithCookies(const Vector<String>& hostnames, uint64_t callbackID) { RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); @@ -116,54 +110,79 @@ void WebCookieManagerProxy::didGetHostnamesWithCookies(const Vector<String>& hos return; } - callback->performCallbackWithReturnValue(API::Array::createStringArray(hostnames).get()); + callback->performCallbackWithReturnValue(API::Array::createStringArray(hostnames).ptr()); +} + +void WebCookieManagerProxy::deleteCookiesForHostname(WebCore::SessionID sessionID, const String& hostname) +{ + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteCookiesForHostname(sessionID, hostname)); +} + +void WebCookieManagerProxy::deleteAllCookies(WebCore::SessionID sessionID) +{ + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteAllCookies(sessionID)); +} + +void WebCookieManagerProxy::deleteAllCookiesModifiedSince(WebCore::SessionID sessionID, std::chrono::system_clock::time_point time) +{ + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteAllCookiesModifiedSince(sessionID, time)); } -void WebCookieManagerProxy::deleteCookiesForHostname(const String& hostname) +void WebCookieManagerProxy::addCookie(WebCore::SessionID sessionID, const WebCore::Cookie& cookie, const String& hostname) { - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteCookiesForHostname(hostname)); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::AddCookie(sessionID, cookie, hostname)); } -void WebCookieManagerProxy::deleteAllCookies() +void WebCookieManagerProxy::startObservingCookieChanges(WebCore::SessionID sessionID) { - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::DeleteAllCookies()); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StartObservingCookieChanges(sessionID)); } -void WebCookieManagerProxy::startObservingCookieChanges() +void WebCookieManagerProxy::stopObservingCookieChanges(WebCore::SessionID sessionID) { - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StartObservingCookieChanges()); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StopObservingCookieChanges(sessionID)); } -void WebCookieManagerProxy::stopObservingCookieChanges() +void WebCookieManagerProxy::setCookieObserverCallback(WebCore::SessionID sessionID, std::function<void ()>&& callback) { - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::StopObservingCookieChanges()); + if (callback) + m_cookieObservers.set(sessionID, WTFMove(callback)); + else + m_cookieObservers.remove(sessionID); } -void WebCookieManagerProxy::cookiesDidChange() +void WebCookieManagerProxy::cookiesDidChange(WebCore::SessionID sessionID) { m_client.cookiesDidChange(this); + if (auto callback = m_cookieObservers.get(sessionID)) + callback(); } void WebCookieManagerProxy::setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { -#if PLATFORM(MAC) - persistHTTPCookieAcceptPolicy(policy); +#if PLATFORM(COCOA) + if (!processPool()->isUsingTestingNetworkSession()) + persistHTTPCookieAcceptPolicy(policy); #endif #if USE(SOUP) - context()->setInitialHTTPCookieAcceptPolicy(policy); + processPool()->setInitialHTTPCookieAcceptPolicy(policy); #endif - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::SetHTTPCookieAcceptPolicy(policy)); + // The policy is not sent to newly created processes (only Soup does that via setInitialHTTPCookieAcceptPolicy()). This is not a serious problem, because: + // - When testing, we only have one WebProcess and one NetworkProcess, and WebKitTestRunner never restarts them; + // - When not testing, Cocoa has the policy persisted, and thus new processes use it (even for ephemeral sessions). + processPool()->sendToAllProcesses(Messages::WebCookieManager::SetHTTPCookieAcceptPolicy(policy)); + processPool()->sendToNetworkingProcess(Messages::WebCookieManager::SetHTTPCookieAcceptPolicy(policy)); } -void WebCookieManagerProxy::getHTTPCookieAcceptPolicy(PassRefPtr<HTTPCookieAcceptPolicyCallback> prpCallback) +void WebCookieManagerProxy::getHTTPCookieAcceptPolicy(std::function<void (HTTPCookieAcceptPolicy, CallbackBase::Error)> callbackFunction) { - RefPtr<HTTPCookieAcceptPolicyCallback> callback = prpCallback; + auto callback = HTTPCookieAcceptPolicyCallback::create(WTFMove(callbackFunction)); uint64_t callbackID = callback->callbackID(); - m_httpCookieAcceptPolicyCallbacks.set(callbackID, callback.release()); + m_httpCookieAcceptPolicyCallbacks.set(callbackID, WTFMove(callback)); - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::GetHTTPCookieAcceptPolicy(callbackID)); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::GetHTTPCookieAcceptPolicy(callbackID)); } void WebCookieManagerProxy::didGetHTTPCookieAcceptPolicy(uint32_t policy, uint64_t callbackID) diff --git a/Source/WebKit2/UIProcess/WebCookieManagerProxy.h b/Source/WebKit2/UIProcess/WebCookieManagerProxy.h index cc15f7f17..44005bc36 100644 --- a/Source/WebKit2/UIProcess/WebCookieManagerProxy.h +++ b/Source/WebKit2/UIProcess/WebCookieManagerProxy.h @@ -31,6 +31,7 @@ #include "MessageReceiver.h" #include "WebContextSupplement.h" #include "WebCookieManagerProxyClient.h" +#include <WebCore/SessionID.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> @@ -43,32 +44,40 @@ namespace API { class Array; } +namespace WebCore { +struct Cookie; +} + namespace WebKit { -class WebContext; +class WebProcessPool; class WebProcessProxy; -typedef GenericCallback<WKArrayRef> ArrayCallback; -typedef GenericCallback<WKHTTPCookieAcceptPolicy, HTTPCookieAcceptPolicy> HTTPCookieAcceptPolicyCallback; +typedef GenericCallback<API::Array*> ArrayCallback; +typedef GenericCallback<HTTPCookieAcceptPolicy> HTTPCookieAcceptPolicyCallback; class WebCookieManagerProxy : public API::ObjectImpl<API::Object::Type::CookieManager>, public WebContextSupplement, private IPC::MessageReceiver { public: static const char* supplementName(); - static PassRefPtr<WebCookieManagerProxy> create(WebContext*); + static PassRefPtr<WebCookieManagerProxy> create(WebProcessPool*); virtual ~WebCookieManagerProxy(); void initializeClient(const WKCookieManagerClientBase*); - void getHostnamesWithCookies(PassRefPtr<ArrayCallback>); - void deleteCookiesForHostname(const String& hostname); - void deleteAllCookies(); + void getHostnamesWithCookies(WebCore::SessionID, std::function<void (API::Array*, CallbackBase::Error)>); + void deleteCookiesForHostname(WebCore::SessionID, const String& hostname); + void deleteAllCookies(WebCore::SessionID); + void deleteAllCookiesModifiedSince(WebCore::SessionID, std::chrono::system_clock::time_point); + void addCookie(WebCore::SessionID, const WebCore::Cookie&, const String& hostname); void setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy); - void getHTTPCookieAcceptPolicy(PassRefPtr<HTTPCookieAcceptPolicyCallback>); + void getHTTPCookieAcceptPolicy(std::function<void (HTTPCookieAcceptPolicy, CallbackBase::Error)>); - void startObservingCookieChanges(); - void stopObservingCookieChanges(); + void startObservingCookieChanges(WebCore::SessionID); + void stopObservingCookieChanges(WebCore::SessionID); + + void setCookieObserverCallback(WebCore::SessionID, std::function<void ()>&&); #if USE(SOUP) void setCookiePersistentStorage(const String& storagePath, uint32_t storageType); @@ -79,31 +88,32 @@ public: using API::Object::deref; private: - WebCookieManagerProxy(WebContext*); + WebCookieManagerProxy(WebProcessPool*); void didGetHostnamesWithCookies(const Vector<String>&, uint64_t callbackID); void didGetHTTPCookieAcceptPolicy(uint32_t policy, uint64_t callbackID); - void cookiesDidChange(); + void cookiesDidChange(WebCore::SessionID); // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual void processDidClose(NetworkProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; + void processPoolDestroyed() override; + void processDidClose(WebProcessProxy*) override; + void processDidClose(NetworkProcessProxy*) override; + void refWebContextSupplement() override; + void derefWebContextSupplement() override; // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void persistHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy); #endif HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; HashMap<uint64_t, RefPtr<HTTPCookieAcceptPolicyCallback>> m_httpCookieAcceptPolicyCallbacks; + HashMap<WebCore::SessionID, std::function<void ()>> m_cookieObservers; + WebCookieManagerProxyClient m_client; #if USE(SOUP) diff --git a/Source/WebKit2/UIProcess/WebCookieManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebCookieManagerProxy.messages.in index 49ac6db23..12e009018 100644 --- a/Source/WebKit2/UIProcess/WebCookieManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebCookieManagerProxy.messages.in @@ -24,5 +24,5 @@ messages -> WebCookieManagerProxy { DidGetHostnamesWithCookies(Vector<String> hostnames, uint64_t callbackID); DidGetHTTPCookieAcceptPolicy(uint32_t policy, uint64_t callbackID); - CookiesDidChange() + CookiesDidChange(WebCore::SessionID sessionID) } diff --git a/Source/WebKit2/UIProcess/WebCookieManagerProxyClient.cpp b/Source/WebKit2/UIProcess/WebCookieManagerProxyClient.cpp index 088f36cec..79c660f81 100644 --- a/Source/WebKit2/UIProcess/WebCookieManagerProxyClient.cpp +++ b/Source/WebKit2/UIProcess/WebCookieManagerProxyClient.cpp @@ -27,6 +27,7 @@ #include "WebCookieManagerProxyClient.h" #include "WKAPICast.h" +#include "WebCookieManagerProxy.h" namespace WebKit { diff --git a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.cpp b/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.cpp deleted file mode 100644 index afa7dc8e7..000000000 --- a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2010, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebDatabaseManagerProxy.h" - -#if ENABLE(SQL_DATABASE) - -#include "APIArray.h" -#include "ImmutableDictionary.h" -#include "WebContext.h" -#include "WebDatabaseManagerMessages.h" -#include "WebDatabaseManagerProxyMessages.h" -#include "WebSecurityOrigin.h" -#include <wtf/NeverDestroyed.h> - -using namespace WebCore; - -namespace WebKit { - -const char* WebDatabaseManagerProxy::supplementName() -{ - return "WebDatabaseManagerProxy"; -} - -String WebDatabaseManagerProxy::originKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginKey")); - return key; -} - -String WebDatabaseManagerProxy::originQuotaKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginQuotaKey")); - return key; -} - -String WebDatabaseManagerProxy::originUsageKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerOriginUsageKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsNameKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsNameKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsDisplayNameKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsDisplayNameKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsExpectedUsageKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsExpectedUsageKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsCurrentUsageKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsCurrentUsageKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsCreationTimeKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsCreationTimeKey")); - return key; -} - -String WebDatabaseManagerProxy::databaseDetailsModificationTimeKey() -{ - static NeverDestroyed<String> key(ASCIILiteral("WebDatabaseManagerDatabaseDetailsModificationTimeKey")); - return key; -} - -PassRefPtr<WebDatabaseManagerProxy> WebDatabaseManagerProxy::create(WebContext* webContext) -{ - return adoptRef(new WebDatabaseManagerProxy(webContext)); -} - -WebDatabaseManagerProxy::WebDatabaseManagerProxy(WebContext* webContext) - : WebContextSupplement(webContext) -{ - WebContextSupplement::context()->addMessageReceiver(Messages::WebDatabaseManagerProxy::messageReceiverName(), *this); -} - -WebDatabaseManagerProxy::~WebDatabaseManagerProxy() -{ -} - -void WebDatabaseManagerProxy::initializeClient(const WKDatabaseManagerClientBase* client) -{ - m_client.initialize(client); -} - -// WebContextSupplement - -void WebDatabaseManagerProxy::contextDestroyed() -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -void WebDatabaseManagerProxy::processDidClose(WebProcessProxy*) -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -bool WebDatabaseManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return m_arrayCallbacks.isEmpty(); -} - -void WebDatabaseManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebDatabaseManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebDatabaseManagerProxy::getDatabasesByOrigin(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - context()->sendToOneProcess(Messages::WebDatabaseManager::GetDatabasesByOrigin(callbackID)); -} - -void WebDatabaseManagerProxy::didGetDatabasesByOrigin(const Vector<OriginAndDatabases>& originAndDatabasesVector, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - Vector<RefPtr<API::Object>> result; - result.reserveInitialCapacity(originAndDatabasesVector.size()); - - for (const auto& originAndDatabases : originAndDatabasesVector) { - RefPtr<API::Object> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originAndDatabases.originIdentifier); - - Vector<RefPtr<API::Object>> databases; - databases.reserveInitialCapacity(originAndDatabases.databases.size()); - - for (const auto& databaseDetails : originAndDatabases.databases) { - HashMap<String, RefPtr<API::Object>> detailsMap; - - detailsMap.set(databaseDetailsNameKey(), API::String::create(databaseDetails.name())); - detailsMap.set(databaseDetailsDisplayNameKey(), API::String::create(databaseDetails.displayName())); - detailsMap.set(databaseDetailsExpectedUsageKey(), API::UInt64::create(databaseDetails.expectedUsage())); - detailsMap.set(databaseDetailsCurrentUsageKey(), API::UInt64::create(databaseDetails.currentUsage())); - if (databaseDetails.creationTime()) - detailsMap.set(databaseDetailsCreationTimeKey(), API::Double::create(databaseDetails.creationTime())); - if (databaseDetails.modificationTime()) - detailsMap.set(databaseDetailsModificationTimeKey(), API::Double::create(databaseDetails.modificationTime())); - - databases.uncheckedAppend(ImmutableDictionary::create(std::move(detailsMap))); - } - - HashMap<String, RefPtr<API::Object>> originAndDatabasesMap; - originAndDatabasesMap.set(originKey(), origin); - originAndDatabasesMap.set(originQuotaKey(), API::UInt64::create(originAndDatabases.originQuota)); - originAndDatabasesMap.set(originUsageKey(), API::UInt64::create(originAndDatabases.originUsage)); - originAndDatabasesMap.set(databaseDetailsKey(), API::Array::create(std::move(databases))); - - result.uncheckedAppend(ImmutableDictionary::create(std::move(originAndDatabasesMap))); - } - - callback->performCallbackWithReturnValue(API::Array::create(std::move(result)).get()); -} - -void WebDatabaseManagerProxy::getDatabaseOrigins(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - context()->sendToOneProcess(Messages::WebDatabaseManager::GetDatabaseOrigins(callbackID)); -} - -void WebDatabaseManagerProxy::didGetDatabaseOrigins(const Vector<String>& originIdentifiers, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - Vector<RefPtr<API::Object>> securityOrigins; - securityOrigins.reserveInitialCapacity(originIdentifiers.size()); - - for (const auto& originIdentifier : originIdentifiers) - securityOrigins.uncheckedAppend(WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier)); - - callback->performCallbackWithReturnValue(API::Array::create(std::move(securityOrigins)).get()); -} - -void WebDatabaseManagerProxy::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, WebSecurityOrigin* origin) -{ - context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteDatabaseWithNameForOrigin(databaseIdentifier, origin->databaseIdentifier())); -} - -void WebDatabaseManagerProxy::deleteDatabasesForOrigin(WebSecurityOrigin* origin) -{ - context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteDatabasesForOrigin(origin->databaseIdentifier())); -} - -void WebDatabaseManagerProxy::deleteAllDatabases() -{ - context()->sendToOneProcess(Messages::WebDatabaseManager::DeleteAllDatabases()); -} - -void WebDatabaseManagerProxy::setQuotaForOrigin(WebSecurityOrigin* origin, uint64_t quota) -{ - context()->sendToOneProcess(Messages::WebDatabaseManager::SetQuotaForOrigin(origin->databaseIdentifier(), quota)); -} - -void WebDatabaseManagerProxy::didModifyOrigin(const String& originIdentifier) -{ - RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier); - m_client.didModifyOrigin(this, origin.get()); -} - -void WebDatabaseManagerProxy::didModifyDatabase(const String& originIdentifier, const String& databaseIdentifier) -{ - RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier); - m_client.didModifyDatabase(this, origin.get(), databaseIdentifier); -} - -} // namespace WebKit - -#endif // ENABLE(SQL_DATABASE) diff --git a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.h b/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.h deleted file mode 100644 index b32f2ab81..000000000 --- a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2010, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebDatabaseManagerProxy_h -#define WebDatabaseManagerProxy_h - -#if ENABLE(SQL_DATABASE) - -#include "APIObject.h" -#include "Arguments.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "OriginAndDatabases.h" -#include "WebContextSupplement.h" -#include "WebDatabaseManagerProxyClient.h" -#include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> - -namespace WebKit { - -class WebContext; -class WebProcessProxy; -class WebSecurityOrigin; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebDatabaseManagerProxy : public API::ObjectImpl<API::Object::Type::DatabaseManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebDatabaseManagerProxy> create(WebContext*); - virtual ~WebDatabaseManagerProxy(); - - void initializeClient(const WKDatabaseManagerClientBase*); - - void getDatabasesByOrigin(PassRefPtr<ArrayCallback>); - void getDatabaseOrigins(PassRefPtr<ArrayCallback>); - void deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, WebSecurityOrigin*); - void deleteDatabasesForOrigin(WebSecurityOrigin*); - void deleteAllDatabases(); - void setQuotaForOrigin(WebSecurityOrigin*, uint64_t quota); - - static String originKey(); - static String originQuotaKey(); - static String originUsageKey(); - static String databaseDetailsKey(); - static String databaseDetailsNameKey(); - static String databaseDetailsDisplayNameKey(); - static String databaseDetailsExpectedUsageKey(); - static String databaseDetailsCurrentUsageKey(); - static String databaseDetailsCreationTimeKey(); - static String databaseDetailsModificationTimeKey(); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebDatabaseManagerProxy(WebContext*); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - // Message handlers. - void didGetDatabasesByOrigin(const Vector<OriginAndDatabases>& originAndDatabases, uint64_t callbackID); - void didGetDatabaseOrigins(const Vector<String>& originIdentifiers, uint64_t callbackID); - void didModifyOrigin(const String& originIdentifier); - void didModifyDatabase(const String& originIdentifier, const String& databaseIdentifier); - - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; - WebDatabaseManagerProxyClient m_client; -}; - -} // namespace WebKit - -#endif // ENABLE(SQL_DATABASE) - -#endif // DatabaseManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebDownloadClient.cpp b/Source/WebKit2/UIProcess/WebDownloadClient.cpp deleted file mode 100644 index 58b84507a..000000000 --- a/Source/WebKit2/UIProcess/WebDownloadClient.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebDownloadClient.h" - -#include "APIURLResponse.h" -#include "WKAPICast.h" -#include "WKRetainPtr.h" - -using namespace WebCore; - -namespace WebKit { - -void WebDownloadClient::didStart(WebContext* webContext, DownloadProxy* downloadProxy) -{ - if (!m_client.didStart) - return; - - m_client.didStart(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo); -} - -void WebDownloadClient::didReceiveAuthenticationChallenge(WebContext* webContext, DownloadProxy* downloadProxy, AuthenticationChallengeProxy* authenticationChallengeProxy) -{ - if (!m_client.didReceiveAuthenticationChallenge) - return; - - m_client.didReceiveAuthenticationChallenge(toAPI(webContext), toAPI(downloadProxy), toAPI(authenticationChallengeProxy), m_client.base.clientInfo); -} - -void WebDownloadClient::didReceiveResponse(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceResponse& response) -{ - if (!m_client.didReceiveResponse) - return; - - m_client.didReceiveResponse(toAPI(webContext), toAPI(downloadProxy), toAPI(API::URLResponse::create(response).get()), m_client.base.clientInfo); -} - -void WebDownloadClient::didReceiveData(WebContext* webContext, DownloadProxy* downloadProxy, uint64_t length) -{ - if (!m_client.didReceiveData) - return; - - m_client.didReceiveData(toAPI(webContext), toAPI(downloadProxy), length, m_client.base.clientInfo); -} - -bool WebDownloadClient::shouldDecodeSourceDataOfMIMEType(WebContext* webContext, DownloadProxy* downloadProxy, const String& mimeType) -{ - if (!m_client.shouldDecodeSourceDataOfMIMEType) - return true; - - return m_client.shouldDecodeSourceDataOfMIMEType(toAPI(webContext), toAPI(downloadProxy), toAPI(mimeType.impl()), m_client.base.clientInfo); -} - -String WebDownloadClient::decideDestinationWithSuggestedFilename(WebContext* webContext, DownloadProxy* downloadProxy, const String& filename, bool& allowOverwrite) -{ - if (!m_client.decideDestinationWithSuggestedFilename) - return String(); - - WKRetainPtr<WKStringRef> destination(AdoptWK, m_client.decideDestinationWithSuggestedFilename(toAPI(webContext), toAPI(downloadProxy), toAPI(filename.impl()), &allowOverwrite, m_client.base.clientInfo)); - return toWTFString(destination.get()); -} - -void WebDownloadClient::didCreateDestination(WebContext* webContext, DownloadProxy* downloadProxy, const String& path) -{ - if (!m_client.didCreateDestination) - return; - - m_client.didCreateDestination(toAPI(webContext), toAPI(downloadProxy), toAPI(path.impl()), m_client.base.clientInfo); -} - -void WebDownloadClient::didFinish(WebContext* webContext, DownloadProxy* downloadProxy) -{ - if (!m_client.didFinish) - return; - - m_client.didFinish(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo); -} - -void WebDownloadClient::didFail(WebContext* webContext, DownloadProxy* downloadProxy, const ResourceError& error) -{ - if (!m_client.didFail) - return; - - m_client.didFail(toAPI(webContext), toAPI(downloadProxy), toAPI(error), m_client.base.clientInfo); -} - -void WebDownloadClient::didCancel(WebContext* webContext, DownloadProxy* downloadProxy) -{ - if (!m_client.didCancel) - return; - - m_client.didCancel(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo); -} - -void WebDownloadClient::processDidCrash(WebContext* webContext, DownloadProxy* downloadProxy) -{ - if (!m_client.processDidCrash) - return; - - m_client.processDidCrash(toAPI(webContext), toAPI(downloadProxy), m_client.base.clientInfo); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebDownloadClient.h b/Source/WebKit2/UIProcess/WebDownloadClient.h deleted file mode 100644 index ec70c8468..000000000 --- a/Source/WebKit2/UIProcess/WebDownloadClient.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebDownloadClient_h -#define WebDownloadClient_h - -#include "APIClient.h" -#include "WKContext.h" -#include <wtf/Forward.h> - -namespace API { -template<> struct ClientTraits<WKContextDownloadClientBase> { - typedef std::tuple<WKContextDownloadClientV0> Versions; -}; -} - -namespace WebCore { - class ResourceError; - class ResourceResponse; -} - -namespace WebKit { - -class AuthenticationChallengeProxy; -class DownloadProxy; -class WebContext; - -class WebDownloadClient : public API::Client<WKContextDownloadClientBase> { -public: - void didStart(WebContext*, DownloadProxy*); - void didReceiveAuthenticationChallenge(WebContext*, DownloadProxy*, AuthenticationChallengeProxy*); - void didReceiveResponse(WebContext*, DownloadProxy*, const WebCore::ResourceResponse&); - void didReceiveData(WebContext*, DownloadProxy*, uint64_t length); - bool shouldDecodeSourceDataOfMIMEType(WebContext*, DownloadProxy*, const String& mimeType); - String decideDestinationWithSuggestedFilename(WebContext*, DownloadProxy*, const String& filename, bool& allowOverwrite); - void didCreateDestination(WebContext*, DownloadProxy*, const String& path); - void didFinish(WebContext*, DownloadProxy*); - void didFail(WebContext*, DownloadProxy*, const WebCore::ResourceError&); - void didCancel(WebContext*, DownloadProxy*); - void processDidCrash(WebContext*, DownloadProxy*); -}; - -} // namespace WebKit - -#endif // WebDownloadClient_h diff --git a/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp b/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp index d3e858438..24c62fbef 100644 --- a/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp +++ b/Source/WebKit2/UIProcess/WebEditCommandProxy.cpp @@ -55,7 +55,7 @@ void WebEditCommandProxy::unapply() if (!m_page || !m_page->isValid()) return; - m_page->process().send(Messages::WebPage::UnapplyEditCommand(m_commandID), m_page->pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply); + m_page->process().send(Messages::WebPage::UnapplyEditCommand(m_commandID), m_page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); m_page->registerEditCommand(this, WebPageProxy::Redo); } @@ -64,14 +64,18 @@ void WebEditCommandProxy::reapply() if (!m_page || !m_page->isValid()) return; - m_page->process().send(Messages::WebPage::ReapplyEditCommand(m_commandID), m_page->pageID(), IPC::DispatchMessageEvenWhenWaitingForSyncReply); + m_page->process().send(Messages::WebPage::ReapplyEditCommand(m_commandID), m_page->pageID(), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); m_page->registerEditCommand(this, WebPageProxy::Undo); } String WebEditCommandProxy::nameForEditAction(EditAction editAction) { + // FIXME: This is identical to code in WebKit's WebEditorClient class; would be nice to share the strings instead of having two copies. switch (editAction) { case EditActionUnspecified: + case EditActionInsert: + case EditActionInsertReplacement: + case EditActionInsertFromDrop: return String(); case EditActionSetColor: return WEB_UI_STRING_KEY("Set Color", "Set Color (Undo action name)", "Undo action name"); @@ -121,7 +125,7 @@ String WebEditCommandProxy::nameForEditAction(EditAction editAction) return WEB_UI_STRING_KEY("Outline", "Outline (Undo action name)", "Undo action name"); case EditActionUnscript: return WEB_UI_STRING_KEY("Unscript", "Unscript (Undo action name)", "Undo action name"); - case EditActionDrag: + case EditActionDeleteByDrag: return WEB_UI_STRING_KEY("Drag", "Drag (Undo action name)", "Undo action name"); case EditActionCut: return WEB_UI_STRING_KEY("Cut", "Cut (Undo action name)", "Undo action name"); @@ -129,25 +133,37 @@ String WebEditCommandProxy::nameForEditAction(EditAction editAction) return WEB_UI_STRING_KEY("Bold", "Bold (Undo action name)", "Undo action name"); case EditActionItalics: return WEB_UI_STRING_KEY("Italics", "Italics (Undo action name)", "Undo action name"); -#if PLATFORM(IOS) case EditActionDelete: return WEB_UI_STRING_KEY("Delete", "Delete (Undo action name)", "Undo action name"); case EditActionDictation: return WEB_UI_STRING_KEY("Dictation", "Dictation (Undo action name)", "Undo action name"); -#endif case EditActionPaste: return WEB_UI_STRING_KEY("Paste", "Paste (Undo action name)", "Undo action name"); case EditActionPasteFont: return WEB_UI_STRING_KEY("Paste Font", "Paste Font (Undo action name)", "Undo action name"); case EditActionPasteRuler: return WEB_UI_STRING_KEY("Paste Ruler", "Paste Ruler (Undo action name)", "Undo action name"); - case EditActionTyping: + case EditActionTypingDeleteSelection: + case EditActionTypingDeleteBackward: + case EditActionTypingDeleteForward: + case EditActionTypingDeleteWordBackward: + case EditActionTypingDeleteWordForward: + case EditActionTypingDeleteLineBackward: + case EditActionTypingDeleteLineForward: + case EditActionTypingDeletePendingComposition: + case EditActionTypingDeleteFinalComposition: + case EditActionTypingInsertText: + case EditActionTypingInsertLineBreak: + case EditActionTypingInsertParagraph: + case EditActionTypingInsertPendingComposition: + case EditActionTypingInsertFinalComposition: return WEB_UI_STRING_KEY("Typing", "Typing (Undo action name)", "Undo action name"); case EditActionCreateLink: return WEB_UI_STRING_KEY("Create Link", "Create Link (Undo action name)", "Undo action name"); case EditActionUnlink: return WEB_UI_STRING_KEY("Unlink", "Unlink (Undo action name)", "Undo action name"); - case EditActionInsertList: + case EditActionInsertUnorderedList: + case EditActionInsertOrderedList: return WEB_UI_STRING_KEY("Insert List", "Insert List (Undo action name)", "Undo action name"); case EditActionFormatBlock: return WEB_UI_STRING_KEY("Formatting", "Format Block (Undo action name)", "Undo action name"); diff --git a/Source/WebKit2/UIProcess/WebFindClient.cpp b/Source/WebKit2/UIProcess/WebFindClient.cpp deleted file mode 100644 index 42e21c798..000000000 --- a/Source/WebKit2/UIProcess/WebFindClient.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebFindClient.h" -#include "WKAPICast.h" -#include <wtf/text/WTFString.h> - -namespace WebKit { - -void WebFindClient::didFindString(WebPageProxy* page, const String& string, uint32_t matchCount) -{ - if (!m_client.didFindString) - return; - - m_client.didFindString(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo); - -} - -void WebFindClient::didFailToFindString(WebPageProxy* page, const String& string) -{ - if (!m_client.didFailToFindString) - return; - - m_client.didFailToFindString(toAPI(page), toAPI(string.impl()), m_client.base.clientInfo); -} - -void WebFindClient::didCountStringMatches(WebPageProxy* page, const String& string, uint32_t matchCount) -{ - if (!m_client.didCountStringMatches) - return; - - m_client.didCountStringMatches(toAPI(page), toAPI(string.impl()), matchCount, m_client.base.clientInfo); -} - -void WebFindMatchesClient::didFindStringMatches(WebPageProxy* page, const String& string, API::Array* matches, int firstIndex) -{ - if (!m_client.didFindStringMatches) - return; - - m_client.didFindStringMatches(toAPI(page), toAPI(string.impl()), toAPI(matches), firstIndex, m_client.base.clientInfo); -} - -void WebFindMatchesClient::didGetImageForMatchResult(WebPageProxy* page, WebImage* image, uint32_t index) -{ - if (!m_client.didGetImageForMatchResult) - return; - m_client.didGetImageForMatchResult(toAPI(page), toAPI(image), index, m_client.base.clientInfo); -} - -} // namespace WebKit - diff --git a/Source/WebKit2/UIProcess/WebFormClient.cpp b/Source/WebKit2/UIProcess/WebFormClient.cpp index 271e9eaa2..716b7bd60 100644 --- a/Source/WebKit2/UIProcess/WebFormClient.cpp +++ b/Source/WebKit2/UIProcess/WebFormClient.cpp @@ -26,24 +26,31 @@ #include "config.h" #include "WebFormClient.h" +#include "APIDictionary.h" #include "APIString.h" -#include "ImmutableDictionary.h" #include "WKAPICast.h" +#include "WebFormSubmissionListenerProxy.h" +#include "WebPageProxy.h" namespace WebKit { -bool WebFormClient::willSubmitForm(WebPageProxy* page, WebFrameProxy* frame, WebFrameProxy* sourceFrame, const Vector<std::pair<String, String>>& textFieldValues, API::Object* userData, WebFormSubmissionListenerProxy* listener) +WebFormClient::WebFormClient(const WKPageFormClientBase* wkClient) { - if (!m_client.willSubmitForm) - return false; + initialize(wkClient); +} + +void WebFormClient::willSubmitForm(WebPageProxy& page, WebFrameProxy& frame, WebFrameProxy& sourceFrame, const Vector<std::pair<String, String>>& textFieldValues, API::Object* userData, Ref<WebFormSubmissionListenerProxy>&& listener) +{ + if (!m_client.willSubmitForm) { + listener->continueSubmission(); + return; + } - ImmutableDictionary::MapType map; + API::Dictionary::MapType map; for (size_t i = 0; i < textFieldValues.size(); ++i) map.set(textFieldValues[i].first, API::String::create(textFieldValues[i].second)); - RefPtr<ImmutableDictionary> textFieldsMap = ImmutableDictionary::create(std::move(map)); - - m_client.willSubmitForm(toAPI(page), toAPI(frame), toAPI(sourceFrame), toAPI(textFieldsMap.get()), toAPI(userData), toAPI(listener), m_client.base.clientInfo); - return true; + Ref<API::Dictionary> textFieldsMap = API::Dictionary::create(WTFMove(map)); + m_client.willSubmitForm(toAPI(&page), toAPI(&frame), toAPI(&sourceFrame), toAPI(textFieldsMap.ptr()), toAPI(userData), toAPI(&listener.get()), m_client.base.clientInfo); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFormClient.h b/Source/WebKit2/UIProcess/WebFormClient.h index 38e12ddd3..f2a6d67ea 100644 --- a/Source/WebKit2/UIProcess/WebFormClient.h +++ b/Source/WebKit2/UIProcess/WebFormClient.h @@ -27,14 +27,10 @@ #define WebFormClient_h #include "APIClient.h" -#include "WKPage.h" -#include <utility> -#include <wtf/Forward.h> -#include <wtf/Vector.h> +#include "APIFormClient.h" +#include "WKPageFormClient.h" namespace API { -class Object; - template<> struct ClientTraits<WKPageFormClientBase> { typedef std::tuple<WKPageFormClientV0> Versions; }; @@ -42,13 +38,11 @@ template<> struct ClientTraits<WKPageFormClientBase> { namespace WebKit { -class WebPageProxy; -class WebFrameProxy; -class WebFormSubmissionListenerProxy; - -class WebFormClient : public API::Client<WKPageFormClientBase> { +class WebFormClient : public API::FormClient, API::Client<WKPageFormClientBase> { public: - bool willSubmitForm(WebPageProxy*, WebFrameProxy*, WebFrameProxy*, const Vector<std::pair<String, String>>& textFieldValues, API::Object* userData, WebFormSubmissionListenerProxy*); + explicit WebFormClient(const WKPageFormClientBase*); + + void willSubmitForm(WebPageProxy&, WebFrameProxy&, WebFrameProxy&, const Vector<std::pair<String, String>>& textFieldValues, API::Object* userData, Ref<WebFormSubmissionListenerProxy>&&) override; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.cpp b/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.cpp index dcc864afe..b4413d05b 100644 --- a/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "WebFormSubmissionListenerProxy.h" +#include "WebsitePolicies.h" + namespace WebKit { WebFormSubmissionListenerProxy::WebFormSubmissionListenerProxy(WebFrameProxy* frame, uint64_t listenerID) @@ -35,7 +37,7 @@ WebFormSubmissionListenerProxy::WebFormSubmissionListenerProxy(WebFrameProxy* fr void WebFormSubmissionListenerProxy::continueSubmission() { - receivedPolicyDecision(WebCore::PolicyUse); + receivedPolicyDecision(WebCore::PolicyUse, { }); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.h b/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.h index 48420b2b6..f6f6ec3b4 100644 --- a/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.h +++ b/Source/WebKit2/UIProcess/WebFormSubmissionListenerProxy.h @@ -28,11 +28,11 @@ #include "WebFrameListenerProxy.h" -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include "WKFoundation.h" #endif -#define DELEGATE_REF_COUNTING_TO_COCOA (PLATFORM(MAC) && WK_API_ENABLED) +#define DELEGATE_REF_COUNTING_TO_COCOA (PLATFORM(COCOA) && WK_API_ENABLED) namespace WebKit { @@ -52,7 +52,7 @@ public: private: WebFormSubmissionListenerProxy(WebFrameProxy*, uint64_t listenerID); - virtual Type type() const { return APIType; } + Type type() const override { return APIType; } #if DELEGATE_REF_COUNTING_TO_COCOA void* operator new(size_t size) { return newObject(size, APIType); } diff --git a/Source/WebKit2/UIProcess/WebFrameListenerProxy.cpp b/Source/WebKit2/UIProcess/WebFrameListenerProxy.cpp index b998f5836..5add2794f 100644 --- a/Source/WebKit2/UIProcess/WebFrameListenerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFrameListenerProxy.cpp @@ -42,16 +42,16 @@ WebFrameListenerProxy::~WebFrameListenerProxy() void WebFrameListenerProxy::invalidate() { - m_frame = 0; + m_frame = nullptr; } -void WebFrameListenerProxy::receivedPolicyDecision(WebCore::PolicyAction action) +void WebFrameListenerProxy::receivedPolicyDecision(WebCore::PolicyAction action, const WebsitePolicies& websitePolicies) { if (!m_frame) return; - m_frame->receivedPolicyDecision(action, m_listenerID); - m_frame = 0; + m_frame->receivedPolicyDecision(action, m_listenerID, m_navigation.get(), websitePolicies); + m_frame = nullptr; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFrameListenerProxy.h b/Source/WebKit2/UIProcess/WebFrameListenerProxy.h index 8b3ee3653..70380d6d1 100644 --- a/Source/WebKit2/UIProcess/WebFrameListenerProxy.h +++ b/Source/WebKit2/UIProcess/WebFrameListenerProxy.h @@ -23,17 +23,19 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebFrameListenerProxy_h -#define WebFrameListenerProxy_h +#pragma once +#include "APINavigation.h" #include "APIObject.h" #include <WebCore/FrameLoaderTypes.h> #include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> #include <wtf/RefPtr.h> namespace WebKit { class WebFrameProxy; +struct WebsitePolicies; class WebFrameListenerProxy : public API::Object { public: @@ -42,16 +44,18 @@ public: void invalidate(); uint64_t listenerID() const { return m_listenerID; } + API::Navigation* navigation() { return m_navigation.get(); } + void setNavigation(Ref<API::Navigation>&& navigation) { m_navigation = WTFMove(navigation); } + protected: WebFrameListenerProxy(WebFrameProxy*, uint64_t listenerID); - void receivedPolicyDecision(WebCore::PolicyAction); + void receivedPolicyDecision(WebCore::PolicyAction, const WebsitePolicies&); private: RefPtr<WebFrameProxy> m_frame; uint64_t m_listenerID; + RefPtr<API::Navigation> m_navigation; }; } // namespace WebKit - -#endif // WebFrameListenerProxy_h diff --git a/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.cpp b/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.cpp index 576453343..ef5e29b5f 100644 --- a/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.cpp @@ -27,6 +27,7 @@ #include "WebFramePolicyListenerProxy.h" #include "WebFrameProxy.h" +#include "WebsitePolicies.h" namespace WebKit { @@ -35,19 +36,19 @@ WebFramePolicyListenerProxy::WebFramePolicyListenerProxy(WebFrameProxy* frame, u { } -void WebFramePolicyListenerProxy::use() +void WebFramePolicyListenerProxy::use(const WebsitePolicies& websitePolicies) { - receivedPolicyDecision(WebCore::PolicyUse); + receivedPolicyDecision(WebCore::PolicyUse, websitePolicies); } void WebFramePolicyListenerProxy::download() { - receivedPolicyDecision(WebCore::PolicyDownload); + receivedPolicyDecision(WebCore::PolicyDownload, { }); } void WebFramePolicyListenerProxy::ignore() { - receivedPolicyDecision(WebCore::PolicyIgnore); + receivedPolicyDecision(WebCore::PolicyIgnore, { }); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.h b/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.h index 6f1367354..379efd204 100644 --- a/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.h +++ b/Source/WebKit2/UIProcess/WebFramePolicyListenerProxy.h @@ -23,16 +23,15 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebFramePolicyListenerProxy_h -#define WebFramePolicyListenerProxy_h +#pragma once #include "WebFrameListenerProxy.h" -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include "WKFoundation.h" #endif -#define DELEGATE_REF_COUNTING_TO_COCOA (PLATFORM(MAC) && WK_API_ENABLED) +#define DELEGATE_REF_COUNTING_TO_COCOA (PLATFORM(COCOA) && WK_API_ENABLED) namespace WebKit { @@ -40,19 +39,19 @@ class WebFramePolicyListenerProxy : public WebFrameListenerProxy { public: static const Type APIType = Type::FramePolicyListener; - static PassRefPtr<WebFramePolicyListenerProxy> create(WebFrameProxy* frame, uint64_t listenerID) + static Ref<WebFramePolicyListenerProxy> create(WebFrameProxy* frame, uint64_t listenerID) { - return adoptRef(new WebFramePolicyListenerProxy(frame, listenerID)); + return adoptRef(*new WebFramePolicyListenerProxy(frame, listenerID)); } - void use(); + void use(const WebsitePolicies&); void download(); void ignore(); private: WebFramePolicyListenerProxy(WebFrameProxy*, uint64_t listenerID); - virtual Type type() const { return APIType; } + Type type() const override { return APIType; } #if DELEGATE_REF_COUNTING_TO_COCOA void* operator new(size_t size) { return newObject(size, APIType); } @@ -62,5 +61,3 @@ private: } // namespace WebKit #undef DELEGATE_REF_COUNTING_TO_COCOA - -#endif // WebFramePolicyListenerProxy_h diff --git a/Source/WebKit2/UIProcess/WebFrameProxy.cpp b/Source/WebKit2/UIProcess/WebFrameProxy.cpp index ea26db29d..b13102fd9 100644 --- a/Source/WebKit2/UIProcess/WebFrameProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFrameProxy.cpp @@ -27,12 +27,12 @@ #include "WebFrameProxy.h" #include "WebCertificateInfo.h" -#include "WebContext.h" #include "WebFormSubmissionListenerProxy.h" #include "WebFramePolicyListenerProxy.h" #include "WebPageMessages.h" #include "WebPageProxy.h" -#include <WebCore/DOMImplementation.h> +#include "WebPasteboardProxy.h" +#include "WebProcessPool.h" #include <WebCore/Image.h> #include <WebCore/MIMETypeRegistry.h> #include <stdio.h> @@ -47,21 +47,24 @@ WebFrameProxy::WebFrameProxy(WebPageProxy* page, uint64_t frameID) , m_isFrameSet(false) , m_frameID(frameID) { - WebContext::statistics().wkFrameCount++; + WebProcessPool::statistics().wkFrameCount++; } WebFrameProxy::~WebFrameProxy() { - WebContext::statistics().wkFrameCount--; + WebProcessPool::statistics().wkFrameCount--; +#if PLATFORM(GTK) + WebPasteboardProxy::singleton().didDestroyFrame(this); +#endif } -void WebFrameProxy::disconnect() +void WebFrameProxy::webProcessWillShutDown() { - m_page = 0; + m_page = nullptr; if (m_activeListener) { m_activeListener->invalidate(); - m_activeListener = 0; + m_activeListener = nullptr; } } @@ -110,17 +113,20 @@ bool WebFrameProxy::isDisplayingStandaloneImageDocument() const return Image::supportsType(m_MIMEType); } +bool WebFrameProxy::isDisplayingStandaloneMediaDocument() const +{ + return MIMETypeRegistry::isSupportedMediaMIMEType(m_MIMEType); +} + bool WebFrameProxy::isDisplayingMarkupDocument() const { - // FIXME: This check should be moved to somewhere in WebCore. - return m_MIMEType == "text/html" || m_MIMEType == "image/svg+xml" || m_MIMEType == "application/x-webarchive" || DOMImplementation::isXMLMIMEType(m_MIMEType); + // FIXME: This should be a call to a single MIMETypeRegistry function; adding a new one if needed. + // FIXME: This is doing case sensitive comparisons on MIME types, should be using ASCII case insensitive instead. + return m_MIMEType == "text/html" || m_MIMEType == "image/svg+xml" || m_MIMEType == "application/x-webarchive" || MIMETypeRegistry::isXMLMIMEType(m_MIMEType); } bool WebFrameProxy::isDisplayingPDFDocument() const { - if (m_MIMEType.isEmpty()) - return false; - return MIMETypeRegistry::isPDFOrPostScriptMIMEType(m_MIMEType); } @@ -139,14 +145,15 @@ void WebFrameProxy::didFailProvisionalLoad() m_frameLoadState.didFailProvisionalLoad(); } -void WebFrameProxy::didCommitLoad(const String& contentType, const WebCore::CertificateInfo& certificateInfo) +void WebFrameProxy::didCommitLoad(const String& contentType, WebCertificateInfo& certificateInfo, bool containsPluginDocument) { m_frameLoadState.didCommitLoad(); m_title = String(); m_MIMEType = contentType; m_isFrameSet = false; - m_certificateInfo = WebCertificateInfo::create(certificateInfo); + m_certificateInfo = &certificateInfo; + m_containsPluginDocument = containsPluginDocument; } void WebFrameProxy::didFinishLoad() @@ -169,60 +176,60 @@ void WebFrameProxy::didChangeTitle(const String& title) m_title = title; } -void WebFrameProxy::receivedPolicyDecision(WebCore::PolicyAction action, uint64_t listenerID) +void WebFrameProxy::receivedPolicyDecision(WebCore::PolicyAction action, uint64_t listenerID, API::Navigation* navigation, const WebsitePolicies& websitePolicies) { if (!m_page) return; ASSERT(m_activeListener); ASSERT(m_activeListener->listenerID() == listenerID); - m_page->receivedPolicyDecision(action, this, listenerID); + m_page->receivedPolicyDecision(action, *this, listenerID, navigation, websitePolicies); } -WebFramePolicyListenerProxy* WebFrameProxy::setUpPolicyListenerProxy(uint64_t listenerID) +WebFramePolicyListenerProxy& WebFrameProxy::setUpPolicyListenerProxy(uint64_t listenerID) { if (m_activeListener) m_activeListener->invalidate(); m_activeListener = WebFramePolicyListenerProxy::create(this, listenerID); - return static_cast<WebFramePolicyListenerProxy*>(m_activeListener.get()); + return *static_cast<WebFramePolicyListenerProxy*>(m_activeListener.get()); } -WebFormSubmissionListenerProxy* WebFrameProxy::setUpFormSubmissionListenerProxy(uint64_t listenerID) +WebFormSubmissionListenerProxy& WebFrameProxy::setUpFormSubmissionListenerProxy(uint64_t listenerID) { if (m_activeListener) m_activeListener->invalidate(); m_activeListener = WebFormSubmissionListenerProxy::create(this, listenerID); - return static_cast<WebFormSubmissionListenerProxy*>(m_activeListener.get()); + return *static_cast<WebFormSubmissionListenerProxy*>(m_activeListener.get()); } -void WebFrameProxy::getWebArchive(PassRefPtr<DataCallback> callback) +void WebFrameProxy::getWebArchive(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { if (!m_page) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - m_page->getWebArchiveOfFrame(this, callback); + m_page->getWebArchiveOfFrame(this, callbackFunction); } -void WebFrameProxy::getMainResourceData(PassRefPtr<DataCallback> callback) +void WebFrameProxy::getMainResourceData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { if (!m_page) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - m_page->getMainResourceDataOfFrame(this, callback); + m_page->getMainResourceDataOfFrame(this, callbackFunction); } -void WebFrameProxy::getResourceData(API::URL* resourceURL, PassRefPtr<DataCallback> callback) +void WebFrameProxy::getResourceData(API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { if (!m_page) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - m_page->getResourceDataFromFrame(this, resourceURL, callback); + m_page->getResourceDataFromFrame(this, resourceURL, callbackFunction); } void WebFrameProxy::setUnreachableURL(const String& unreachableURL) @@ -230,4 +237,35 @@ void WebFrameProxy::setUnreachableURL(const String& unreachableURL) m_frameLoadState.setUnreachableURL(unreachableURL); } +#if ENABLE(CONTENT_FILTERING) +bool WebFrameProxy::didHandleContentFilterUnblockNavigation(const WebCore::ResourceRequest& request) +{ + if (!m_contentFilterUnblockHandler.canHandleRequest(request)) { + m_contentFilterUnblockHandler = { }; + return false; + } + + RefPtr<WebPageProxy> page { m_page }; + ASSERT(page); + m_contentFilterUnblockHandler.requestUnblockAsync([page](bool unblocked) { + if (unblocked) { + const bool reloadFromOrigin = false; + const bool contentBlockersEnabled = true; + page->reload(reloadFromOrigin, contentBlockersEnabled); + } + }); + return true; +} +#endif + +#if PLATFORM(GTK) +void WebFrameProxy::collapseSelection() +{ + if (!m_page) + return; + + m_page->process().send(Messages::WebPage::CollapseSelectionInFrame(m_frameID), m_page->pageID()); +} +#endif + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFrameProxy.h b/Source/WebKit2/UIProcess/WebFrameProxy.h index d82decbbe..24bfc99ea 100644 --- a/Source/WebKit2/UIProcess/WebFrameProxy.h +++ b/Source/WebKit2/UIProcess/WebFrameProxy.h @@ -23,8 +23,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebFrameProxy_h -#define WebFrameProxy_h +#pragma once #include "APIObject.h" #include "FrameLoadState.h" @@ -35,13 +34,17 @@ #include <wtf/PassRefPtr.h> #include <wtf/text/WTFString.h> -namespace IPC { - class ArgumentDecoder; - class Connection; +#if ENABLE(CONTENT_FILTERING) +#include <WebCore/ContentFilterUnblockHandler.h> +#endif + +namespace API { +class Navigation; } -namespace WebCore { -class CertificateInfo; +namespace IPC { +class Connection; +class Decoder; } namespace WebKit { @@ -49,8 +52,9 @@ class WebCertificateInfo; class WebFormSubmissionListenerProxy; class WebFramePolicyListenerProxy; class WebPageProxy; +struct WebsitePolicies; -typedef GenericCallback<WKDataRef> DataCallback; +typedef GenericCallback<API::Data*> DataCallback; class WebFrameProxy : public API::ObjectImpl<API::Object::Type::Frame> { public: @@ -64,7 +68,7 @@ public: uint64_t frameID() const { return m_frameID; } WebPageProxy* page() const { return m_page; } - void disconnect(); + void webProcessWillShutDown(); bool isMainFrame() const; @@ -76,13 +80,14 @@ public: void loadURL(const String&); void stopLoading() const; - const String& url() const { return m_frameLoadState.m_url; } - const String& provisionalURL() const { return m_frameLoadState.m_provisionalURL; } + const String& url() const { return m_frameLoadState.url(); } + const String& provisionalURL() const { return m_frameLoadState.provisionalURL(); } void setUnreachableURL(const String&); - const String& unreachableURL() const { return m_frameLoadState.m_unreachableURL; } + const String& unreachableURL() const { return m_frameLoadState.unreachableURL(); } const String& mimeType() const { return m_MIMEType; } + bool containsPluginDocument() const { return m_containsPluginDocument; } const String& title() const { return m_title; } @@ -92,26 +97,36 @@ public: bool canShowMIMEType(const String& mimeType) const; bool isDisplayingStandaloneImageDocument() const; + bool isDisplayingStandaloneMediaDocument() const; bool isDisplayingMarkupDocument() const; bool isDisplayingPDFDocument() const; - void getWebArchive(PassRefPtr<DataCallback>); - void getMainResourceData(PassRefPtr<DataCallback>); - void getResourceData(API::URL*, PassRefPtr<DataCallback>); + void getWebArchive(std::function<void (API::Data*, CallbackBase::Error)>); + void getMainResourceData(std::function<void (API::Data*, CallbackBase::Error)>); + void getResourceData(API::URL*, std::function<void (API::Data*, CallbackBase::Error)>); void didStartProvisionalLoad(const String& url); void didReceiveServerRedirectForProvisionalLoad(const String& url); void didFailProvisionalLoad(); - void didCommitLoad(const String& contentType, const WebCore::CertificateInfo&); + void didCommitLoad(const String& contentType, WebCertificateInfo&, bool containsPluginDocument); void didFinishLoad(); void didFailLoad(); void didSameDocumentNavigation(const String&); // eg. anchor navigation, session state change. void didChangeTitle(const String&); // Policy operations. - void receivedPolicyDecision(WebCore::PolicyAction, uint64_t listenerID); - WebFramePolicyListenerProxy* setUpPolicyListenerProxy(uint64_t listenerID); - WebFormSubmissionListenerProxy* setUpFormSubmissionListenerProxy(uint64_t listenerID); + void receivedPolicyDecision(WebCore::PolicyAction, uint64_t listenerID, API::Navigation*, const WebsitePolicies&); + WebFramePolicyListenerProxy& setUpPolicyListenerProxy(uint64_t listenerID); + WebFormSubmissionListenerProxy& setUpFormSubmissionListenerProxy(uint64_t listenerID); + +#if ENABLE(CONTENT_FILTERING) + void contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler contentFilterUnblockHandler) { m_contentFilterUnblockHandler = WTFMove(contentFilterUnblockHandler); } + bool didHandleContentFilterUnblockNavigation(const WebCore::ResourceRequest&); +#endif + +#if PLATFORM(GTK) + void collapseSelection(); +#endif private: WebFrameProxy(WebPageProxy* page, uint64_t frameID); @@ -123,11 +138,14 @@ private: String m_MIMEType; String m_title; bool m_isFrameSet; + bool m_containsPluginDocument { false }; RefPtr<WebCertificateInfo> m_certificateInfo; RefPtr<WebFrameListenerProxy> m_activeListener; uint64_t m_frameID; + +#if ENABLE(CONTENT_FILTERING) + WebCore::ContentFilterUnblockHandler m_contentFilterUnblockHandler; +#endif }; } // namespace WebKit - -#endif // WebFrameProxy_h diff --git a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp index 4817f3fb0..352d6a075 100644 --- a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp @@ -28,6 +28,7 @@ #if ENABLE(FULLSCREEN_API) +#include "APIFullscreenClient.h" #include "WebFullScreenManagerMessages.h" #include "WebFullScreenManagerProxyMessages.h" #include "WebPageProxy.h" @@ -56,21 +57,25 @@ WebFullScreenManagerProxy::~WebFullScreenManagerProxy() void WebFullScreenManagerProxy::willEnterFullScreen() { + m_page->fullscreenClient().willEnterFullscreen(m_page); m_page->process().send(Messages::WebFullScreenManager::WillEnterFullScreen(), m_page->pageID()); } void WebFullScreenManagerProxy::didEnterFullScreen() { + m_page->fullscreenClient().didEnterFullscreen(m_page); m_page->process().send(Messages::WebFullScreenManager::DidEnterFullScreen(), m_page->pageID()); } void WebFullScreenManagerProxy::willExitFullScreen() { + m_page->fullscreenClient().willExitFullscreen(m_page); m_page->process().send(Messages::WebFullScreenManager::WillExitFullScreen(), m_page->pageID()); } void WebFullScreenManagerProxy::didExitFullScreen() { + m_page->fullscreenClient().didExitFullscreen(m_page); m_page->process().send(Messages::WebFullScreenManager::DidExitFullScreen(), m_page->pageID()); } @@ -86,7 +91,7 @@ void WebFullScreenManagerProxy::requestExitFullScreen() void WebFullScreenManagerProxy::supportsFullScreen(bool withKeyboard, bool& supports) { - supports = !withKeyboard; + supports = true; } void WebFullScreenManagerProxy::saveScrollPosition() diff --git a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h index 74342eac4..107b5c0aa 100644 --- a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h +++ b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h @@ -81,8 +81,8 @@ private: void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame); void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame); - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; WebPageProxy* m_page; WebFullScreenManagerProxyClient* m_client; diff --git a/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.cpp b/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.cpp index a420b908f..7e18ac5da 100644 --- a/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "WebGeolocationManagerProxy.h" -#include "WebContext.h" #include "WebGeolocationManagerMessages.h" #include "WebGeolocationManagerProxyMessages.h" +#include "WebProcessPool.h" namespace WebKit { @@ -37,15 +37,15 @@ const char* WebGeolocationManagerProxy::supplementName() return "WebGeolocationManagerProxy"; } -PassRefPtr<WebGeolocationManagerProxy> WebGeolocationManagerProxy::create(WebContext* context) +PassRefPtr<WebGeolocationManagerProxy> WebGeolocationManagerProxy::create(WebProcessPool* processPool) { - return adoptRef(new WebGeolocationManagerProxy(context)); + return adoptRef(new WebGeolocationManagerProxy(processPool)); } -WebGeolocationManagerProxy::WebGeolocationManagerProxy(WebContext* context) - : WebContextSupplement(context) +WebGeolocationManagerProxy::WebGeolocationManagerProxy(WebProcessPool* processPool) + : WebContextSupplement(processPool) { - WebContextSupplement::context()->addMessageReceiver(Messages::WebGeolocationManagerProxy::messageReceiverName(), *this); + WebContextSupplement::processPool()->addMessageReceiver(Messages::WebGeolocationManagerProxy::messageReceiverName(), *this); } void WebGeolocationManagerProxy::initializeProvider(const WKGeolocationProviderBase* provider) @@ -55,10 +55,14 @@ void WebGeolocationManagerProxy::initializeProvider(const WKGeolocationProviderB // WebContextSupplement -void WebGeolocationManagerProxy::contextDestroyed() +void WebGeolocationManagerProxy::processPoolDestroyed() { + bool wasUpdating = isUpdating(); m_updateRequesters.clear(); - m_provider.stopUpdating(this); + + ASSERT(!isUpdating()); + if (wasUpdating) + m_provider.stopUpdating(this); } void WebGeolocationManagerProxy::processDidClose(WebProcessProxy* webProcessProxy) @@ -78,40 +82,40 @@ void WebGeolocationManagerProxy::derefWebContextSupplement() void WebGeolocationManagerProxy::providerDidChangePosition(WebGeolocationPosition* position) { - if (!context()) + if (!processPool()) return; - context()->sendToAllProcesses(Messages::WebGeolocationManager::DidChangePosition(position->data())); + processPool()->sendToAllProcesses(Messages::WebGeolocationManager::DidChangePosition(position->data())); } void WebGeolocationManagerProxy::providerDidFailToDeterminePosition(const String& errorMessage) { - if (!context()) + if (!processPool()) return; - context()->sendToAllProcesses(Messages::WebGeolocationManager::DidFailToDeterminePosition(errorMessage)); + processPool()->sendToAllProcesses(Messages::WebGeolocationManager::DidFailToDeterminePosition(errorMessage)); } #if PLATFORM(IOS) void WebGeolocationManagerProxy::resetPermissions() { - context()->sendToAllProcesses(Messages::WebGeolocationManager::ResetPermissions()); + processPool()->sendToAllProcesses(Messages::WebGeolocationManager::ResetPermissions()); } #endif -void WebGeolocationManagerProxy::startUpdating(IPC::Connection* connection) +void WebGeolocationManagerProxy::startUpdating(IPC::Connection& connection) { bool wasUpdating = isUpdating(); - m_updateRequesters.add(connection->client()); + m_updateRequesters.add(&connection.client()); if (!wasUpdating) { m_provider.setEnableHighAccuracy(this, isHighAccuracyEnabled()); m_provider.startUpdating(this); } } -void WebGeolocationManagerProxy::stopUpdating(IPC::Connection* connection) +void WebGeolocationManagerProxy::stopUpdating(IPC::Connection& connection) { - removeRequester(connection->client()); + removeRequester(&connection.client()); } void WebGeolocationManagerProxy::removeRequester(const IPC::Connection::Client* client) @@ -131,14 +135,14 @@ void WebGeolocationManagerProxy::removeRequester(const IPC::Connection::Client* } } -void WebGeolocationManagerProxy::setEnableHighAccuracy(IPC::Connection* connection, bool enabled) +void WebGeolocationManagerProxy::setEnableHighAccuracy(IPC::Connection& connection, bool enabled) { bool highAccuracyWasEnabled = isHighAccuracyEnabled(); if (enabled) - m_highAccuracyRequesters.add(connection->client()); + m_highAccuracyRequesters.add(&connection.client()); else - m_highAccuracyRequesters.remove(connection->client()); + m_highAccuracyRequesters.remove(&connection.client()); bool highAccuracyShouldBeEnabled = isHighAccuracyEnabled(); if (isUpdating() && highAccuracyWasEnabled != highAccuracyShouldBeEnabled) diff --git a/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.h b/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.h index 5668f9189..a4cb122cb 100644 --- a/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.h +++ b/Source/WebKit2/UIProcess/WebGeolocationManagerProxy.h @@ -36,14 +36,14 @@ namespace WebKit { -class WebContext; class WebGeolocationPosition; +class WebProcessPool; class WebGeolocationManagerProxy : public API::ObjectImpl<API::Object::Type::GeolocationManager>, public WebContextSupplement, private IPC::MessageReceiver { public: static const char* supplementName(); - static PassRefPtr<WebGeolocationManagerProxy> create(WebContext*); + static PassRefPtr<WebGeolocationManagerProxy> create(WebProcessPool*); void initializeProvider(const WKGeolocationProviderBase*); @@ -57,24 +57,24 @@ public: using API::Object::deref; private: - explicit WebGeolocationManagerProxy(WebContext*); + explicit WebGeolocationManagerProxy(WebProcessPool*); // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; + void processPoolDestroyed() override; + void processDidClose(WebProcessProxy*) override; + void refWebContextSupplement() override; + void derefWebContextSupplement() override; // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; bool isUpdating() const { return !m_updateRequesters.isEmpty(); } bool isHighAccuracyEnabled() const { return !m_highAccuracyRequesters.isEmpty(); } - void startUpdating(IPC::Connection*); - void stopUpdating(IPC::Connection*); + void startUpdating(IPC::Connection&); + void stopUpdating(IPC::Connection&); void removeRequester(const IPC::Connection::Client*); - void setEnableHighAccuracy(IPC::Connection*, bool); + void setEnableHighAccuracy(IPC::Connection&, bool); HashSet<const IPC::Connection::Client*> m_updateRequesters; HashSet<const IPC::Connection::Client*> m_highAccuracyRequesters; diff --git a/Source/WebKit2/UIProcess/WebGrammarDetail.cpp b/Source/WebKit2/UIProcess/WebGrammarDetail.cpp index 064fc3568..0fe1bfb31 100644 --- a/Source/WebKit2/UIProcess/WebGrammarDetail.cpp +++ b/Source/WebKit2/UIProcess/WebGrammarDetail.cpp @@ -55,13 +55,13 @@ WebGrammarDetail::WebGrammarDetail(int location, int length, API::Array* guesses m_grammarDetail.userDescription = userDescription; } -PassRefPtr<API::Array> WebGrammarDetail::guesses() const +Ref<API::Array> WebGrammarDetail::guesses() const { size_t numGuesses = m_grammarDetail.guesses.size(); Vector<RefPtr<API::Object> > wkGuesses(numGuesses); for (unsigned i = 0; i < numGuesses; ++i) wkGuesses[i] = API::String::create(m_grammarDetail.guesses[i]); - return API::Array::create(std::move(wkGuesses)); + return API::Array::create(WTFMove(wkGuesses)); } WebGrammarDetail::WebGrammarDetail(const WebCore::GrammarDetail& grammarDetail) diff --git a/Source/WebKit2/UIProcess/WebGrammarDetail.h b/Source/WebKit2/UIProcess/WebGrammarDetail.h index cbb81738f..7d1770570 100644 --- a/Source/WebKit2/UIProcess/WebGrammarDetail.h +++ b/Source/WebKit2/UIProcess/WebGrammarDetail.h @@ -41,7 +41,7 @@ public: int location() const { return m_grammarDetail.location; } int length() const { return m_grammarDetail.length; } - PassRefPtr<API::Array> guesses() const; + Ref<API::Array> guesses() const; const String& userDescription() const { return m_grammarDetail.userDescription; } const WebCore::GrammarDetail& grammarDetail() { return m_grammarDetail; } diff --git a/Source/WebKit2/UIProcess/WebHistoryClient.cpp b/Source/WebKit2/UIProcess/WebHistoryClient.cpp deleted file mode 100644 index d52297f09..000000000 --- a/Source/WebKit2/UIProcess/WebHistoryClient.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebHistoryClient.h" - -#include "APINavigationData.h" -#include "WKAPICast.h" -#include <wtf/RefPtr.h> - -using namespace WebCore; - -namespace WebKit { - -void WebHistoryClient::didNavigateWithNavigationData(WebContext* context, WebPageProxy* page, const WebNavigationDataStore& navigationDataStore, WebFrameProxy* frame) -{ - if (!m_client.didNavigateWithNavigationData) - return; - - RefPtr<API::NavigationData> navigationData = API::NavigationData::create(navigationDataStore); - m_client.didNavigateWithNavigationData(toAPI(context), toAPI(page), toAPI(navigationData.get()), toAPI(frame), m_client.base.clientInfo); -} - -void WebHistoryClient::didPerformClientRedirect(WebContext* context, WebPageProxy* page, const String& sourceURL, const String& destinationURL, WebFrameProxy* frame) -{ - if (!m_client.didPerformClientRedirect) - return; - - m_client.didPerformClientRedirect(toAPI(context), toAPI(page), toURLRef(sourceURL.impl()), toURLRef(destinationURL.impl()), toAPI(frame), m_client.base.clientInfo); -} - -void WebHistoryClient::didPerformServerRedirect(WebContext* context, WebPageProxy* page, const String& sourceURL, const String& destinationURL, WebFrameProxy* frame) -{ - if (!m_client.didPerformServerRedirect) - return; - - m_client.didPerformServerRedirect(toAPI(context), toAPI(page), toURLRef(sourceURL.impl()), toURLRef(destinationURL.impl()), toAPI(frame), m_client.base.clientInfo); -} - -void WebHistoryClient::didUpdateHistoryTitle(WebContext* context, WebPageProxy* page, const String& title, const String& url, WebFrameProxy* frame) -{ - if (!m_client.didUpdateHistoryTitle) - return; - - m_client.didUpdateHistoryTitle(toAPI(context), toAPI(page), toAPI(title.impl()), toURLRef(url.impl()), toAPI(frame), m_client.base.clientInfo); -} - -void WebHistoryClient::populateVisitedLinks(WebContext* context) -{ - if (!m_client.populateVisitedLinks) - return; - - m_client.populateVisitedLinks(toAPI(context), m_client.base.clientInfo); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebIconDatabase.cpp b/Source/WebKit2/UIProcess/WebIconDatabase.cpp index 8ed610a24..892c05fda 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabase.cpp +++ b/Source/WebKit2/UIProcess/WebIconDatabase.cpp @@ -26,42 +26,40 @@ #include "config.h" #include "WebIconDatabase.h" -#include "DataReference.h" #include "Logging.h" -#include "WebContext.h" #include "WebIconDatabaseMessages.h" #include "WebIconDatabaseProxyMessages.h" -#include "WebPreferences.h" +#include "WebProcessPool.h" #include <WebCore/FileSystem.h> #include <WebCore/IconDatabase.h> -#include <WebCore/IconDatabaseBase.h> -#include <wtf/text/CString.h> -#include <wtf/text/WTFString.h> +#include <WebCore/Image.h> +#include <WebCore/SharedBuffer.h> using namespace WebCore; namespace WebKit { -PassRefPtr<WebIconDatabase> WebIconDatabase::create(WebContext* context) +PassRefPtr<WebIconDatabase> WebIconDatabase::create(WebProcessPool* processPool) { - return adoptRef(new WebIconDatabase(context)); + return adoptRef(new WebIconDatabase(*processPool)); } WebIconDatabase::~WebIconDatabase() { } -WebIconDatabase::WebIconDatabase(WebContext* context) - : m_webContext(context) +WebIconDatabase::WebIconDatabase(WebProcessPool& processPool) + : m_processPool(&processPool) , m_urlImportCompleted(false) , m_databaseCleanupDisabled(false) + , m_shouldDerefWhenAppropriate(false) { - m_webContext->addMessageReceiver(Messages::WebIconDatabase::messageReceiverName(), *this); + m_processPool->addMessageReceiver(Messages::WebIconDatabase::messageReceiverName(), *this); } void WebIconDatabase::invalidate() { - setGlobalIconDatabase(0); + setGlobalIconDatabase(nullptr); } void WebIconDatabase::setDatabasePath(const String& path) @@ -71,20 +69,20 @@ void WebIconDatabase::setDatabasePath(const String& path) return; } - m_iconDatabaseImpl = IconDatabase::create(); + m_iconDatabaseImpl = std::make_unique<IconDatabase>(); m_iconDatabaseImpl->setClient(this); IconDatabase::delayDatabaseCleanup(); m_databaseCleanupDisabled = true; m_iconDatabaseImpl->setEnabled(true); - // FIXME: WebIconDatabases are per-WebContext but WebContext's don't have their own notion of the current private browsing setting. + // FIXME: WebIconDatabases are per-ProcessPool but ProcessPools's don't have their own notion of the current private browsing setting. // As we clean up private browsing throughout the stack we need to clean it up here. - m_iconDatabaseImpl->setPrivateBrowsingEnabled(WebPreferences::anyPageGroupsAreUsingPrivateBrowsing()); + m_iconDatabaseImpl->setPrivateBrowsingEnabled(WebPreferences::anyPagesAreUsingPrivateBrowsing()); if (!m_iconDatabaseImpl->open(directoryName(path), pathGetFileName(path))) { LOG_ERROR("Unable to open WebKit2 icon database on disk"); - m_iconDatabaseImpl.clear(); - setGlobalIconDatabase(0); + m_iconDatabaseImpl = nullptr; + setGlobalIconDatabase(nullptr); IconDatabase::allowDatabaseCleanup(); m_databaseCleanupDisabled = false; } @@ -103,7 +101,7 @@ void WebIconDatabase::enableDatabaseCleanup() ASSERT_NOT_REACHED(); return; } - + IconDatabase::allowDatabaseCleanup(); m_databaseCleanupDisabled = false; } @@ -132,9 +130,7 @@ void WebIconDatabase::setIconDataForIconURL(const IPC::DataReference& iconData, LOG(IconDatabase, "WK2 UIProcess setting icon data (%i bytes) for page URL %s", (int)iconData.size(), iconURL.ascii().data()); if (!m_iconDatabaseImpl) return; - - RefPtr<SharedBuffer> buffer = SharedBuffer::create(iconData.data(), iconData.size()); - m_iconDatabaseImpl->setIconDataForIconURL(buffer.release(), iconURL); + m_iconDatabaseImpl->setIconDataForIconURL(SharedBuffer::create(iconData.data(), iconData.size()).ptr(), iconURL); } void WebIconDatabase::synchronousIconDataForPageURL(const String&, IPC::DataReference& iconData) @@ -148,7 +144,6 @@ void WebIconDatabase::synchronousIconURLForPageURL(const String& pageURL, String iconURL = String(); return; } - iconURL = m_iconDatabaseImpl->synchronousIconURLForPageURL(pageURL); } @@ -166,12 +161,12 @@ void WebIconDatabase::getLoadDecisionForIconURL(const String& iconURL, uint64_t { LOG(IconDatabase, "WK2 UIProcess getting load decision for icon URL %s with callback ID %lli", iconURL.ascii().data(), static_cast<long long>(callbackID)); - if (!m_webContext) + if (!m_processPool) return; if (!m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || iconURL.isEmpty()) { // FIXME (Multi-WebProcess): <rdar://problem/12240223> We need to know which connection to send this message to. - m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(IconLoadNo), callbackID)); + m_processPool->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(IconLoadNo), callbackID)); return; } @@ -182,11 +177,11 @@ void WebIconDatabase::getLoadDecisionForIconURL(const String& iconURL, uint64_t ASSERT(!m_urlImportCompleted); m_pendingLoadDecisionURLMap.set(callbackID, iconURL); - return; + return; } // FIXME (Multi-WebProcess): <rdar://problem/12240223> We need to know which connection to send this message to. - m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision((int)decision, callbackID)); + m_processPool->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision((int)decision, callbackID)); } void WebIconDatabase::didReceiveIconForPageURL(const String& pageURL) @@ -194,20 +189,20 @@ void WebIconDatabase::didReceiveIconForPageURL(const String& pageURL) notifyIconDataReadyForPageURL(pageURL); } -Image* WebIconDatabase::imageForPageURL(const String& pageURL, const WebCore::IntSize& iconSize) +Image* WebIconDatabase::imageForPageURL(const String& pageURL, const IntSize& iconSize) { - if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty()) - return 0; + if (!m_processPool || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty()) + return nullptr; // The WebCore IconDatabase ignores the passed in size parameter. // If that changes we'll need to rethink how this API is exposed. return m_iconDatabaseImpl->synchronousIconForPageURL(pageURL, iconSize); } -WebCore::NativeImagePtr WebIconDatabase::nativeImageForPageURL(const String& pageURL, const WebCore::IntSize& iconSize) +NativeImagePtr WebIconDatabase::nativeImageForPageURL(const String& pageURL, const IntSize& iconSize) { - if (!m_webContext || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty()) - return 0; + if (!m_processPool || !m_iconDatabaseImpl || !m_iconDatabaseImpl->isOpen() || pageURL.isEmpty()) + return nullptr; return m_iconDatabaseImpl->synchronousNativeIconForPageURL(pageURL, iconSize); } @@ -224,7 +219,7 @@ bool WebIconDatabase::isUrlImportCompleted() void WebIconDatabase::removeAllIcons() { - m_iconDatabaseImpl->removeAllIcons(); + m_iconDatabaseImpl->removeAllIcons(); } void WebIconDatabase::checkIntegrityBeforeOpening() @@ -257,7 +252,7 @@ void WebIconDatabase::didImportIconDataForPageURL(const String& pageURL) void WebIconDatabase::didChangeIconForPageURL(const String& pageURL) { - m_iconDatabaseClient.didChangeIconForPageURL(this, API::URL::create(pageURL).get()); + m_iconDatabaseClient.didChangeIconForPageURL(this, API::URL::create(pageURL).ptr()); } void WebIconDatabase::didRemoveAllIcons() @@ -267,35 +262,50 @@ void WebIconDatabase::didRemoveAllIcons() void WebIconDatabase::didFinishURLImport() { - if (!m_webContext) + if (!m_processPool) return; - + ASSERT(!m_urlImportCompleted); LOG(IconDatabase, "WK2 UIProcess URL import complete, notifying all %i pending page URL load decisions", m_pendingLoadDecisionURLMap.size()); - - HashMap<uint64_t, String>::iterator i = m_pendingLoadDecisionURLMap.begin(); - HashMap<uint64_t, String>::iterator end = m_pendingLoadDecisionURLMap.end(); - for (; i != end; ++i) { - LOG(IconDatabase, "WK2 UIProcess performing delayed callback on callback ID %i for page url %s", (int)i->key, i->value.ascii().data()); - IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(i->value, 0); + for (auto& slot : m_pendingLoadDecisionURLMap) { + LOG(IconDatabase, "WK2 UIProcess performing delayed callback on callback ID %i for page url %s", (int)slot.key, slot.value.ascii().data()); + IconLoadDecision decision = m_iconDatabaseImpl->synchronousLoadDecisionForIconURL(slot.value, nullptr); - // Decisions should never be unknown after the inital import is complete + // Decisions should never be unknown after the inital import is complete. ASSERT(decision != IconLoadUnknown); // FIXME (Multi-WebProcess): <rdar://problem/12240223> We need to know which connection to send this message to. - m_webContext->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(decision), i->key)); + m_processPool->sendToAllProcesses(Messages::WebIconDatabaseProxy::ReceivedIconLoadDecision(static_cast<int>(decision), slot.key)); } - + m_pendingLoadDecisionURLMap.clear(); - + m_urlImportCompleted = true; } +void WebIconDatabase::didClose() +{ + if (!m_shouldDerefWhenAppropriate) + return; + + deref(); +} + +void WebIconDatabase::derefWhenAppropriate() +{ + if (m_iconDatabaseImpl && m_iconDatabaseImpl->isOpen()) { + m_shouldDerefWhenAppropriate = true; + return; + } + + deref(); +} + void WebIconDatabase::notifyIconDataReadyForPageURL(const String& pageURL) { - m_iconDatabaseClient.iconDataReadyForPageURL(this, API::URL::create(pageURL).get()); + m_iconDatabaseClient.iconDataReadyForPageURL(this, API::URL::create(pageURL).ptr()); didChangeIconForPageURL(pageURL); } @@ -305,4 +315,23 @@ void WebIconDatabase::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) m_iconDatabaseImpl->setPrivateBrowsingEnabled(privateBrowsingEnabled); } +PassRefPtr<API::Data> WebIconDatabase::iconDataForPageURL(const String& pageURL) +{ + auto* image = imageForPageURL(pageURL); + if (!image) + return nullptr; + + SharedBuffer* sharedBuffer = image->data(); + if (!sharedBuffer) + return nullptr; + + // Balanced by deref() below. + sharedBuffer->ref(); + return API::Data::createWithoutCopying(reinterpret_cast<const unsigned char*>(sharedBuffer->data()), sharedBuffer->size(), + [](unsigned char*, const void* untypedSharedBuffer) { + // Balanced by ref() above. + static_cast<SharedBuffer*>(const_cast<void*>(untypedSharedBuffer))->deref(); + }, sharedBuffer); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebIconDatabase.h b/Source/WebKit2/UIProcess/WebIconDatabase.h index 816b20d4b..8b70fe824 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabase.h +++ b/Source/WebKit2/UIProcess/WebIconDatabase.h @@ -27,21 +27,14 @@ #define WebIconDatabase_h #include "APIObject.h" - #include "Connection.h" #include "WebIconDatabaseClient.h" #include <WebCore/IconDatabaseClient.h> -#include <WebCore/ImageSource.h> #include <WebCore/IntSize.h> -#include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> -#include <wtf/text/StringHash.h> - -namespace IPC { -class ArgumentDecoder; -class DataReference; +#include <WebCore/NativeImage.h> + +namespace API { +class Data; } namespace WebCore { @@ -51,15 +44,15 @@ class Image; namespace WebKit { -class WebContext; +class WebProcessPool; -class WebIconDatabase : public API::ObjectImpl<API::Object::Type::IconDatabase>, public WebCore::IconDatabaseClient, private IPC::MessageReceiver { +class WebIconDatabase : public API::ObjectImpl<API::Object::Type::IconDatabase>, private WebCore::IconDatabaseClient, private IPC::MessageReceiver { public: - static PassRefPtr<WebIconDatabase> create(WebContext*); + static PassRefPtr<WebIconDatabase> create(WebProcessPool*); virtual ~WebIconDatabase(); void invalidate(); - void clearContext() { m_webContext = 0; } + void clearProcessPool() { m_processPool = nullptr; } void setDatabasePath(const String&); void enableDatabaseCleanup(); @@ -67,17 +60,19 @@ public: void releaseIconForPageURL(const String&); void setIconURLForPageURL(const String&, const String&); void setIconDataForIconURL(const IPC::DataReference&, const String&); - + void synchronousIconDataForPageURL(const String&, IPC::DataReference&); void synchronousIconURLForPageURL(const String&, String&); void synchronousIconDataKnownForIconURL(const String&, bool&) const; void synchronousLoadDecisionForIconURL(const String&, int&) const; - + void getLoadDecisionForIconURL(const String&, uint64_t callbackID); void didReceiveIconForPageURL(const String&); WebCore::Image* imageForPageURL(const String&, const WebCore::IntSize& iconSize = WebCore::IntSize(32, 32)); WebCore::NativeImagePtr nativeImageForPageURL(const String&, const WebCore::IntSize& iconSize = WebCore::IntSize(32, 32)); + PassRefPtr<API::Data> iconDataForPageURL(const String& pageURL); + bool isOpen(); bool isUrlImportCompleted(); @@ -88,28 +83,35 @@ public: void initializeIconDatabaseClient(const WKIconDatabaseClientBase*); void setPrivateBrowsingEnabled(bool); - + + // Called when the WebProcessPool is through with this WebIconDatabase but the + // WebCore::IconDatabase possibly isn't done shutting down. + // In that case this WebIconDatabase will deref() itself when the time is right. + void derefWhenAppropriate(); + private: - WebIconDatabase(WebContext*); + explicit WebIconDatabase(WebProcessPool&); // WebCore::IconDatabaseClient - virtual void didImportIconURLForPageURL(const String&); - virtual void didImportIconDataForPageURL(const String&); - virtual void didChangeIconForPageURL(const String&); - virtual void didRemoveAllIcons(); - virtual void didFinishURLImport(); + void didImportIconURLForPageURL(const String&) override; + void didImportIconDataForPageURL(const String&) override; + void didChangeIconForPageURL(const String&) override; + void didRemoveAllIcons() override; + void didFinishURLImport() override; + void didClose() override; // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; void notifyIconDataReadyForPageURL(const String&); - WebContext* m_webContext; - - OwnPtr<WebCore::IconDatabase> m_iconDatabaseImpl; + WebProcessPool* m_processPool; + + std::unique_ptr<WebCore::IconDatabase> m_iconDatabaseImpl; bool m_urlImportCompleted; bool m_databaseCleanupDisabled; + bool m_shouldDerefWhenAppropriate; HashMap<uint64_t, String> m_pendingLoadDecisionURLMap; WebIconDatabaseClient m_iconDatabaseClient; diff --git a/Source/WebKit2/UIProcess/WebIconDatabase.messages.in b/Source/WebKit2/UIProcess/WebIconDatabase.messages.in index 37052b5d8..f5b96fd1f 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabase.messages.in +++ b/Source/WebKit2/UIProcess/WebIconDatabase.messages.in @@ -21,8 +21,6 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> WebIconDatabase { - RetainIconForPageURL(String pageURL) - ReleaseIconForPageURL(String pageURL) SetIconURLForPageURL(String iconURL, String pageURL) SetIconDataForIconURL(IPC::DataReference iconData, String iconURL) diff --git a/Source/WebKit2/UIProcess/WebIconDatabaseClient.cpp b/Source/WebKit2/UIProcess/WebIconDatabaseClient.cpp index 0cc148e89..9555bc233 100644 --- a/Source/WebKit2/UIProcess/WebIconDatabaseClient.cpp +++ b/Source/WebKit2/UIProcess/WebIconDatabaseClient.cpp @@ -28,6 +28,7 @@ #include "WKAPICast.h" #include "WKSharedAPICast.h" +#include "WebIconDatabase.h" namespace WebKit { diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.cpp b/Source/WebKit2/UIProcess/WebInspectorProxy.cpp index 2d2297f8c..38c8039f7 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.cpp +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2014, 2016 Apple Inc. All rights reserved. * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,19 +27,23 @@ #include "config.h" #include "WebInspectorProxy.h" -#if ENABLE(INSPECTOR) - -#include "APIURLRequest.h" +#include "APINavigationAction.h" +#include "APIProcessPoolConfiguration.h" +#include "WKArray.h" +#include "WKContextMenuItem.h" +#include "WKMutableArray.h" +#include "WebAutomationSession.h" #include "WebFramePolicyListenerProxy.h" #include "WebFrameProxy.h" #include "WebInspectorMessages.h" #include "WebInspectorProxyMessages.h" -#include "WebPageCreationParameters.h" +#include "WebInspectorUIMessages.h" #include "WebPageGroup.h" #include "WebPageProxy.h" #include "WebPreferences.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" -#include <WebCore/SchemeRegistry.h> +#include <WebCore/NotImplemented.h> #include <wtf/NeverDestroyed.h> #if ENABLE(INSPECTOR_SERVER) @@ -50,129 +54,55 @@ using namespace WebCore; namespace WebKit { -const unsigned WebInspectorProxy::minimumWindowWidth = 750; +const unsigned WebInspectorProxy::minimumWindowWidth = 500; const unsigned WebInspectorProxy::minimumWindowHeight = 400; const unsigned WebInspectorProxy::initialWindowWidth = 1000; const unsigned WebInspectorProxy::initialWindowHeight = 650; -const unsigned WebInspectorProxy::minimumAttachedWidth = 750; -const unsigned WebInspectorProxy::minimumAttachedHeight = 250; - -class WebInspectorPageGroups { -public: - static WebInspectorPageGroups& shared() - { - static NeverDestroyed<WebInspectorPageGroups> instance; - return instance; - } - - unsigned inspectorLevel(WebPageGroup& inspectedPageGroup) - { - return isInspectorPageGroup(inspectedPageGroup) ? inspectorPageGroupLevel(inspectedPageGroup) + 1 : 1; - } - - bool isInspectorPageGroup(WebPageGroup& group) - { - return m_pageGroupLevel.contains(&group); - } - - unsigned inspectorPageGroupLevel(WebPageGroup& group) - { - ASSERT(isInspectorPageGroup(group)); - return m_pageGroupLevel.get(&group); - } - - WebPageGroup* inspectorPageGroupForLevel(unsigned level) - { - // The level is the key of the HashMap, so it cannot be 0. - ASSERT(level); - - auto iterator = m_pageGroupByLevel.find(level); - if (iterator != m_pageGroupByLevel.end()) - return iterator->value.get(); - - RefPtr<WebPageGroup> group = createInspectorPageGroup(level); - m_pageGroupByLevel.set(level, group.get()); - m_pageGroupLevel.set(group.get(), level); - return group.get(); - } - -private: - static PassRefPtr<WebPageGroup> createInspectorPageGroup(unsigned level) - { - RefPtr<WebPageGroup> pageGroup = WebPageGroup::create(String::format("__WebInspectorPageGroupLevel%u__", level), false, false); - -#ifndef NDEBUG - // Allow developers to inspect the Web Inspector in debug builds. - pageGroup->preferences()->setDeveloperExtrasEnabled(true); - pageGroup->preferences()->setLogsPageMessagesToSystemConsoleEnabled(true); -#endif - - pageGroup->preferences()->setApplicationChromeModeEnabled(true); - - return pageGroup.release(); - } - - typedef HashMap<unsigned, RefPtr<WebPageGroup> > PageGroupByLevelMap; - typedef HashMap<WebPageGroup*, unsigned> PageGroupLevelMap; - - PageGroupByLevelMap m_pageGroupByLevel; - PageGroupLevelMap m_pageGroupLevel; -}; - -WebInspectorProxy::WebInspectorProxy(WebPageProxy* page) - : m_page(page) - , m_isVisible(false) - , m_isAttached(false) - , m_isDebuggingJavaScript(false) - , m_isProfilingJavaScript(false) - , m_isProfilingPage(false) - , m_showMessageSent(false) - , m_createdInspectorPage(false) - , m_ignoreFirstBringToFront(false) - , m_attachmentSide(AttachmentSideBottom) -#if PLATFORM(GTK) || PLATFORM(EFL) - , m_inspectorView(0) - , m_inspectorWindow(0) -#endif -#if ENABLE(INSPECTOR_SERVER) - , m_remoteInspectionPageId(0) +WebInspectorProxy::WebInspectorProxy(WebPageProxy* inspectedPage) + : m_inspectedPage(inspectedPage) +#if PLATFORM(MAC) && WK_API_ENABLED + , m_closeTimer(RunLoop::main(), this, &WebInspectorProxy::closeTimerFired) #endif { - m_level = WebInspectorPageGroups::shared().inspectorLevel(m_page->pageGroup()); - m_page->process().addMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_page->pageID(), *this); + m_inspectedPage->process().addMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID(), *this); } WebInspectorProxy::~WebInspectorProxy() { } -WebPageGroup* WebInspectorProxy::inspectorPageGroup() const +unsigned WebInspectorProxy::inspectionLevel() const +{ + return inspectorLevelForPage(inspectedPage()); +} + +WebPreferences& WebInspectorProxy::inspectorPagePreferences() const { - return WebInspectorPageGroups::shared().inspectorPageGroupForLevel(m_level); + ASSERT(m_inspectorPage); + return m_inspectorPage->pageGroup().preferences(); } void WebInspectorProxy::invalidate() { #if ENABLE(INSPECTOR_SERVER) if (m_remoteInspectionPageId) - WebInspectorServer::shared().unregisterPage(m_remoteInspectionPageId); + WebInspectorServer::singleton().unregisterPage(m_remoteInspectionPageId); #endif - m_page->process().removeMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_page->pageID()); - - m_page->close(); + m_inspectedPage->process().removeMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID()); didClose(); + platformInvalidate(); - m_page = 0; + m_inspectedPage = nullptr; } // Public APIs bool WebInspectorProxy::isFront() { - if (!m_page) + if (!m_inspectedPage) return false; return platformIsFront(); @@ -180,7 +110,7 @@ bool WebInspectorProxy::isFront() void WebInspectorProxy::connect() { - if (!m_page) + if (!m_inspectedPage) return; if (m_showMessageSent) @@ -189,12 +119,14 @@ void WebInspectorProxy::connect() m_showMessageSent = true; m_ignoreFirstBringToFront = true; - m_page->process().send(Messages::WebInspector::Show(), m_page->pageID()); + eagerlyCreateInspectorPage(); + + m_inspectedPage->process().send(Messages::WebInspector::Show(), m_inspectedPage->pageID()); } void WebInspectorProxy::show() { - if (!m_page) + if (!m_inspectedPage) return; if (isConnected()) { @@ -210,7 +142,7 @@ void WebInspectorProxy::show() void WebInspectorProxy::hide() { - if (!m_page) + if (!m_inspectedPage) return; m_isVisible = false; @@ -220,68 +152,102 @@ void WebInspectorProxy::hide() void WebInspectorProxy::close() { - if (!m_page) + if (!m_inspectedPage) return; - m_page->process().send(Messages::WebInspector::Close(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::Close(), m_inspectedPage->pageID()); didClose(); } +void WebInspectorProxy::closeForCrash() +{ + close(); + + platformDidCloseForCrash(); +} + void WebInspectorProxy::showConsole() { - if (!m_page) + if (!m_inspectedPage) return; - m_page->process().send(Messages::WebInspector::ShowConsole(), m_page->pageID()); + eagerlyCreateInspectorPage(); + + m_inspectedPage->process().send(Messages::WebInspector::ShowConsole(), m_inspectedPage->pageID()); } void WebInspectorProxy::showResources() { - if (!m_page) + if (!m_inspectedPage) return; - m_page->process().send(Messages::WebInspector::ShowResources(), m_page->pageID()); + eagerlyCreateInspectorPage(); + + m_inspectedPage->process().send(Messages::WebInspector::ShowResources(), m_inspectedPage->pageID()); +} + +void WebInspectorProxy::showTimelines() +{ + if (!m_inspectedPage) + return; + + eagerlyCreateInspectorPage(); + + m_inspectedPage->process().send(Messages::WebInspector::ShowTimelines(), m_inspectedPage->pageID()); } void WebInspectorProxy::showMainResourceForFrame(WebFrameProxy* frame) { - if (!m_page) + if (!m_inspectedPage) return; - m_page->process().send(Messages::WebInspector::ShowMainResourceForFrame(frame->frameID()), m_page->pageID()); + eagerlyCreateInspectorPage(); + + m_inspectedPage->process().send(Messages::WebInspector::ShowMainResourceForFrame(frame->frameID()), m_inspectedPage->pageID()); } void WebInspectorProxy::attachBottom() { - attach(AttachmentSideBottom); + attach(AttachmentSide::Bottom); } void WebInspectorProxy::attachRight() { - attach(AttachmentSideRight); + attach(AttachmentSide::Right); +} + +void WebInspectorProxy::attachLeft() +{ + attach(AttachmentSide::Left); } void WebInspectorProxy::attach(AttachmentSide side) { - if (!m_page || !canAttach()) + if (!m_inspectedPage || !canAttach()) return; m_isAttached = true; m_attachmentSide = side; - inspectorPageGroup()->preferences()->setInspectorAttachmentSide(side); + inspectorPagePreferences().setInspectorAttachmentSide(static_cast<uint32_t>(side)); if (m_isVisible) - inspectorPageGroup()->preferences()->setInspectorStartsAttached(true); + inspectorPagePreferences().setInspectorStartsAttached(true); + + m_inspectedPage->process().send(Messages::WebInspector::SetAttached(true), m_inspectedPage->pageID()); switch (m_attachmentSide) { - case AttachmentSideBottom: - m_page->process().send(Messages::WebInspector::AttachedBottom(), m_page->pageID()); + case AttachmentSide::Bottom: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedBottom(), m_inspectorPage->pageID()); + break; + + case AttachmentSide::Right: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedRight(), m_inspectorPage->pageID()); break; - case AttachmentSideRight: - m_page->process().send(Messages::WebInspector::AttachedRight(), m_page->pageID()); + case AttachmentSide::Left: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedLeft(), m_inspectorPage->pageID()); break; } @@ -290,103 +256,105 @@ void WebInspectorProxy::attach(AttachmentSide side) void WebInspectorProxy::detach() { - if (!m_page) + if (!m_inspectedPage) return; m_isAttached = false; if (m_isVisible) - inspectorPageGroup()->preferences()->setInspectorStartsAttached(false); + inspectorPagePreferences().setInspectorStartsAttached(false); - m_page->process().send(Messages::WebInspector::Detached(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::SetAttached(false), m_inspectedPage->pageID()); + m_inspectorPage->process().send(Messages::WebInspectorUI::Detached(), m_inspectorPage->pageID()); platformDetach(); } void WebInspectorProxy::setAttachedWindowHeight(unsigned height) { - inspectorPageGroup()->preferences()->setInspectorAttachedHeight(height); + inspectorPagePreferences().setInspectorAttachedHeight(height); platformSetAttachedWindowHeight(height); } void WebInspectorProxy::setAttachedWindowWidth(unsigned width) { - inspectorPageGroup()->preferences()->setInspectorAttachedWidth(width); + inspectorPagePreferences().setInspectorAttachedWidth(width); platformSetAttachedWindowWidth(width); } -void WebInspectorProxy::toggleJavaScriptDebugging() -{ - if (!m_page) - return; - - if (m_isDebuggingJavaScript) - m_page->process().send(Messages::WebInspector::StopJavaScriptDebugging(), m_page->pageID()); - else - m_page->process().send(Messages::WebInspector::StartJavaScriptDebugging(), m_page->pageID()); - - // FIXME: have the WebProcess notify us on state changes. - m_isDebuggingJavaScript = !m_isDebuggingJavaScript; -} - -void WebInspectorProxy::toggleJavaScriptProfiling() +void WebInspectorProxy::startWindowDrag() { - if (!m_page) - return; - - if (m_isProfilingJavaScript) - m_page->process().send(Messages::WebInspector::StopJavaScriptProfiling(), m_page->pageID()); - else - m_page->process().send(Messages::WebInspector::StartJavaScriptProfiling(), m_page->pageID()); - - // FIXME: have the WebProcess notify us on state changes. - m_isProfilingJavaScript = !m_isProfilingJavaScript; + platformStartWindowDrag(); } void WebInspectorProxy::togglePageProfiling() { - if (!m_page) + if (!m_inspectedPage) return; if (m_isProfilingPage) - m_page->process().send(Messages::WebInspector::StopPageProfiling(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::StopPageProfiling(), m_inspectedPage->pageID()); else - m_page->process().send(Messages::WebInspector::StartPageProfiling(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::StartPageProfiling(), m_inspectedPage->pageID()); // FIXME: have the WebProcess notify us on state changes. m_isProfilingPage = !m_isProfilingPage; } -bool WebInspectorProxy::isInspectorPage(WebPageProxy& page) +void WebInspectorProxy::toggleElementSelection() { - return WebInspectorPageGroups::shared().isInspectorPageGroup(page.pageGroup()); + if (!m_inspectedPage) + return; + + if (m_elementSelectionActive) { + m_ignoreElementSelectionChange = true; + m_inspectedPage->process().send(Messages::WebInspector::StopElementSelection(), m_inspectedPage->pageID()); + } else { + connect(); + m_inspectedPage->process().send(Messages::WebInspector::StartElementSelection(), m_inspectedPage->pageID()); + } } -static bool isMainInspectorPage(const WebInspectorProxy* webInspectorProxy, WKURLRequestRef requestRef) +bool WebInspectorProxy::isMainOrTestInspectorPage(const URL& url) { - // Use URL so we can compare just the paths. - URL inspectorURL(URL(), webInspectorProxy->inspectorPageURL()); - URL requestURL(URL(), toImpl(requestRef)->resourceRequest().url()); + // Use URL so we can compare the paths and protocols. + URL mainPageURL(URL(), WebInspectorProxy::inspectorPageURL()); + if (url.protocol() == mainPageURL.protocol() && decodeURLEscapeSequences(url.path()) == decodeURLEscapeSequences(mainPageURL.path())) + return true; + + // We might not have a Test URL in Production builds. + String testPageURLString = WebInspectorProxy::inspectorTestPageURL(); + if (testPageURLString.isNull()) + return false; - ASSERT(WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(inspectorURL.protocol())); + URL testPageURL(URL(), testPageURLString); + return url.protocol() == testPageURL.protocol() && decodeURLEscapeSequences(url.path()) == decodeURLEscapeSequences(testPageURL.path()); +} - return WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(requestURL.protocol()) && decodeURLEscapeSequences(requestURL.path()) == decodeURLEscapeSequences(inspectorURL.path()); +static void webProcessDidCrash(WKPageRef, const void* clientInfo) +{ + WebInspectorProxy* webInspectorProxy = static_cast<WebInspectorProxy*>(const_cast<void*>(clientInfo)); + ASSERT(webInspectorProxy); + webInspectorProxy->closeForCrash(); } -static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef frameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKFrameRef, WKURLRequestRef requestRef, WKFramePolicyListenerRef listenerRef, WKTypeRef, const void* clientInfo) +static void decidePolicyForNavigationAction(WKPageRef pageRef, WKNavigationActionRef navigationActionRef, WKFramePolicyListenerRef listenerRef, WKTypeRef, const void* clientInfo) { // Allow non-main frames to navigate anywhere. - if (!toImpl(frameRef)->isMainFrame()) { - toImpl(listenerRef)->use(); + API::FrameInfo* sourceFrame = toImpl(navigationActionRef)->sourceFrame(); + if (sourceFrame && !sourceFrame->isMainFrame()) { + toImpl(listenerRef)->use({ }); return; } const WebInspectorProxy* webInspectorProxy = static_cast<const WebInspectorProxy*>(clientInfo); ASSERT(webInspectorProxy); + WebCore::ResourceRequest request = toImpl(navigationActionRef)->request(); + // Allow loading of the main inspector file. - if (isMainInspectorPage(webInspectorProxy, requestRef)) { - toImpl(listenerRef)->use(); + if (WebInspectorProxy::isMainOrTestInspectorPage(request.url())) { + toImpl(listenerRef)->use({ }); return; } @@ -394,115 +362,208 @@ static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef frameRef, WKFr toImpl(listenerRef)->ignore(); // And instead load it in the inspected page. - webInspectorProxy->page()->loadRequest(toImpl(requestRef)->resourceRequest()); + webInspectorProxy->inspectedPage()->loadRequest(request); +} + +static void getContextMenuFromProposedMenu(WKPageRef pageRef, WKArrayRef proposedMenuRef, WKArrayRef* newMenuRef, WKHitTestResultRef, WKTypeRef, const void*) +{ + WKMutableArrayRef menuItems = WKMutableArrayCreate(); + + size_t count = WKArrayGetSize(proposedMenuRef); + for (size_t i = 0; i < count; ++i) { + WKContextMenuItemRef contextMenuItem = static_cast<WKContextMenuItemRef>(WKArrayGetItemAtIndex(proposedMenuRef, i)); + switch (WKContextMenuItemGetTag(contextMenuItem)) { + case kWKContextMenuItemTagOpenLinkInNewWindow: + case kWKContextMenuItemTagOpenImageInNewWindow: + case kWKContextMenuItemTagOpenFrameInNewWindow: + case kWKContextMenuItemTagOpenMediaInNewWindow: + case kWKContextMenuItemTagDownloadLinkToDisk: + case kWKContextMenuItemTagDownloadImageToDisk: + break; + default: + WKArrayAppendItem(menuItems, contextMenuItem); + break; + } + } + + *newMenuRef = menuItems; } #if ENABLE(INSPECTOR_SERVER) void WebInspectorProxy::enableRemoteInspection() { if (!m_remoteInspectionPageId) - m_remoteInspectionPageId = WebInspectorServer::shared().registerPage(this); + m_remoteInspectionPageId = WebInspectorServer::singleton().registerPage(this); } void WebInspectorProxy::remoteFrontendConnected() { - m_page->process().send(Messages::WebInspector::RemoteFrontendConnected(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::RemoteFrontendConnected(), m_inspectedPage->pageID()); } void WebInspectorProxy::remoteFrontendDisconnected() { - m_page->process().send(Messages::WebInspector::RemoteFrontendDisconnected(), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::RemoteFrontendDisconnected(), m_inspectedPage->pageID()); } void WebInspectorProxy::dispatchMessageFromRemoteFrontend(const String& message) { - m_page->process().send(Messages::WebInspector::DispatchMessageFromRemoteFrontend(message), m_page->pageID()); + m_inspectedPage->process().send(Messages::WebInspector::SendMessageToBackend(message), m_inspectedPage->pageID()); } #endif -// Called by WebInspectorProxy messages -void WebInspectorProxy::createInspectorPage(uint64_t& inspectorPageID, WebPageCreationParameters& inspectorPageParameters) +void WebInspectorProxy::eagerlyCreateInspectorPage() { - inspectorPageID = 0; - - if (!m_page) + if (m_inspectorPage) return; - m_isAttached = shouldOpenAttached(); - m_attachmentSide = static_cast<AttachmentSide>(inspectorPageGroup()->preferences()->inspectorAttachmentSide()); - - WebPageProxy* inspectorPage = platformCreateInspectorPage(); - ASSERT(inspectorPage); - if (!inspectorPage) + m_inspectorPage = platformCreateInspectorPage(); + ASSERT(m_inspectorPage); + if (!m_inspectorPage) return; - inspectorPageID = inspectorPage->pageID(); - inspectorPageParameters = inspectorPage->creationParameters(); + trackInspectorPage(m_inspectorPage); - WKPagePolicyClientV1 policyClient = { - { 1, this }, - 0, /* decidePolicyForNavigationAction_deprecatedForUseWithV0 */ - 0, /* decidePolicyForNewWindowAction */ - 0, /* decidePolicyForResponse_deprecatedForUseWithV0 */ - 0, /* unableToImplementPolicy */ + WKPageNavigationClientV0 navigationClient = { + { 0, this }, decidePolicyForNavigationAction, - 0, /* decidePolicyForResponse */ + nullptr, // decidePolicyForNavigationResponse + nullptr, // decidePolicyForPluginLoad + nullptr, // didStartProvisionalNavigation + nullptr, // didReceiveServerRedirectForProvisionalNavigation + nullptr, // didFailProvisionalNavigation + nullptr, // didCommitNavigation + nullptr, // didFinishNavigation + nullptr, // didFailNavigation + nullptr, // didFailProvisionalLoadInSubframe + nullptr, // didFinishDocumentLoad + nullptr, // didSameDocumentNavigation + nullptr, // renderingProgressDidChange + nullptr, // canAuthenticateAgainstProtectionSpace + nullptr, // didReceiveAuthenticationChallenge + webProcessDidCrash, + nullptr, // copyWebCryptoMasterKey + + nullptr, // didBeginNavigationGesture + nullptr, // willEndNavigationGesture + nullptr, // didEndNavigationGesture + nullptr, // didRemoveNavigationGestureSnapshot }; - WKPageSetPagePolicyClient(toAPI(inspectorPage), &policyClient.base); + WKPageContextMenuClientV3 contextMenuClient = { + { 3, this }, + nullptr, // getContextMenuFromProposedMenu_deprecatedForUseWithV0 + nullptr, // customContextMenuItemSelected + nullptr, // contextMenuDismissed + getContextMenuFromProposedMenu, + nullptr, // showContextMenu + nullptr, // hideContextMenu + }; - String url = inspectorPageURL(); + WKPageSetPageNavigationClient(toAPI(m_inspectorPage), &navigationClient.base); + WKPageSetPageContextMenuClient(toAPI(m_inspectorPage), &contextMenuClient.base); - url.append("?dockSide="); + m_inspectorPage->process().addMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID(), *this); + m_inspectorPage->process().assumeReadAccessToBaseURL(WebInspectorProxy::inspectorBaseURL()); +} - if (m_isAttached) { - switch (m_attachmentSide) { - case AttachmentSideBottom: - url.append("bottom"); - m_page->process().send(Messages::WebInspector::AttachedBottom(), m_page->pageID()); - break; - case AttachmentSideRight: - url.append("right"); - m_page->process().send(Messages::WebInspector::AttachedRight(), m_page->pageID()); - break; - } - } else - url.append("undocked"); +// Called by WebInspectorProxy messages +void WebInspectorProxy::createInspectorPage(IPC::Attachment connectionIdentifier, bool canAttach, bool underTest) +{ + if (!m_inspectedPage) + return; - m_page->process().assumeReadAccessToBaseURL(inspectorBaseURL()); + m_underTest = underTest; + eagerlyCreateInspectorPage(); - inspectorPage->loadRequest(URL(URL(), url)); + ASSERT(m_inspectorPage); + if (!m_inspectorPage) + return; - m_createdInspectorPage = true; + m_connectionIdentifier = WTFMove(connectionIdentifier); + + m_inspectorPage->process().send(Messages::WebInspectorUI::EstablishConnection(m_connectionIdentifier, m_inspectedPage->pageID(), m_underTest, inspectionLevel()), m_inspectorPage->pageID()); + + if (!m_underTest) { + m_canAttach = platformCanAttach(canAttach); + m_isAttached = shouldOpenAttached(); + m_attachmentSide = static_cast<AttachmentSide>(inspectorPagePreferences().inspectorAttachmentSide()); + + m_inspectedPage->process().send(Messages::WebInspector::SetAttached(m_isAttached), m_inspectedPage->pageID()); + + if (m_isAttached) { + switch (m_attachmentSide) { + case AttachmentSide::Bottom: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedBottom(), m_inspectorPage->pageID()); + break; + + case AttachmentSide::Right: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedRight(), m_inspectorPage->pageID()); + break; + + case AttachmentSide::Left: + m_inspectorPage->process().send(Messages::WebInspectorUI::AttachedLeft(), m_inspectorPage->pageID()); + break; + } + } else + m_inspectorPage->process().send(Messages::WebInspectorUI::Detached(), m_inspectorPage->pageID()); + + m_inspectorPage->process().send(Messages::WebInspectorUI::SetDockingUnavailable(!m_canAttach), m_inspectorPage->pageID()); + } + + m_inspectorPage->loadRequest(URL(URL(), m_underTest ? WebInspectorProxy::inspectorTestPageURL() : WebInspectorProxy::inspectorPageURL())); } void WebInspectorProxy::open() { + if (m_underTest) + return; + + if (!m_inspectorPage) + return; + m_isVisible = true; + m_inspectorPage->process().send(Messages::WebInspectorUI::SetIsVisible(m_isVisible), m_inspectorPage->pageID()); platformOpen(); } void WebInspectorProxy::didClose() { - if (!m_createdInspectorPage) + if (!m_inspectorPage) return; m_isVisible = false; - m_isDebuggingJavaScript = false; - m_isProfilingJavaScript = false; m_isProfilingPage = false; - m_createdInspectorPage = false; m_showMessageSent = false; m_ignoreFirstBringToFront = false; + untrackInspectorPage(m_inspectorPage); + + m_inspectorPage->process().send(Messages::WebInspectorUI::SetIsVisible(m_isVisible), m_inspectorPage->pageID()); + m_inspectorPage->process().removeMessageReceiver(Messages::WebInspectorProxy::messageReceiverName(), m_inspectedPage->pageID()); + if (m_isAttached) platformDetach(); + + // Null out m_inspectorPage after platformDetach(), so the views can be cleaned up correctly. + m_inspectorPage = nullptr; + m_isAttached = false; + m_canAttach = false; + m_underTest = false; + + m_connectionIdentifier = IPC::Attachment(); platformDidClose(); } +void WebInspectorProxy::frontendLoaded() +{ + if (auto* automationSession = m_inspectedPage->process().processPool().automationSession()) + automationSession->inspectorFrontendLoaded(*m_inspectedPage); +} + void WebInspectorProxy::bringToFront() { // WebCore::InspectorFrontendClientLocal tells us to do this on load. We want to @@ -521,7 +582,17 @@ void WebInspectorProxy::bringToFront() void WebInspectorProxy::attachAvailabilityChanged(bool available) { - platformAttachAvailabilityChanged(available); + bool previousCanAttach = m_canAttach; + + m_canAttach = platformCanAttach(available); + + if (previousCanAttach == m_canAttach) + return; + + if (m_inspectorPage && !m_underTest) + m_inspectorPage->process().send(Messages::WebInspectorUI::SetDockingUnavailable(!m_canAttach), m_inspectorPage->pageID()); + + platformAttachAvailabilityChanged(m_canAttach); } void WebInspectorProxy::inspectedURLChanged(const String& urlString) @@ -529,6 +600,23 @@ void WebInspectorProxy::inspectedURLChanged(const String& urlString) platformInspectedURLChanged(urlString); } +void WebInspectorProxy::elementSelectionChanged(bool active) +{ + m_elementSelectionActive = active; + + if (m_ignoreElementSelectionChange) { + m_ignoreElementSelectionChange = false; + if (!m_isVisible) + close(); + return; + } + + if (active) + platformBringInspectedPageToFront(); + else if (isConnected()) + bringToFront(); +} + void WebInspectorProxy::save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs) { platformSave(filename, content, base64Encoded, forceSaveAs); @@ -539,41 +627,145 @@ void WebInspectorProxy::append(const String& filename, const String& content) platformAppend(filename, content); } -bool WebInspectorProxy::canAttach() +bool WebInspectorProxy::shouldOpenAttached() { - // Keep this in sync with InspectorFrontendClientLocal::canAttachWindow. There are two implementations - // to make life easier in the multi-process world we have. WebInspectorProxy uses canAttach to decide if - // we can attach on open (on the UI process side). And InspectorFrontendClientLocal::canAttachWindow is - // used to decide if we can attach when the attach button is pressed (on the WebProcess side). + return inspectorPagePreferences().inspectorStartsAttached() && canAttach(); +} - // If we are already attached, allow attaching again to allow switching sides. - if (m_isAttached) - return true; +#if ENABLE(INSPECTOR_SERVER) +void WebInspectorProxy::sendMessageToRemoteFrontend(const String& message) +{ + ASSERT(m_remoteInspectionPageId); + WebInspectorServer::singleton().sendMessageOverConnection(m_remoteInspectionPageId, message); +} +#endif - // Don't allow attaching to another inspector -- two inspectors in one window is too much! - if (m_level > 1) - return false; +// Unsupported configurations can use the stubs provided here. - // Don't allow the attach if the window would be too small to accommodate the minimum inspector height. - unsigned inspectedPageHeight = platformInspectedWindowHeight(); - unsigned inspectedPageWidth = platformInspectedWindowWidth(); - unsigned maximumAttachedHeight = inspectedPageHeight * 3 / 4; - return minimumAttachedHeight <= maximumAttachedHeight && minimumAttachedWidth <= inspectedPageWidth; +#if PLATFORM(IOS) || (PLATFORM(MAC) && !WK_API_ENABLED) + +WebPageProxy* WebInspectorProxy::platformCreateInspectorPage() +{ + notImplemented(); + return nullptr; } -bool WebInspectorProxy::shouldOpenAttached() +void WebInspectorProxy::platformOpen() { - return inspectorPageGroup()->preferences()->inspectorStartsAttached() && canAttach(); + notImplemented(); } -#if ENABLE(INSPECTOR_SERVER) -void WebInspectorProxy::sendMessageToRemoteFrontend(const String& message) +void WebInspectorProxy::platformDidClose() { - ASSERT(m_remoteInspectionPageId); - WebInspectorServer::shared().sendMessageOverConnection(m_remoteInspectionPageId, message); + notImplemented(); } -#endif -} // namespace WebKit +void WebInspectorProxy::platformDidCloseForCrash() +{ + notImplemented(); +} + +void WebInspectorProxy::platformInvalidate() +{ + notImplemented(); +} + +void WebInspectorProxy::platformBringToFront() +{ + notImplemented(); +} + +void WebInspectorProxy::platformBringInspectedPageToFront() +{ + notImplemented(); +} + +void WebInspectorProxy::platformHide() +{ + notImplemented(); +} + +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + +void WebInspectorProxy::platformInspectedURLChanged(const String&) +{ + notImplemented(); +} + +void WebInspectorProxy::platformSave(const String& suggestedURL, const String& content, bool base64Encoded, bool forceSaveDialog) +{ + notImplemented(); +} -#endif // ENABLE(INSPECTOR) +void WebInspectorProxy::platformAppend(const String& suggestedURL, const String& content) +{ + notImplemented(); +} + +unsigned WebInspectorProxy::platformInspectedWindowHeight() +{ + notImplemented(); + return 0; +} + +unsigned WebInspectorProxy::platformInspectedWindowWidth() +{ + notImplemented(); + return 0; +} + +void WebInspectorProxy::platformAttach() +{ + notImplemented(); +} + +void WebInspectorProxy::platformDetach() +{ + notImplemented(); +} + +void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned) +{ + notImplemented(); +} + +void WebInspectorProxy::platformStartWindowDrag() +{ + notImplemented(); +} + +String WebInspectorProxy::inspectorPageURL() +{ + notImplemented(); + return String(); +} + +String WebInspectorProxy::inspectorTestPageURL() +{ + notImplemented(); + return String(); +} + +String WebInspectorProxy::inspectorBaseURL() +{ + notImplemented(); + return String(); +} + +void WebInspectorProxy::platformSetAttachedWindowWidth(unsigned) +{ + notImplemented(); +} + +void WebInspectorProxy::platformAttachAvailabilityChanged(bool) +{ + notImplemented(); +} + +#endif // PLATFORM(IOS) || (PLATFORM(MAC) && !WK_API_ENABLED) + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.h b/Source/WebKit2/UIProcess/WebInspectorProxy.h index 0457c471f..1c8ef463c 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.h +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2014, 2016 Apple Inc. All rights reserved. * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,56 +24,56 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebInspectorProxy_h -#define WebInspectorProxy_h - -#if ENABLE(INSPECTOR) +#pragma once #include "APIObject.h" +#include "Attachment.h" #include "MessageReceiver.h" +#include "WebInspectorUtilities.h" #include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/text/WTFString.h> #if PLATFORM(MAC) #include "WKGeometry.h" +#include <WebCore/IntRect.h> #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> +#include <wtf/RunLoop.h> -OBJC_CLASS NSButton; OBJC_CLASS NSURL; +OBJC_CLASS NSView; OBJC_CLASS NSWindow; OBJC_CLASS WKWebInspectorProxyObjCAdapter; -OBJC_CLASS WKWebInspectorWKView; +OBJC_CLASS WKWebInspectorWKWebView; +OBJC_CLASS WKWebViewConfiguration; #endif #if PLATFORM(GTK) #include "WebInspectorClientGtk.h" #endif -#if PLATFORM(EFL) -#include <Ecore_Evas.h> -#include <Evas.h> -#endif +namespace WebCore { +class URL; +} namespace WebKit { class WebFrameProxy; -class WebPageGroup; class WebPageProxy; -struct WebPageCreationParameters; +class WebPreferences; -enum AttachmentSide { - AttachmentSideBottom, - AttachmentSideRight +enum class AttachmentSide { + Bottom, + Right, + Left, }; class WebInspectorProxy : public API::ObjectImpl<API::Object::Type::Inspector>, public IPC::MessageReceiver { public: - static PassRefPtr<WebInspectorProxy> create(WebPageProxy* page) + static Ref<WebInspectorProxy> create(WebPageProxy* inspectedPage) { - return adoptRef(new WebInspectorProxy(page)); + return adoptRef(*new WebInspectorProxy(inspectedPage)); } ~WebInspectorProxy(); @@ -81,9 +81,9 @@ public: void invalidate(); // Public APIs - WebPageProxy* page() const { return m_page; } + WebPageProxy* inspectedPage() const { return m_inspectedPage; } - bool isConnected() const { return m_createdInspectorPage; } + bool isConnected() const { return !!m_inspectorPage; } bool isVisible() const { return m_isVisible; } bool isFront(); @@ -92,16 +92,25 @@ public: void show(); void hide(); void close(); - -#if PLATFORM(MAC) + void closeForCrash(); + +#if PLATFORM(MAC) && WK_API_ENABLED + static RetainPtr<WKWebViewConfiguration> createFrontendConfiguration(WebPageProxy*, bool underTest); + static RetainPtr<NSWindow> createFrontendWindow(NSRect savedWindowFrame); + void createInspectorWindow(); void updateInspectorWindowTitle() const; void inspectedViewFrameDidChange(CGFloat = 0); void windowFrameDidChange(); + void windowFullScreenDidChange(); NSWindow* inspectorWindow() const { return m_inspectorWindow.get(); } void setInspectorWindowFrame(WKRect&); WKRect inspectorWindowFrame(); + + void closeTimerFired(); + + void attachmentViewDidChange(NSView *oldView, NSView *newView); #endif #if PLATFORM(GTK) @@ -111,32 +120,33 @@ public: void showConsole(); void showResources(); + void showTimelines(); void showMainResourceForFrame(WebFrameProxy*); + AttachmentSide attachmentSide() const { return m_attachmentSide; } bool isAttached() const { return m_isAttached; } void attachRight(); + void attachLeft(); void attachBottom(); - void attach(AttachmentSide = AttachmentSideBottom); + void attach(AttachmentSide = AttachmentSide::Bottom); void detach(); void setAttachedWindowHeight(unsigned); void setAttachedWindowWidth(unsigned); - void setToolbarHeight(unsigned height) { platformSetToolbarHeight(height); } - bool isDebuggingJavaScript() const { return m_isDebuggingJavaScript; } - void toggleJavaScriptDebugging(); - - bool isProfilingJavaScript() const { return m_isProfilingJavaScript; } - void toggleJavaScriptProfiling(); + void startWindowDrag(); bool isProfilingPage() const { return m_isProfilingPage; } void togglePageProfiling(); - static bool isInspectorPage(WebPageProxy&); + bool isElementSelectionActive() const { return m_elementSelectionActive; } + void toggleElementSelection(); - // Implemented the platform WebInspectorProxy file - String inspectorPageURL() const; - String inspectorBaseURL() const; + // Provided by platform WebInspectorProxy implementations. + static String inspectorPageURL(); + static String inspectorTestPageURL(); + static String inspectorBaseURL(); + static bool isMainOrTestInspectorPage(const WebCore::URL&); #if ENABLE(INSPECTOR_SERVER) void enableRemoteInspection(); @@ -146,17 +156,27 @@ public: int remoteInspectionPageID() const { return m_remoteInspectionPageId; } #endif + static const unsigned minimumWindowWidth; + static const unsigned minimumWindowHeight; + + static const unsigned initialWindowWidth; + static const unsigned initialWindowHeight; + private: explicit WebInspectorProxy(WebPageProxy*); + void eagerlyCreateInspectorPage(); + // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; WebPageProxy* platformCreateInspectorPage(); void platformOpen(); void platformDidClose(); + void platformDidCloseForCrash(); + void platformInvalidate(); void platformBringToFront(); + void platformBringInspectedPageToFront(); void platformHide(); bool platformIsFront(); void platformAttachAvailabilityChanged(bool); @@ -167,16 +187,24 @@ private: void platformDetach(); void platformSetAttachedWindowHeight(unsigned); void platformSetAttachedWindowWidth(unsigned); - void platformSetToolbarHeight(unsigned); + void platformStartWindowDrag(); void platformSave(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs); void platformAppend(const String& filename, const String& content); +#if PLATFORM(MAC) && WK_API_ENABLED + bool platformCanAttach(bool webProcessCanAttach); +#else + bool platformCanAttach(bool webProcessCanAttach) { return webProcessCanAttach; } +#endif + // Called by WebInspectorProxy messages - void createInspectorPage(uint64_t& inspectorPageID, WebPageCreationParameters&); + void createInspectorPage(IPC::Attachment, bool canAttach, bool underTest); + void frontendLoaded(); void didClose(); void bringToFront(); void attachAvailabilityChanged(bool); void inspectedURLChanged(const String&); + void elementSelectionChanged(bool); void save(const String& filename, const String& content, bool base64Encoded, bool forceSaveAs); void append(const String& filename, const String& content); @@ -185,68 +213,56 @@ private: void sendMessageToRemoteFrontend(const String& message); #endif - bool canAttach(); + bool canAttach() const { return m_canAttach; } bool shouldOpenAttached(); + bool isUnderTest() const { return m_underTest; } + void open(); - WebPageGroup* inspectorPageGroup() const; + unsigned inspectionLevel() const; + + WebPreferences& inspectorPagePreferences() const; -#if PLATFORM(GTK) || PLATFORM(EFL) +#if PLATFORM(GTK) void createInspectorWindow(); + void updateInspectorWindowTitle() const; #endif - static const unsigned minimumWindowWidth; - static const unsigned minimumWindowHeight; - - static const unsigned initialWindowWidth; - static const unsigned initialWindowHeight; - - // Keep this in sync with the value in InspectorFrontendClientLocal. - static const unsigned minimumAttachedWidth; - static const unsigned minimumAttachedHeight; + WebPageProxy* m_inspectedPage { nullptr }; + WebPageProxy* m_inspectorPage { nullptr }; - WebPageProxy* m_page; + bool m_underTest { false }; + bool m_isVisible { false }; + bool m_isAttached { false }; + bool m_canAttach { false }; + bool m_isProfilingPage { false }; + bool m_showMessageSent { false }; + bool m_ignoreFirstBringToFront { false }; + bool m_elementSelectionActive { false }; + bool m_ignoreElementSelectionChange { false }; - bool m_isVisible; - bool m_isAttached; - bool m_isDebuggingJavaScript; - bool m_isProfilingJavaScript; - bool m_isProfilingPage; - bool m_showMessageSent; - bool m_createdInspectorPage; - bool m_ignoreFirstBringToFront; + IPC::Attachment m_connectionIdentifier; - // The debugger stops all the pages in the same PageGroup. Having - // all the inspectors in the same group will make it impossible to debug - // the inspector code, so we use the level to make different page groups. - unsigned m_level; + AttachmentSide m_attachmentSide {AttachmentSide::Bottom}; - AttachmentSide m_attachmentSide; - -#if PLATFORM(MAC) - RetainPtr<WKWebInspectorWKView> m_inspectorView; +#if PLATFORM(MAC) && WK_API_ENABLED + RetainPtr<WKWebInspectorWKWebView> m_inspectorView; RetainPtr<NSWindow> m_inspectorWindow; - RetainPtr<NSButton> m_dockBottomButton; - RetainPtr<NSButton> m_dockRightButton; RetainPtr<WKWebInspectorProxyObjCAdapter> m_inspectorProxyObjCAdapter; - String m_urlString; HashMap<String, RetainPtr<NSURL>> m_suggestedToActualURLMap; + RunLoop::Timer<WebInspectorProxy> m_closeTimer; + String m_urlString; #elif PLATFORM(GTK) WebInspectorClientGtk m_client; - GtkWidget* m_inspectorView; - GtkWidget* m_inspectorWindow; -#elif PLATFORM(EFL) - Evas_Object* m_inspectorView; - Ecore_Evas* m_inspectorWindow; + GtkWidget* m_inspectorView { nullptr }; + GtkWidget* m_inspectorWindow { nullptr }; + GtkWidget* m_headerBar { nullptr }; + String m_inspectedURLString; #endif #if ENABLE(INSPECTOR_SERVER) - int m_remoteInspectionPageId; + int m_remoteInspectionPageId { 0 }; #endif }; } // namespace WebKit - -#endif // ENABLE(INSPECTOR) - -#endif // WebInspectorProxy_h diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in b/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in index 2add42f30..cb1946db7 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2010 Apple Inc. All rights reserved. +# Copyright (C) 2010, 2014 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,29 +20,32 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(INSPECTOR) - messages -> WebInspectorProxy { - CreateInspectorPage() -> (uint64_t inspectorPageID, WebKit::WebPageCreationParameters inspectorPageParameters) + CreateInspectorPage(IPC::Attachment connectionIdentifier, bool canAttach, bool underTest) + + FrontendLoaded() DidClose() BringToFront() + InspectedURLChanged(String urlString) + ElementSelectionChanged(bool active) Save(String filename, String content, bool base64Encoded, bool forceSaveAs) Append(String filename, String content) AttachBottom() AttachRight() + AttachLeft() Detach() + AttachAvailabilityChanged(bool available) SetAttachedWindowHeight(unsigned height) SetAttachedWindowWidth(unsigned width) - SetToolbarHeight(unsigned height) + + StartWindowDrag() #if ENABLE(INSPECTOR_SERVER) SendMessageToRemoteFrontend(String message) #endif } - -#endif diff --git a/Source/WebKit2/UIProcess/WebInspectorUtilities.cpp b/Source/WebKit2/UIProcess/WebInspectorUtilities.cpp new file mode 100644 index 000000000..c5db401ee --- /dev/null +++ b/Source/WebKit2/UIProcess/WebInspectorUtilities.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebInspectorUtilities.h" + +#include "APIProcessPoolConfiguration.h" +#include "WebPageGroup.h" +#include "WebPageProxy.h" +#include "WebProcessPool.h" +#include "WebProcessProxy.h" +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> + +namespace WebKit { + +typedef HashMap<WebPageProxy*, unsigned> PageLevelMap; + +static PageLevelMap& pageLevelMap() +{ + static NeverDestroyed<PageLevelMap> map; + return map; +} + +unsigned inspectorLevelForPage(WebPageProxy* page) +{ + if (page) { + auto findResult = pageLevelMap().find(page); + if (findResult != pageLevelMap().end()) + return findResult->value + 1; + } + + return 1; +} + +String inspectorPageGroupIdentifierForPage(WebPageProxy* page) +{ + return String::format("__WebInspectorPageGroupLevel%u__", inspectorLevelForPage(page)); +} + +void trackInspectorPage(WebPageProxy* page) +{ + pageLevelMap().set(page, inspectorLevelForPage(page)); +} + +void untrackInspectorPage(WebPageProxy* page) +{ + pageLevelMap().remove(page); +} + +static WebProcessPool* s_mainInspectorProcessPool; +static WebProcessPool* s_nestedInspectorProcessPool; + +WebProcessPool& inspectorProcessPool(unsigned inspectionLevel) +{ + // Having our own process pool removes us from the main process pool and + // guarantees no process sharing for our user interface. + WebProcessPool*& pool = (inspectionLevel == 1) ? s_mainInspectorProcessPool : s_nestedInspectorProcessPool; + if (!pool) { + auto configuration = API::ProcessPoolConfiguration::createWithLegacyOptions(); + pool = &WebProcessPool::create(configuration.get()).leakRef(); + } + return *pool; +} + +bool isInspectorProcessPool(WebProcessPool& processPool) +{ + return (s_mainInspectorProcessPool && s_mainInspectorProcessPool == &processPool) + || (s_nestedInspectorProcessPool && s_nestedInspectorProcessPool == &processPool); +} + +bool isInspectorPage(WebPageProxy& webPage) +{ + return pageLevelMap().contains(&webPage); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Network/soup/NetworkProcessProxySoup.cpp b/Source/WebKit2/UIProcess/WebInspectorUtilities.h index 1bdf0ed7c..ec345703b 100644 --- a/Source/WebKit2/UIProcess/Network/soup/NetworkProcessProxySoup.cpp +++ b/Source/WebKit2/UIProcess/WebInspectorUtilities.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Apple Inc. All rights reserved. + * Copyright (C) 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,25 +23,24 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#if ENABLE(NETWORK_PROCESS) +#pragma once -#include "NetworkProcessProxy.h" -#include <glib.h> +#include <wtf/text/WTFString.h> namespace WebKit { -void NetworkProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) -{ -#ifndef NDEBUG - const char* networkProcessCmdPrefix = g_getenv("NETWORK_PROCESS_CMD_PREFIX"); - if (networkProcessCmdPrefix && *networkProcessCmdPrefix) - launchOptions.processCmdPrefix = String::fromUTF8(networkProcessCmdPrefix); -#else - UNUSED_PARAM(launchOptions); -#endif -} +class WebPageProxy; +class WebProcessPool; -} +// The inspector page groups are used to give different preferences to each +// inspector level by setting a per-level page group identifier. +unsigned inspectorLevelForPage(WebPageProxy*); +String inspectorPageGroupIdentifierForPage(WebPageProxy*); +void trackInspectorPage(WebPageProxy*); +void untrackInspectorPage(WebPageProxy*); -#endif // ENABLE(NETWORK_PROCESS) +WebProcessPool& inspectorProcessPool(unsigned inspectionLevel); +bool isInspectorProcessPool(WebProcessPool&); +bool isInspectorPage(WebPageProxy&); + +} diff --git a/Source/WebKit2/UIProcess/WebKeyValueStorageManager.cpp b/Source/WebKit2/UIProcess/WebKeyValueStorageManager.cpp deleted file mode 100644 index b478ad11b..000000000 --- a/Source/WebKit2/UIProcess/WebKeyValueStorageManager.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebKeyValueStorageManager.h" - -#include "APIArray.h" -#include "SecurityOriginData.h" -#include "WebContext.h" -#include "WebSecurityOrigin.h" - -using namespace WebCore; - -namespace WebKit { - -const char* WebKeyValueStorageManager::supplementName() -{ - return "WebKeyValueStorageManager"; -} - -PassRefPtr<WebKeyValueStorageManager> WebKeyValueStorageManager::create(WebContext* context) -{ - return adoptRef(new WebKeyValueStorageManager(context)); -} - -WebKeyValueStorageManager::WebKeyValueStorageManager(WebContext* context) - : WebContextSupplement(context) -{ -} - -WebKeyValueStorageManager::~WebKeyValueStorageManager() -{ -} - -// WebContextSupplement - -void WebKeyValueStorageManager::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebKeyValueStorageManager::derefWebContextSupplement() -{ - API::Object::deref(); -} - -static void didGetKeyValueStorageOrigins(const Vector<RefPtr<WebCore::SecurityOrigin>>& securityOrigins, void* context) -{ - RefPtr<ArrayCallback> callback = adoptRef(static_cast<ArrayCallback*>(context)); - - Vector<RefPtr<API::Object>> webSecurityOrigins; - webSecurityOrigins.reserveInitialCapacity(securityOrigins.size()); - - for (unsigned i = 0; i < securityOrigins.size(); ++i) - webSecurityOrigins.uncheckedAppend(WebSecurityOrigin::create(securityOrigins[i])); - - callback->performCallbackWithReturnValue(API::Array::create(std::move(webSecurityOrigins)).get()); -} - -void WebKeyValueStorageManager::getKeyValueStorageOrigins(PassRefPtr<ArrayCallback> prpCallback) -{ - context()->storageManager().getOrigins(RunLoop::main(), prpCallback.leakRef(), didGetKeyValueStorageOrigins); -} - -void WebKeyValueStorageManager::deleteEntriesForOrigin(WebSecurityOrigin* origin) -{ - context()->storageManager().deleteEntriesForOrigin(origin->securityOrigin()); -} - -void WebKeyValueStorageManager::deleteAllEntries() -{ - context()->storageManager().deleteAllEntries(); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.cpp b/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.cpp deleted file mode 100644 index 781a7f07a..000000000 --- a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebMediaCacheManagerProxy.h" - -#include "APIArray.h" -#include "WebContext.h" -#include "WebMediaCacheManagerMessages.h" -#include "WebMediaCacheManagerProxyMessages.h" -#include "WebSecurityOrigin.h" - -namespace WebKit { - -const char* WebMediaCacheManagerProxy::supplementName() -{ - return "WebMediaCacheManagerProxy"; -} - -PassRefPtr<WebMediaCacheManagerProxy> WebMediaCacheManagerProxy::create(WebContext* context) -{ - return adoptRef(new WebMediaCacheManagerProxy(context)); -} - -WebMediaCacheManagerProxy::WebMediaCacheManagerProxy(WebContext* context) - : WebContextSupplement(context) -{ - WebContextSupplement::context()->addMessageReceiver(Messages::WebMediaCacheManagerProxy::messageReceiverName(), *this); -} - -WebMediaCacheManagerProxy::~WebMediaCacheManagerProxy() -{ -} - -// WebContextSupplement - -void WebMediaCacheManagerProxy::contextDestroyed() -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -void WebMediaCacheManagerProxy::processDidClose(WebProcessProxy*) -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -bool WebMediaCacheManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return m_arrayCallbacks.isEmpty(); -} - -void WebMediaCacheManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebMediaCacheManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebMediaCacheManagerProxy::getHostnamesWithMediaCache(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> When we're sending this to multiple processes, we need to aggregate the callback data when it comes back. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebMediaCacheManager::GetHostnamesWithMediaCache(callbackID)); -} - -void WebMediaCacheManagerProxy::didGetHostnamesWithMediaCache(const Vector<String>& hostnames, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - callback->performCallbackWithReturnValue(API::Array::createStringArray(hostnames).get()); -} - -void WebMediaCacheManagerProxy::clearCacheForHostname(const String& hostname) -{ - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebMediaCacheManager::ClearCacheForHostname(hostname)); -} - -void WebMediaCacheManagerProxy::clearCacheForAllHostnames() -{ - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebMediaCacheManager::ClearCacheForAllHostnames()); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.h b/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.h deleted file mode 100644 index 44f583bae..000000000 --- a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebMediaCacheManagerProxy_h -#define WebMediaCacheManagerProxy_h - -#include "APIObject.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "WebContextSupplement.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace WebKit { - -class WebContext; -class WebProcessProxy; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebMediaCacheManagerProxy : public API::ObjectImpl<API::Object::Type::MediaCacheManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebMediaCacheManagerProxy> create(WebContext*); - virtual ~WebMediaCacheManagerProxy(); - - void getHostnamesWithMediaCache(PassRefPtr<ArrayCallback>); - void clearCacheForHostname(const String&); - void clearCacheForAllHostnames(); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebMediaCacheManagerProxy(WebContext*); - - void didGetHostnamesWithMediaCache(const Vector<String>&, uint64_t callbackID); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; -}; - -} // namespace WebKit - -#endif // WebMediaCacheManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebMediaSessionFocusManager.cpp b/Source/WebKit2/UIProcess/WebMediaSessionFocusManager.cpp new file mode 100644 index 000000000..4bf626e78 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebMediaSessionFocusManager.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebMediaSessionFocusManager.h" + +#if ENABLE(MEDIA_SESSION) + +#include "WebProcessPool.h" + +namespace WebKit { + +const char* WebMediaSessionFocusManager::supplementName() +{ + return "WebMediaSessionFocusManager"; +} + +PassRefPtr<WebMediaSessionFocusManager> WebMediaSessionFocusManager::create(WebProcessPool* processPool) +{ + return adoptRef(new WebMediaSessionFocusManager(processPool)); +} + +WebMediaSessionFocusManager::WebMediaSessionFocusManager(WebProcessPool* processPool) + : WebContextSupplement(processPool) { } + +// WebContextSupplement + +void WebMediaSessionFocusManager::refWebContextSupplement() +{ + API::Object::ref(); +} + +void WebMediaSessionFocusManager::derefWebContextSupplement() +{ + API::Object::deref(); +} + +void WebMediaSessionFocusManager::initializeClient(const WKMediaSessionFocusManagerClientBase* client) +{ + m_client.initialize(client); +} + +bool WebMediaSessionFocusManager::valueForPlaybackAttribute(WKMediaSessionFocusManagerPlaybackAttribute attribute) const +{ + if (!m_focusedMediaElement) + return false; + + return m_playbackAttributes & attribute; +} + +void WebMediaSessionFocusManager::updatePlaybackAttribute(WKMediaSessionFocusManagerPlaybackAttribute attribute, bool value) +{ + if (value) + m_playbackAttributes |= attribute; + else + m_playbackAttributes &= ~attribute; + + m_client.didChangePlaybackAttribute(this, attribute, value); +} + +void WebMediaSessionFocusManager::setVolumeOfFocusedMediaElement(double volume) +{ + if (!m_focusedMediaElement) + return; + + if (WebPageProxy* proxy = m_focusedMediaElement->first) + proxy->setVolumeOfMediaElement(volume, m_focusedMediaElement->second); +} + +void WebMediaSessionFocusManager::updatePlaybackAttributesFromMediaState(WebPageProxy* proxy, uint64_t elementID, WebCore::MediaProducer::MediaStateFlags flags) +{ + if (m_focusedMediaElement) { + if (proxy == m_focusedMediaElement->first && elementID == m_focusedMediaElement->second) { + updatePlaybackAttribute(IsPlaying, flags & WebCore::MediaProducer::IsSourceElementPlaying); + updatePlaybackAttribute(IsNextTrackControlEnabled, flags & WebCore::MediaProducer::IsNextTrackControlEnabled); + updatePlaybackAttribute(IsPreviousTrackControlEnabled, flags & WebCore::MediaProducer::IsPreviousTrackControlEnabled); + } + } +} + +void WebMediaSessionFocusManager::setFocusedMediaElement(WebPageProxy& proxy, uint64_t elementID) +{ + m_focusedMediaElement = std::make_unique<FocusedMediaElement>(&proxy, elementID); +} + +void WebMediaSessionFocusManager::clearFocusedMediaElement() +{ + m_focusedMediaElement = nullptr; +} + +} // namespace WebKit + +#endif // ENABLE(MEDIA_SESSION) diff --git a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.h b/Source/WebKit2/UIProcess/WebMediaSessionFocusManager.h index b71872329..cb7623fd4 100644 --- a/Source/WebKit2/UIProcess/WebBatteryManagerProxy.h +++ b/Source/WebKit2/UIProcess/WebMediaSessionFocusManager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,59 +23,54 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebBatteryManagerProxy_h -#define WebBatteryManagerProxy_h +#ifndef WebMediaSessionFocusManager_h +#define WebMediaSessionFocusManager_h -#if ENABLE(BATTERY_STATUS) +#if ENABLE(MEDIA_SESSION) #include "APIObject.h" -#include "MessageReceiver.h" -#include "WebBatteryProvider.h" #include "WebContextSupplement.h" -#include <wtf/Forward.h> +#include "WebMediaSessionFocusManagerClient.h" +#include "WebPageProxy.h" namespace WebKit { -class WebContext; -class WebBatteryStatus; +typedef std::pair<WebPageProxy*, uint64_t> FocusedMediaElement; -class WebBatteryManagerProxy : public API::ObjectImpl<API::Object::Type::BatteryManager>, public WebContextSupplement, private IPC::MessageReceiver { +class WebMediaSessionFocusManager : public API::ObjectImpl<API::Object::Type::MediaSessionFocusManager>, public WebContextSupplement { public: static const char* supplementName(); - static PassRefPtr<WebBatteryManagerProxy> create(WebContext*); - virtual ~WebBatteryManagerProxy(); + static PassRefPtr<WebMediaSessionFocusManager> create(WebProcessPool*); - void initializeProvider(const WKBatteryProviderBase*); + void initializeClient(const WKMediaSessionFocusManagerClientBase*); - void providerDidChangeBatteryStatus(const WTF::AtomicString&, WebBatteryStatus*); - void providerUpdateBatteryStatus(WebBatteryStatus*); + bool valueForPlaybackAttribute(WKMediaSessionFocusManagerPlaybackAttribute) const; + void updatePlaybackAttributesFromMediaState(WebPageProxy*, uint64_t, WebCore::MediaProducer::MediaStateFlags); + void setVolumeOfFocusedMediaElement(double); + + void setFocusedMediaElement(WebPageProxy&, uint64_t); + void clearFocusedMediaElement(); using API::Object::ref; using API::Object::deref; private: - explicit WebBatteryManagerProxy(WebContext*); + explicit WebMediaSessionFocusManager(WebProcessPool*); // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - void startUpdating(); - void stopUpdating(); + void refWebContextSupplement() override; + void derefWebContextSupplement() override; - bool m_isUpdating; + void updatePlaybackAttribute(WKMediaSessionFocusManagerPlaybackAttribute, bool); - WebBatteryProvider m_provider; + std::unique_ptr<FocusedMediaElement> m_focusedMediaElement; + WKMediaSessionFocusManagerPlaybackAttributes m_playbackAttributes { 0 }; + WebMediaSessionFocusManagerClient m_client; }; } // namespace WebKit -#endif // ENABLE(BATTERY_STATUS) +#endif // ENABLE(MEDIA_SESSION) -#endif // WebBatteryManagerProxy_h +#endif /* WebMediaSessionFocusManager_h */ diff --git a/Source/WebKit2/UIProcess/WebBatteryProvider.cpp b/Source/WebKit2/UIProcess/WebMediaSessionFocusManagerClient.cpp index 28eed97ae..54a6f3782 100644 --- a/Source/WebKit2/UIProcess/WebBatteryProvider.cpp +++ b/Source/WebKit2/UIProcess/WebMediaSessionFocusManagerClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,31 +24,23 @@ */ #include "config.h" -#include "WebBatteryProvider.h" +#include "WebMediaSessionFocusManagerClient.h" -#if ENABLE(BATTERY_STATUS) +#if ENABLE(MEDIA_SESSION) #include "WKAPICast.h" -#include "WebBatteryManagerProxy.h" +#include "WebMediaSessionFocusManager.h" namespace WebKit { -void WebBatteryProvider::startUpdating(WebBatteryManagerProxy* batteryManager) +void WebMediaSessionFocusManagerClient::didChangePlaybackAttribute(WebMediaSessionFocusManager* manager, WKMediaSessionFocusManagerPlaybackAttribute playbackAttribute, bool value) { - if (!m_client.startUpdating) + if (!m_client.didChangePlaybackAttribute) return; - m_client.startUpdating(toAPI(batteryManager), m_client.base.clientInfo); -} - -void WebBatteryProvider::stopUpdating(WebBatteryManagerProxy* batteryManager) -{ - if (!m_client.stopUpdating) - return; - - m_client.stopUpdating(toAPI(batteryManager), m_client.base.clientInfo); + m_client.didChangePlaybackAttribute(toAPI(manager), playbackAttribute, value, m_client.base.clientInfo); } } // namespace WebKit -#endif // ENABLE(BATTERY_STATUS) +#endif // ENABLE(MEDIA_SESSION) diff --git a/Source/WebKit2/UIProcess/WebNetworkInfoProvider.h b/Source/WebKit2/UIProcess/WebMediaSessionFocusManagerClient.h index 785aa80ea..ef69a6690 100644 --- a/Source/WebKit2/UIProcess/WebNetworkInfoProvider.h +++ b/Source/WebKit2/UIProcess/WebMediaSessionFocusManagerClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,36 +23,32 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebNetworkInfoProvider_h -#define WebNetworkInfoProvider_h +#ifndef WebMediaSessionFocusManagerClient_h +#define WebMediaSessionFocusManagerClient_h -#if ENABLE(NETWORK_INFO) +#if ENABLE(MEDIA_SESSION) #include "APIClient.h" -#include "WKNetworkInfoManager.h" +#include "WKMediaSessionFocusManager.h" #include <wtf/Forward.h> namespace API { -template<> struct ClientTraits<WKNetworkInfoProviderBase> { - typedef std::tuple<WKNetworkInfoProviderV0> Versions; +template<> struct ClientTraits<WKMediaSessionFocusManagerClientBase> { + typedef std::tuple<WKMediaSessionFocusManagerClientV0> Versions; }; } namespace WebKit { -class WebNetworkInfoManagerProxy; +class WebMediaSessionFocusManager; -class WebNetworkInfoProvider : public API::Client<WKNetworkInfoProviderBase> { +class WebMediaSessionFocusManagerClient : public API::Client<WKMediaSessionFocusManagerClientBase> { public: - void startUpdating(WebNetworkInfoManagerProxy*); - void stopUpdating(WebNetworkInfoManagerProxy*); - - double bandwidth(WebNetworkInfoManagerProxy*) const; - bool isMetered(WebNetworkInfoManagerProxy*) const; + void didChangePlaybackAttribute(WebMediaSessionFocusManager*, WKMediaSessionFocusManagerPlaybackAttribute, bool); }; } // namespace WebKit -#endif // ENABLE(NETWORK_INFO) +#endif // ENABLE(MEDIA_SESSION) -#endif // WebNetworkInfoProvider_h +#endif // WebMediaSessionFocusManagerClient_h diff --git a/Source/WebKit2/UIProcess/WebNavigationState.cpp b/Source/WebKit2/UIProcess/WebNavigationState.cpp new file mode 100644 index 000000000..43d57ccbb --- /dev/null +++ b/Source/WebKit2/UIProcess/WebNavigationState.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebNavigationState.h" + +#include "APINavigation.h" +#include "WebPageProxy.h" +#include <WebCore/ResourceRequest.h> + +namespace WebKit { + +WebNavigationState::WebNavigationState() +{ +} + +WebNavigationState::~WebNavigationState() +{ +} + +Ref<API::Navigation> WebNavigationState::createLoadRequestNavigation(const WebCore::ResourceRequest& request) +{ + auto navigation = API::Navigation::create(*this, request); + + m_navigations.set(navigation->navigationID(), navigation.ptr()); + + return navigation; +} + +Ref<API::Navigation> WebNavigationState::createBackForwardNavigation() +{ + auto navigation = API::Navigation::create(*this); + + m_navigations.set(navigation->navigationID(), navigation.ptr()); + + return navigation; +} + +Ref<API::Navigation> WebNavigationState::createReloadNavigation() +{ + auto navigation = API::Navigation::create(*this); + + m_navigations.set(navigation->navigationID(), navigation.ptr()); + + return navigation; +} + +Ref<API::Navigation> WebNavigationState::createLoadDataNavigation() +{ + auto navigation = API::Navigation::create(*this); + + m_navigations.set(navigation->navigationID(), navigation.ptr()); + + return navigation; +} + +API::Navigation& WebNavigationState::navigation(uint64_t navigationID) +{ + ASSERT(navigationID); + + return *m_navigations.get(navigationID); +} + +Ref<API::Navigation> WebNavigationState::takeNavigation(uint64_t navigationID) +{ + ASSERT(navigationID); + + return m_navigations.take(navigationID).releaseNonNull(); +} + +void WebNavigationState::didDestroyNavigation(uint64_t navigationID) +{ + ASSERT(navigationID); + + m_navigations.remove(navigationID); +} + +void WebNavigationState::clearAllNavigations() +{ + m_navigations.clear(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebFindClient.h b/Source/WebKit2/UIProcess/WebNavigationState.h index d05bd47e8..13b0c9727 100644 --- a/Source/WebKit2/UIProcess/WebFindClient.h +++ b/Source/WebKit2/UIProcess/WebNavigationState.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,43 +23,50 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebFindClient_h -#define WebFindClient_h +#ifndef WebNavigationState_h +#define WebNavigationState_h -#include "APIClient.h" -#include "WKPage.h" -#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/Ref.h> namespace API { -class Array; - -template<> struct ClientTraits<WKPageFindClientBase> { - typedef std::tuple<WKPageFindClientV0> Versions; -}; +class Navigation; +} -template<> struct ClientTraits<WKPageFindMatchesClientBase> { - typedef std::tuple<WKPageFindMatchesClientV0> Versions; -}; +namespace WebCore { +class ResourceRequest; } namespace WebKit { class WebPageProxy; -class WebImage; +class WebBackForwardListItem; -class WebFindClient : public API::Client<WKPageFindClientBase> { +class WebNavigationState { public: - void didFindString(WebPageProxy*, const String&, uint32_t matchCount); - void didFailToFindString(WebPageProxy*, const String&); - void didCountStringMatches(WebPageProxy*, const String&, uint32_t matchCount); -}; + explicit WebNavigationState(); + ~WebNavigationState(); -class WebFindMatchesClient : public API::Client<WKPageFindMatchesClientBase> { -public: - void didFindStringMatches(WebPageProxy*, const String&, API::Array*, int); - void didGetImageForMatchResult(WebPageProxy*, WebImage*, uint32_t); + Ref<API::Navigation> createBackForwardNavigation(); + Ref<API::Navigation> createLoadRequestNavigation(const WebCore::ResourceRequest&); + Ref<API::Navigation> createReloadNavigation(); + Ref<API::Navigation> createLoadDataNavigation(); + + API::Navigation& navigation(uint64_t navigationID); + Ref<API::Navigation> takeNavigation(uint64_t navigationID); + void didDestroyNavigation(uint64_t navigationID); + void clearAllNavigations(); + + uint64_t generateNavigationID() + { + return ++m_navigationID; + } + +private: + HashMap<uint64_t, RefPtr<API::Navigation>> m_navigations; + uint64_t m_navigationID { 0 }; }; } // namespace WebKit -#endif // WebFindClient_h +#endif // WebNavigationState_h diff --git a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.cpp b/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.cpp deleted file mode 100644 index b9b960b64..000000000 --- a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebNetworkInfoManagerProxy.h" - -#if ENABLE(NETWORK_INFO) - -#include "WebContext.h" -#include "WebNetworkInfo.h" -#include "WebNetworkInfoManagerMessages.h" -#include "WebNetworkInfoManagerProxyMessages.h" - -namespace WebKit { - -const char* WebNetworkInfoManagerProxy::supplementName() -{ - return "WebNetworkInfoManagerProxy"; -} - -PassRefPtr<WebNetworkInfoManagerProxy> WebNetworkInfoManagerProxy::create(WebContext* context) -{ - return adoptRef(new WebNetworkInfoManagerProxy(context)); -} - -WebNetworkInfoManagerProxy::WebNetworkInfoManagerProxy(WebContext* context) - : WebContextSupplement(context) - , m_isUpdating(false) -{ - WebContextSupplement::context()->addMessageReceiver(Messages::WebNetworkInfoManagerProxy::messageReceiverName(), *this); -} - -WebNetworkInfoManagerProxy::~WebNetworkInfoManagerProxy() -{ -} - -void WebNetworkInfoManagerProxy::initializeProvider(const WKNetworkInfoProviderBase* provider) -{ - m_provider.initialize(provider); -} - -void WebNetworkInfoManagerProxy::providerDidChangeNetworkInformation(const AtomicString& eventType, WebNetworkInfo* networkInformation) -{ - if (!context()) - return; - - context()->sendToAllProcesses(Messages::WebNetworkInfoManager::DidChangeNetworkInformation(eventType, networkInformation->data())); -} - -// WebContextSupplement - -void WebNetworkInfoManagerProxy::contextDestroyed() -{ - stopUpdating(); -} - -void WebNetworkInfoManagerProxy::processDidClose(WebProcessProxy*) -{ - stopUpdating(); -} - -void WebNetworkInfoManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebNetworkInfoManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebNetworkInfoManagerProxy::startUpdating() -{ - if (m_isUpdating) - return; - - m_provider.startUpdating(this); - m_isUpdating = true; -} - -void WebNetworkInfoManagerProxy::stopUpdating() -{ - if (!m_isUpdating) - return; - - m_provider.stopUpdating(this); - m_isUpdating = false; -} - -void WebNetworkInfoManagerProxy::getBandwidth(double& bandwidth) -{ - bandwidth = m_provider.bandwidth(this); -} - -void WebNetworkInfoManagerProxy::isMetered(bool& isMetered) -{ - isMetered = m_provider.isMetered(this); -} - -} // namespace WebKit - -#endif // ENABLE(NETWORK_INFO) diff --git a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.h b/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.h deleted file mode 100644 index d8ed157f5..000000000 --- a/Source/WebKit2/UIProcess/WebNetworkInfoManagerProxy.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2012 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebNetworkInfoManagerProxy_h -#define WebNetworkInfoManagerProxy_h - -#if ENABLE(NETWORK_INFO) - -#include "APIObject.h" -#include "MessageReceiver.h" -#include "WebContextSupplement.h" -#include "WebNetworkInfoProvider.h" -#include <wtf/Forward.h> - -namespace WebKit { - -class WebContext; -class WebNetworkInfo; - -class WebNetworkInfoManagerProxy : public API::ObjectImpl<API::Object::Type::NetworkInfoManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebNetworkInfoManagerProxy> create(WebContext*); - virtual ~WebNetworkInfoManagerProxy(); - - void initializeProvider(const WKNetworkInfoProviderBase*); - - void providerDidChangeNetworkInformation(const WTF::AtomicString& eventType, WebNetworkInfo*); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebNetworkInfoManagerProxy(WebContext*); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; - - void startUpdating(); - void stopUpdating(); - - void getBandwidth(double&); - void isMetered(bool&); - - bool m_isUpdating; - - WebContext* m_context; - WebNetworkInfoProvider m_provider; -}; - -} // namespace WebKit - -#endif // ENABLE(NETWORK_INFO) - -#endif // WebNetworkInfoManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp b/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp index f63f5f72d..d503e6ab0 100644 --- a/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.cpp @@ -27,6 +27,7 @@ #include "WebOpenPanelResultListenerProxy.h" #include "APIArray.h" +#include "APIString.h" #include "WebPageProxy.h" #include <WebCore/URL.h> #include <wtf/Vector.h> @@ -44,25 +45,22 @@ WebOpenPanelResultListenerProxy::~WebOpenPanelResultListenerProxy() { } -void WebOpenPanelResultListenerProxy::chooseFiles(API::Array* fileURLsArray) +#if PLATFORM(IOS) +void WebOpenPanelResultListenerProxy::chooseFiles(const Vector<WTF::String>& filenames, const String& displayString, const API::Data* iconImageData) { if (!m_page) return; - size_t size = fileURLsArray->size(); - - Vector<String> filePaths; - filePaths.reserveInitialCapacity(size); + m_page->didChooseFilesForOpenPanelWithDisplayStringAndIcon(filenames, displayString, iconImageData); +} +#endif - for (size_t i = 0; i < size; ++i) { - API::URL* apiURL = fileURLsArray->at<API::URL>(i); - if (apiURL) { - URL url(URL(), apiURL->string()); - filePaths.uncheckedAppend(url.fileSystemPath()); - } - } +void WebOpenPanelResultListenerProxy::chooseFiles(const Vector<String>& filenames) +{ + if (!m_page) + return; - m_page->didChooseFilesForOpenPanel(filePaths); + m_page->didChooseFilesForOpenPanel(filenames); } void WebOpenPanelResultListenerProxy::cancel() @@ -75,7 +73,7 @@ void WebOpenPanelResultListenerProxy::cancel() void WebOpenPanelResultListenerProxy::invalidate() { - m_page = 0; + m_page = nullptr; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h b/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h index ad4bf8f43..ef500238b 100644 --- a/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h +++ b/Source/WebKit2/UIProcess/WebOpenPanelResultListenerProxy.h @@ -27,11 +27,15 @@ #define WebOpenPanelResultListenerProxy_h #include "APIObject.h" +#include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> namespace API { class Array; +class Data; +class String; } namespace WebKit { @@ -47,7 +51,10 @@ public: virtual ~WebOpenPanelResultListenerProxy(); - void chooseFiles(API::Array*); +#if PLATFORM(IOS) + void chooseFiles(const Vector<String>& filenames, const String& displayString, const API::Data* iconImageData); +#endif + void chooseFiles(const Vector<String>& filenames); void cancel(); void invalidate(); diff --git a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.cpp b/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.cpp deleted file mode 100644 index 1595d1bae..000000000 --- a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebOriginDataManagerProxy.h" - -#include "SecurityOriginData.h" -#include "WebContext.h" -#include "WebOriginDataManagerMessages.h" -#include "WebOriginDataManagerProxyMessages.h" -#include "WebSecurityOrigin.h" - -namespace WebKit { - -const char* WebOriginDataManagerProxy::supplementName() -{ - return "WebOriginDataManagerProxy"; -} - -PassRefPtr<WebOriginDataManagerProxy> WebOriginDataManagerProxy::create(WebContext* context) -{ - return adoptRef(new WebOriginDataManagerProxy(context)); -} - -WebOriginDataManagerProxy::WebOriginDataManagerProxy(WebContext* context) - : WebContextSupplement(context) -{ - context->addMessageReceiver(Messages::WebOriginDataManagerProxy::messageReceiverName(), *this); -} - -WebOriginDataManagerProxy::~WebOriginDataManagerProxy() -{ -} - - -void WebOriginDataManagerProxy::contextDestroyed() -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -void WebOriginDataManagerProxy::processDidClose(WebProcessProxy*) -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -bool WebOriginDataManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return m_arrayCallbacks.isEmpty(); -} - -void WebOriginDataManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebOriginDataManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebOriginDataManagerProxy::getOrigins(WKOriginDataTypes types, PassRefPtr<ArrayCallback> prpCallback) -{ - if (!context()) - return; - - RefPtr<ArrayCallback> callback = prpCallback; - - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebOriginDataManager::GetOrigins(types, callbackID)); -} - -void WebOriginDataManagerProxy::didGetOrigins(const Vector<SecurityOriginData>& originDatas, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - performAPICallbackWithSecurityOriginDataVector(originDatas, callback.get()); -} - -void WebOriginDataManagerProxy::deleteEntriesForOrigin(WKOriginDataTypes types, WebSecurityOrigin* origin) -{ - if (!context()) - return; - - SecurityOriginData securityOriginData; - securityOriginData.protocol = origin->protocol(); - securityOriginData.host = origin->host(); - securityOriginData.port = origin->port(); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebOriginDataManager::DeleteEntriesForOrigin(types, securityOriginData)); -} - -void WebOriginDataManagerProxy::deleteAllEntries(WKOriginDataTypes types) -{ - if (!context()) - return; - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> Make manipulating cache information work with per-tab WebProcess. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebOriginDataManager::DeleteAllEntries(types)); -} - -void WebOriginDataManagerProxy::startObservingChanges(WKOriginDataTypes types) -{ - if (!context()) - return; - - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebOriginDataManager::StartObservingChanges(types)); -} - -void WebOriginDataManagerProxy::stopObservingChanges(WKOriginDataTypes types) -{ - if (!context()) - return; - - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebOriginDataManager::StartObservingChanges(types)); -} - -void WebOriginDataManagerProxy::setChangeClient(const WKOriginDataManagerChangeClientBase *client) -{ - m_client.initialize(client); -} - -void WebOriginDataManagerProxy::didChange() -{ - m_client.didChange(this); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.h b/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.h deleted file mode 100644 index c5709c8b5..000000000 --- a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebOriginDataManagerProxy_h -#define WebOriginDataManagerProxy_h - -#include "APIObject.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "WKOriginDataManager.h" -#include "WebContextSupplement.h" -#include "WebOriginDataManagerProxyChangeClient.h" -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace IPC { -class Connection; -} - -namespace WebKit { - -class WebSecurityOrigin; -struct SecurityOriginData; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebOriginDataManagerProxy : public API::ObjectImpl<API::Object::Type::OriginDataManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebOriginDataManagerProxy> create(WebContext*); - virtual ~WebOriginDataManagerProxy(); - - void getOrigins(WKOriginDataTypes, PassRefPtr<ArrayCallback>); - void deleteEntriesForOrigin(WKOriginDataTypes, WebSecurityOrigin*); - void deleteAllEntries(WKOriginDataTypes); - - void startObservingChanges(WKOriginDataTypes); - void stopObservingChanges(WKOriginDataTypes); - void setChangeClient(const WKOriginDataManagerChangeClientBase*); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebOriginDataManagerProxy(WebContext*); - - void didGetOrigins(const Vector<SecurityOriginData>&, uint64_t callbackID); - void didChange(); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; - - WebOriginDataManagerProxyChangeClient m_client; -}; - -} // namespace WebKit - -#endif // WebOriginDataManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.messages.in deleted file mode 100644 index 76d76b4c8..000000000 --- a/Source/WebKit2/UIProcess/WebOriginDataManagerProxy.messages.in +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2011 Apple Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -messages -> WebOriginDataManagerProxy { - DidGetOrigins(Vector<WebKit::SecurityOriginData> originIdentifiers, uint64_t callbackID); - DidChange() -} diff --git a/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp b/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp deleted file mode 100644 index 2fc340f67..000000000 --- a/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if ENABLE(CONTEXT_MENUS) - -#include "WebPageContextMenuClient.h" - -#include "APIArray.h" -#include "Logging.h" -#include "WebContextMenuItem.h" -#include "WKAPICast.h" -#include "WKSharedAPICast.h" - -namespace WebKit { - -bool WebPageContextMenuClient::getContextMenuFromProposedMenu(WebPageProxy* page, const Vector<WebContextMenuItemData>& proposedMenuVector, Vector<WebContextMenuItemData>& customMenu, const WebHitTestResult::Data& hitTestResultData, API::Object* userData) -{ - if (!m_client.getContextMenuFromProposedMenu && !m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0) - return false; - - if (m_client.base.version >= 2 && !m_client.getContextMenuFromProposedMenu) - return false; - - Vector<RefPtr<API::Object>> proposedMenuItems; - proposedMenuItems.reserveInitialCapacity(proposedMenuVector.size()); - - for (const auto& menuItem : proposedMenuVector) - proposedMenuItems.uncheckedAppend(WebContextMenuItem::create(menuItem)); - - WKArrayRef newMenu = nullptr; - if (m_client.base.version >= 2) { - RefPtr<WebHitTestResult> webHitTestResult = WebHitTestResult::create(hitTestResultData); - m_client.getContextMenuFromProposedMenu(toAPI(page), toAPI(API::Array::create(std::move(proposedMenuItems)).get()), &newMenu, toAPI(webHitTestResult.get()), toAPI(userData), m_client.base.clientInfo); - } else - m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0(toAPI(page), toAPI(API::Array::create(std::move(proposedMenuItems)).get()), &newMenu, toAPI(userData), m_client.base.clientInfo); - - RefPtr<API::Array> array = adoptRef(toImpl(newMenu)); - - customMenu.clear(); - - size_t newSize = array ? array->size() : 0; - for (size_t i = 0; i < newSize; ++i) { - WebContextMenuItem* item = array->at<WebContextMenuItem>(i); - if (!item) { - LOG(ContextMenu, "New menu entry at index %i is not a WebContextMenuItem", (int)i); - continue; - } - - customMenu.append(*item->data()); - } - - return true; -} - -void WebPageContextMenuClient::customContextMenuItemSelected(WebPageProxy* page, const WebContextMenuItemData& itemData) -{ - if (!m_client.customContextMenuItemSelected) - return; - - RefPtr<WebContextMenuItem> item = WebContextMenuItem::create(itemData); - m_client.customContextMenuItemSelected(toAPI(page), toAPI(item.get()), m_client.base.clientInfo); -} - -void WebPageContextMenuClient::contextMenuDismissed(WebPageProxy* page) -{ - if (!m_client.contextMenuDismissed) - return; - - m_client.contextMenuDismissed(toAPI(page), m_client.base.clientInfo); -} - -bool WebPageContextMenuClient::showContextMenu(WebPageProxy* page, const WebCore::IntPoint& menuLocation, const Vector<WebContextMenuItemData>& menuItemsVector) -{ - if (!m_client.showContextMenu) - return false; - - Vector<RefPtr<API::Object>> menuItems; - menuItems.reserveInitialCapacity(menuItemsVector.size()); - - for (const auto& menuItem : menuItemsVector) - menuItems.uncheckedAppend(WebContextMenuItem::create(menuItem)); - - m_client.showContextMenu(toAPI(page), toAPI(menuLocation), toAPI(API::Array::create(std::move(menuItems)).get()), m_client.base.clientInfo); - - return true; -} - -bool WebPageContextMenuClient::hideContextMenu(WebPageProxy* page) -{ - if (!m_client.hideContextMenu) - return false; - - m_client.hideContextMenu(toAPI(page), m_client.base.clientInfo); - - return true; -} - -} // namespace WebKit -#endif // ENABLE(CONTEXT_MENUS) diff --git a/Source/WebKit2/UIProcess/WebPageDiagnosticLoggingClient.cpp b/Source/WebKit2/UIProcess/WebPageDiagnosticLoggingClient.cpp new file mode 100644 index 000000000..a547ead52 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebPageDiagnosticLoggingClient.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPageDiagnosticLoggingClient.h" + +#include "WKAPICast.h" +#include "WebPageProxy.h" +#include <wtf/text/WTFString.h> + +namespace WebKit { + +WebPageDiagnosticLoggingClient::WebPageDiagnosticLoggingClient(const WKPageDiagnosticLoggingClientBase* client) +{ + initialize(client); +} + +void WebPageDiagnosticLoggingClient::logDiagnosticMessage(WebPageProxy* page, const String& message, const String& description) +{ + if (!m_client.logDiagnosticMessage) + return; + + m_client.logDiagnosticMessage(toAPI(page), toAPI(message.impl()), toAPI(description.impl()), m_client.base.clientInfo); +} + +void WebPageDiagnosticLoggingClient::logDiagnosticMessageWithResult(WebPageProxy* page, const String& message, const String& description, WebCore::DiagnosticLoggingResultType result) +{ + if (!m_client.logDiagnosticMessageWithResult) + return; + + m_client.logDiagnosticMessageWithResult(toAPI(page), toAPI(message.impl()), toAPI(description.impl()), toAPI(result), m_client.base.clientInfo); +} + +void WebPageDiagnosticLoggingClient::logDiagnosticMessageWithValue(WebPageProxy* page, const String& message, const String& description, const String& value) +{ + if (!m_client.logDiagnosticMessageWithValue) + return; + + m_client.logDiagnosticMessageWithValue(toAPI(page), toAPI(message.impl()), toAPI(description.impl()), toAPI(value.impl()), m_client.base.clientInfo); +} + +void WebPageDiagnosticLoggingClient::logDiagnosticMessageWithEnhancedPrivacy(WebPageProxy* page, const String& message, const String& description) +{ + if (!m_client.logDiagnosticMessageWithEnhancedPrivacy) + return; + + m_client.logDiagnosticMessageWithEnhancedPrivacy(toAPI(page), toAPI(message.impl()), toAPI(description.impl()), m_client.base.clientInfo); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPageContextMenuClient.h b/Source/WebKit2/UIProcess/WebPageDiagnosticLoggingClient.h index eb96712e5..baadc1527 100644 --- a/Source/WebKit2/UIProcess/WebPageContextMenuClient.h +++ b/Source/WebKit2/UIProcess/WebPageDiagnosticLoggingClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,38 +23,37 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebPageContextMenuClient_h -#define WebPageContextMenuClient_h - -#if ENABLE(CONTEXT_MENUS) +#ifndef WebPageDiagnosticLoggingClient_h +#define WebPageDiagnosticLoggingClient_h #include "APIClient.h" -#include "WebHitTestResult.h" +#include "APIDiagnosticLoggingClient.h" #include "WKPage.h" -#include <WebCore/IntPoint.h> -#include <wtf/Vector.h> +#include <WebCore/DiagnosticLoggingResultType.h> +#include <wtf/Forward.h> namespace API { -template<> struct ClientTraits<WKPageContextMenuClientBase> { - typedef std::tuple<WKPageContextMenuClientV0, WKPageContextMenuClientV1, WKPageContextMenuClientV2, WKPageContextMenuClientV3> Versions; + +template<> struct ClientTraits<WKPageDiagnosticLoggingClientBase> { + typedef std::tuple<WKPageDiagnosticLoggingClientV0, WKPageDiagnosticLoggingClientV1> Versions; }; -} + +} // namespace API namespace WebKit { -class WebContextMenuItemData; class WebPageProxy; -class WebPageContextMenuClient : public API::Client<WKPageContextMenuClientBase> { +class WebPageDiagnosticLoggingClient final : public API::Client<WKPageDiagnosticLoggingClientBase>, public API::DiagnosticLoggingClient { public: - bool getContextMenuFromProposedMenu(WebPageProxy*, const Vector<WebContextMenuItemData>& proposedMenu, Vector<WebContextMenuItemData>& customMenu, const WebHitTestResult::Data&, API::Object* userData); - void customContextMenuItemSelected(WebPageProxy*, const WebContextMenuItemData&); - void contextMenuDismissed(WebPageProxy*); - bool showContextMenu(WebPageProxy*, const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&); - bool hideContextMenu(WebPageProxy*); + explicit WebPageDiagnosticLoggingClient(const WKPageDiagnosticLoggingClientBase*); + + void logDiagnosticMessage(WebPageProxy*, const String& message, const String& description) override; + void logDiagnosticMessageWithResult(WebPageProxy*, const String& message, const String& description, WebCore::DiagnosticLoggingResultType) override; + void logDiagnosticMessageWithValue(WebPageProxy*, const String& message, const String& description, const String& value) override; + void logDiagnosticMessageWithEnhancedPrivacy(WebPageProxy*, const String& message, const String& description) override; }; } // namespace WebKit -#endif // ENABLE(CONTEXT_MENUS) -#endif // WebPageContextMenuClient_h +#endif // WebPageDiagnosticLoggingClient_h diff --git a/Source/WebKit2/UIProcess/WebPageGroup.cpp b/Source/WebKit2/UIProcess/WebPageGroup.cpp index 59cc1ff5d..a04e0370a 100644 --- a/Source/WebKit2/UIProcess/WebPageGroup.cpp +++ b/Source/WebKit2/UIProcess/WebPageGroup.cpp @@ -27,9 +27,13 @@ #include "WebPageGroup.h" #include "APIArray.h" -#include "WebPageGroupProxyMessages.h" +#include "APIUserContentExtension.h" +#include "APIUserScript.h" +#include "APIUserStyleSheet.h" +#include "WebCompiledContentExtension.h" #include "WebPageProxy.h" #include "WebPreferences.h" +#include "WebUserContentControllerProxy.h" #include <wtf/HashMap.h> #include <wtf/NeverDestroyed.h> #include <wtf/text/StringConcatenate.h> @@ -55,7 +59,7 @@ PassRefPtr<WebPageGroup> WebPageGroup::create(const String& identifier, bool vis return adoptRef(new WebPageGroup(identifier, visibleToInjectedBundle, visibleToHistoryClient)); } -PassRef<WebPageGroup> WebPageGroup::createNonNull(const String& identifier, bool visibleToInjectedBundle, bool visibleToHistoryClient) +Ref<WebPageGroup> WebPageGroup::createNonNull(const String& identifier, bool visibleToInjectedBundle, bool visibleToHistoryClient) { return adoptRef(*new WebPageGroup(identifier, visibleToInjectedBundle, visibleToHistoryClient)); } @@ -65,25 +69,37 @@ WebPageGroup* WebPageGroup::get(uint64_t pageGroupID) return webPageGroupMap().get(pageGroupID); } -WebPageGroup::WebPageGroup(const String& identifier, bool visibleToInjectedBundle, bool visibleToHistoryClient) +static WebPageGroupData pageGroupData(const String& identifier, bool visibleToInjectedBundle, bool visibleToHistoryClient) { - m_data.pageGroupID = generatePageGroupID(); + WebPageGroupData data; + + data.pageGroupID = generatePageGroupID(); if (!identifier.isEmpty()) - m_data.identifer = identifier; + data.identifier = identifier; else - m_data.identifer = m_data.identifer = makeString("__uniquePageGroupID-", String::number(m_data.pageGroupID)); + data.identifier = makeString("__uniquePageGroupID-", String::number(data.pageGroupID)); + + data.visibleToInjectedBundle = visibleToInjectedBundle; + data.visibleToHistoryClient = visibleToHistoryClient; + + return data; +} + +// FIXME: Why does the WebPreferences object here use ".WebKit2" instead of "WebKit2." which all the other constructors use. +// If it turns out that it's wrong, we can change it to to "WebKit2." and get rid of the globalDebugKeyPrefix from WebPreferences. +WebPageGroup::WebPageGroup(const String& identifier, bool visibleToInjectedBundle, bool visibleToHistoryClient) + : m_data(pageGroupData(identifier, visibleToInjectedBundle, visibleToHistoryClient)) + , m_preferences(WebPreferences::createWithLegacyDefaults(m_data.identifier, ".WebKit2", "WebKit2.")) + , m_userContentController(WebUserContentControllerProxy::create()) +{ + m_data.userContentControllerIdentifier = m_userContentController->identifier(); - m_data.visibleToInjectedBundle = visibleToInjectedBundle; - m_data.visibleToHistoryClient = visibleToHistoryClient; - webPageGroupMap().set(m_data.pageGroupID, this); } WebPageGroup::~WebPageGroup() { - if (m_preferences) - m_preferences->removePageGroup(this); webPageGroupMap().remove(pageGroupID()); } @@ -102,28 +118,15 @@ void WebPageGroup::setPreferences(WebPreferences* preferences) if (preferences == m_preferences) return; - if (!m_preferences) { - m_preferences = preferences; - m_preferences->addPageGroup(this); - } else { - m_preferences->removePageGroup(this); - m_preferences = preferences; - m_preferences->addPageGroup(this); + m_preferences = preferences; - preferencesDidChange(); - } + for (auto& webPageProxy : m_pages) + webPageProxy->setPreferences(*m_preferences); } -WebPreferences* WebPageGroup::preferences() const +WebPreferences& WebPageGroup::preferences() const { - if (!m_preferences) { - if (!m_data.identifer.isNull()) - m_preferences = WebPreferences::create(m_data.identifer); - else - m_preferences = WebPreferences::create(); - m_preferences->addPageGroup(const_cast<WebPageGroup*>(this)); - } - return m_preferences.get(); + return *m_preferences; } void WebPageGroup::preferencesDidChange() @@ -134,45 +137,9 @@ void WebPageGroup::preferencesDidChange() } } -void WebPageGroup::addUserStyleSheet(const String& source, const String& baseURL, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames injectedFrames, WebCore::UserStyleLevel level) -{ - if (source.isEmpty()) - return; - - WebCore::UserStyleSheet userStyleSheet = WebCore::UserStyleSheet(source, (baseURL.isEmpty() ? WebCore::blankURL() : WebCore::URL(WebCore::URL(), baseURL)), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectedFrames, level); - - m_data.userStyleSheets.append(userStyleSheet); - sendToAllProcessesInGroup(Messages::WebPageGroupProxy::AddUserStyleSheet(userStyleSheet), m_data.pageGroupID); -} - -void WebPageGroup::addUserScript(const String& source, const String& baseURL, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames injectedFrames, WebCore::UserScriptInjectionTime injectionTime) -{ - if (source.isEmpty()) - return; - - WebCore::UserScript userScript = WebCore::UserScript(source, (baseURL.isEmpty() ? WebCore::blankURL() : WebCore::URL(WebCore::URL(), baseURL)), whitelist ? whitelist->toStringVector() : Vector<String>(), blacklist ? blacklist->toStringVector() : Vector<String>(), injectionTime, injectedFrames); - - m_data.userScripts.append(userScript); - sendToAllProcessesInGroup(Messages::WebPageGroupProxy::AddUserScript(userScript), m_data.pageGroupID); -} - -void WebPageGroup::removeAllUserStyleSheets() -{ - m_data.userStyleSheets.clear(); - sendToAllProcessesInGroup(Messages::WebPageGroupProxy::RemoveAllUserStyleSheets(), m_data.pageGroupID); -} - -void WebPageGroup::removeAllUserScripts() -{ - m_data.userScripts.clear(); - sendToAllProcessesInGroup(Messages::WebPageGroupProxy::RemoveAllUserScripts(), m_data.pageGroupID); -} - -void WebPageGroup::removeAllUserContent() +WebUserContentControllerProxy& WebPageGroup::userContentController() { - m_data.userStyleSheets.clear(); - m_data.userScripts.clear(); - sendToAllProcessesInGroup(Messages::WebPageGroupProxy::RemoveAllUserContent(), m_data.pageGroupID); + return *m_userContentController; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPageGroup.h b/Source/WebKit2/UIProcess/WebPageGroup.h index 46027c5af..a3eba61ea 100644 --- a/Source/WebKit2/UIProcess/WebPageGroup.h +++ b/Source/WebKit2/UIProcess/WebPageGroup.h @@ -30,19 +30,22 @@ #include "WebPageGroupData.h" #include "WebPageProxy.h" #include "WebProcessProxy.h" +#include <WebCore/UserStyleSheetTypes.h> #include <wtf/Forward.h> #include <wtf/HashSet.h> +#include <wtf/text/WTFString.h> namespace WebKit { class WebPreferences; class WebPageProxy; +class WebUserContentControllerProxy; class WebPageGroup : public API::ObjectImpl<API::Object::Type::PageGroup> { public: WebPageGroup(const String& identifier = String(), bool visibleToInjectedBundle = true, bool visibleToHistoryClient = true); static PassRefPtr<WebPageGroup> create(const String& identifier = String(), bool visibleToInjectedBundle = true, bool visibleToHistoryClient = true); - static PassRef<WebPageGroup> createNonNull(const String& identifier = String(), bool visibleToInjectedBundle = true, bool visibleToHistoryClient = true); + static Ref<WebPageGroup> createNonNull(const String& identifier = String(), bool visibleToInjectedBundle = true, bool visibleToHistoryClient = true); static WebPageGroup* get(uint64_t pageGroupID); virtual ~WebPageGroup(); @@ -50,44 +53,23 @@ public: void addPage(WebPageProxy*); void removePage(WebPageProxy*); - const String& identifier() const { return m_data.identifer; } uint64_t pageGroupID() const { return m_data.pageGroupID; } - const WebPageGroupData& data() { return m_data; } + const WebPageGroupData& data() const { return m_data; } void setPreferences(WebPreferences*); - WebPreferences* preferences() const; + WebPreferences& preferences() const; void preferencesDidChange(); - - void addUserStyleSheet(const String& source, const String& baseURL, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames, WebCore::UserStyleLevel); - void addUserScript(const String& source, const String& baseURL, API::Array* whitelist, API::Array* blacklist, WebCore::UserContentInjectedFrames, WebCore::UserScriptInjectionTime); - void removeAllUserStyleSheets(); - void removeAllUserScripts(); - void removeAllUserContent(); -private: - template<typename T> void sendToAllProcessesInGroup(const T&, uint64_t destinationID); + WebUserContentControllerProxy& userContentController(); +private: WebPageGroupData m_data; - mutable RefPtr<WebPreferences> m_preferences; + RefPtr<WebPreferences> m_preferences; + RefPtr<WebUserContentControllerProxy> m_userContentController; HashSet<WebPageProxy*> m_pages; }; -template<typename T> -void WebPageGroup::sendToAllProcessesInGroup(const T& message, uint64_t destinationID) -{ - HashSet<WebProcessProxy*> processesSeen; - - for (WebPageProxy* webPageProxy : m_pages) { - WebProcessProxy& webProcessProxy = webPageProxy->process(); - if (!processesSeen.add(&webProcessProxy).isNewEntry) - continue; - - if (webProcessProxy.canSendMessage()) - webProcessProxy.send(T(message), destinationID); - } -} - } // namespace WebKit #endif // WebPageGroup_h diff --git a/Source/WebKit2/UIProcess/WebPageInjectedBundleClient.cpp b/Source/WebKit2/UIProcess/WebPageInjectedBundleClient.cpp new file mode 100644 index 000000000..a89357533 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebPageInjectedBundleClient.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPageInjectedBundleClient.h" + +#include "WKAPICast.h" +#include "WebProcessPool.h" +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPageInjectedBundleClient::didReceiveMessageFromInjectedBundle(WebPageProxy* page, const String& messageName, API::Object* messageBody) +{ + if (!m_client.didReceiveMessageFromInjectedBundle) + return; + + m_client.didReceiveMessageFromInjectedBundle(toAPI(page), toAPI(messageName.impl()), toAPI(messageBody), m_client.base.clientInfo); +} + +void WebPageInjectedBundleClient::didReceiveSynchronousMessageFromInjectedBundle(WebPageProxy* page, const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) +{ + if (!m_client.didReceiveSynchronousMessageFromInjectedBundle) + return; + + WKTypeRef returnDataRef = 0; + m_client.didReceiveSynchronousMessageFromInjectedBundle(toAPI(page), toAPI(messageName.impl()), toAPI(messageBody), &returnDataRef, m_client.base.clientInfo); + returnData = adoptRef(toImpl(returnDataRef)); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebDatabaseManagerProxyClient.h b/Source/WebKit2/UIProcess/WebPageInjectedBundleClient.h index 0e5091a29..30c7f354c 100644 --- a/Source/WebKit2/UIProcess/WebDatabaseManagerProxyClient.h +++ b/Source/WebKit2/UIProcess/WebPageInjectedBundleClient.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,30 +23,31 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebDatabaseManagerProxyClient_h -#define WebDatabaseManagerProxyClient_h +#ifndef WebPageInjectedBundleClient_h +#define WebPageInjectedBundleClient_h #include "APIClient.h" -#include "WKDatabaseManager.h" +#include "WKPage.h" #include <wtf/Forward.h> namespace API { -template<> struct ClientTraits<WKDatabaseManagerClientBase> { - typedef std::tuple<WKDatabaseManagerClientV0> Versions; +class Object; + +template<> struct ClientTraits<WKPageInjectedBundleClientBase> { + typedef std::tuple<WKPageInjectedBundleClientV0> Versions; }; } namespace WebKit { -class WebDatabaseManagerProxy; -class WebSecurityOrigin; +class WebPageProxy; -class WebDatabaseManagerProxyClient : public API::Client<WKDatabaseManagerClientBase> { +class WebPageInjectedBundleClient : public API::Client<WKPageInjectedBundleClientBase> { public: - void didModifyOrigin(WebDatabaseManagerProxy*, WebSecurityOrigin*); - void didModifyDatabase(WebDatabaseManagerProxy*, WebSecurityOrigin*, const String& databaseIdentifier); + void didReceiveMessageFromInjectedBundle(WebPageProxy*, const String&, API::Object*); + void didReceiveSynchronousMessageFromInjectedBundle(WebPageProxy*, const String&, API::Object*, RefPtr<API::Object>& returnData); }; } // namespace WebKit -#endif // WebDatabaseManagerProxyClient_h +#endif // WebPageInjectedBundleClient_h diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index bb8578dc7..721bd41f2 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011, 2015-2016 Apple Inc. All rights reserved. * Copyright (C) 2012 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,8 +28,27 @@ #include "WebPageProxy.h" #include "APIArray.h" +#include "APIContextMenuClient.h" +#include "APIFindClient.h" +#include "APIFindMatchesClient.h" +#include "APIFormClient.h" +#include "APIFrameInfo.h" +#include "APIFullscreenClient.h" +#include "APIGeometry.h" +#include "APIHistoryClient.h" +#include "APIHitTestResult.h" +#include "APIIconLoadingClient.h" +#include "APILegacyContextHistoryClient.h" #include "APILoaderClient.h" +#include "APINavigation.h" +#include "APINavigationAction.h" +#include "APINavigationClient.h" +#include "APINavigationResponse.h" +#include "APIOpenPanelParameters.h" +#include "APIPageConfiguration.h" #include "APIPolicyClient.h" +#include "APISecurityOrigin.h" +#include "APIUIClient.h" #include "APIURLRequest.h" #include "AuthenticationChallengeProxy.h" #include "AuthenticationDecisionListener.h" @@ -38,29 +57,30 @@ #include "DrawingAreaProxy.h" #include "DrawingAreaProxyMessages.h" #include "EventDispatcherMessages.h" -#include "FindIndicator.h" +#include "LoadParameters.h" #include "Logging.h" +#include "NativeWebGestureEvent.h" #include "NativeWebKeyboardEvent.h" #include "NativeWebMouseEvent.h" #include "NativeWebWheelEvent.h" #include "NavigationActionData.h" +#include "NetworkProcessMessages.h" #include "NotificationPermissionRequest.h" #include "NotificationPermissionRequestManager.h" #include "PageClient.h" #include "PluginInformation.h" #include "PluginProcessManager.h" #include "PrintInfo.h" -#include "SessionState.h" #include "TextChecker.h" #include "TextCheckerState.h" +#include "UserMediaPermissionRequestProxy.h" #include "WKContextPrivate.h" +#include "WebAutomationSession.h" #include "WebBackForwardList.h" #include "WebBackForwardListItem.h" #include "WebCertificateInfo.h" -#include "WebColorPickerResultListenerProxy.h" -#include "WebContext.h" +#include "WebContextMenuItem.h" #include "WebContextMenuProxy.h" -#include "WebContextUserMessageCoders.h" #include "WebCoreArgumentCoders.h" #include "WebEditCommandProxy.h" #include "WebEvent.h" @@ -69,8 +89,10 @@ #include "WebFramePolicyListenerProxy.h" #include "WebFullScreenManagerProxy.h" #include "WebFullScreenManagerProxyMessages.h" +#include "WebImage.h" #include "WebInspectorProxy.h" -#include "WebInspectorProxyMessages.h" +#include "WebInspectorUtilities.h" +#include "WebNavigationState.h" #include "WebNotificationManagerProxy.h" #include "WebOpenPanelResultListenerProxy.h" #include "WebPageCreationParameters.h" @@ -78,41 +100,42 @@ #include "WebPageGroupData.h" #include "WebPageMessages.h" #include "WebPageProxyMessages.h" +#include "WebPaymentCoordinatorProxy.h" #include "WebPopupItem.h" #include "WebPopupMenuProxy.h" #include "WebPreferences.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" #include "WebProtectionSpace.h" -#include "WebSecurityOrigin.h" +#include "WebUserContentControllerProxy.h" +#include "WebsiteDataStore.h" +#include <WebCore/BitmapImage.h> +#include <WebCore/DiagnosticLoggingClient.h> #include <WebCore/DragController.h> #include <WebCore/DragData.h> -#include <WebCore/DragSession.h> +#include <WebCore/EventNames.h> #include <WebCore/FloatRect.h> #include <WebCore/FocusDirection.h> +#include <WebCore/JSDOMBinding.h> +#include <WebCore/JSDOMExceptionHandling.h> #include <WebCore/MIMETypeRegistry.h> #include <WebCore/RenderEmbeddedObject.h> +#include <WebCore/SerializedCryptoKeyWrap.h> #include <WebCore/TextCheckerClient.h> +#include <WebCore/TextIndicator.h> +#include <WebCore/URL.h> +#include <WebCore/ValidationBubble.h> #include <WebCore/WindowFeatures.h> -#include <wtf/NeverDestroyed.h> #include <stdio.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/StringBuilder.h> +#include <wtf/text/StringView.h> #if ENABLE(ASYNC_SCROLLING) #include "RemoteScrollingCoordinatorProxy.h" #endif -#if USE(COORDINATED_GRAPHICS) -#include "CoordinatedLayerTreeHostProxyMessages.h" -#endif - -#if PLATFORM(GTK) -#include "ArgumentCodersGtk.h" -#endif - -#if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS) -#include "WebSoupRequestManagerProxy.h" -#endif - #if ENABLE(VIBRATION) #include "WebVibrationProxy.h" #endif @@ -121,24 +144,52 @@ #include <wtf/RefCountedLeakCounter.h> #endif -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessMessages.h" +#if PLATFORM(COCOA) +#include "RemoteLayerTreeDrawingAreaProxy.h" +#include "RemoteLayerTreeScrollingPerformanceData.h" +#include "ViewSnapshotStore.h" +#include "WebVideoFullscreenManagerProxy.h" +#include "WebVideoFullscreenManagerProxyMessages.h" +#include <WebCore/MachSendRight.h> +#include <WebCore/RunLoopObserver.h> +#include <WebCore/TextIndicatorWindow.h> #endif -#if PLATFORM(MAC) -#include "ViewSnapshotStore.h" +#if PLATFORM(GTK) +#include "WebSelectionData.h" #endif #if USE(CAIRO) #include <WebCore/CairoUtilities.h> #endif +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) +#include <WebCore/MediaPlaybackTarget.h> +#include <WebCore/WebMediaSessionManager.h> +#endif + +#if ENABLE(MEDIA_SESSION) +#include "WebMediaSessionFocusManager.h" +#include "WebMediaSessionMetadata.h" +#include <WebCore/MediaSessionMetadata.h> +#endif + +#if PLATFORM(IOS) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) +#include "WebPlaybackSessionManagerProxy.h" +#endif + +#if ENABLE(MEDIA_STREAM) +#include <WebCore/MediaConstraintsImpl.h> +#endif + // This controls what strategy we use for mouse wheel coalescing. #define MERGE_WHEEL_EVENTS 1 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection()) #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection()) +#define RELEASE_LOG_IF_ALLOWED(...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), ProcessSuspension, __VA_ARGS__) + using namespace WebCore; // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively. @@ -164,37 +215,37 @@ public: RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply; }; - static ExceededDatabaseQuotaRecords& shared(); + static ExceededDatabaseQuotaRecords& singleton(); - PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier, + std::unique_ptr<Record> createRecord(uint64_t frameID, String originIdentifier, String databaseName, String displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>); - void add(PassOwnPtr<Record>); - bool areBeingProcessed() const { return m_currentRecord; } + void add(std::unique_ptr<Record>); + bool areBeingProcessed() const { return !!m_currentRecord; } Record* next(); private: ExceededDatabaseQuotaRecords() { } ~ExceededDatabaseQuotaRecords() { } - Deque<OwnPtr<Record>> m_records; - OwnPtr<Record> m_currentRecord; + Deque<std::unique_ptr<Record>> m_records; + std::unique_ptr<Record> m_currentRecord; }; -ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared() +ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::singleton() { static NeverDestroyed<ExceededDatabaseQuotaRecords> records; return records; } -PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord( +std::unique_ptr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord( uint64_t frameID, String originIdentifier, String databaseName, String displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply) { - OwnPtr<Record> record = adoptPtr(new Record); + auto record = std::make_unique<Record>(); record->frameID = frameID; record->originIdentifier = originIdentifier; record->databaseName = databaseName; @@ -204,17 +255,17 @@ PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::c record->currentDatabaseUsage = currentDatabaseUsage; record->expectedUsage = expectedUsage; record->reply = reply; - return record.release(); + return record; } -void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record) +void ExceededDatabaseQuotaRecords::add(std::unique_ptr<ExceededDatabaseQuotaRecords::Record> record) { - m_records.append(record); + m_records.append(WTFMove(record)); } ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next() { - m_currentRecord.clear(); + m_currentRecord = nullptr; if (!m_records.isEmpty()) m_currentRecord = m_records.takeFirst(); return m_currentRecord.get(); @@ -243,40 +294,85 @@ static const char* webKeyboardEventTypeString(WebEvent::Type type) } #endif // !LOG_DISABLED -PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration) +class PageClientProtector { + WTF_MAKE_NONCOPYABLE(PageClientProtector); +public: + PageClientProtector(PageClient& pageClient) + : m_pageClient(pageClient) + { + m_pageClient.refView(); + } + + ~PageClientProtector() + { + m_pageClient.derefView(); + } + +private: + PageClient& m_pageClient; +}; + +Ref<WebPageProxy> WebPageProxy::create(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration) { - return adoptRef(new WebPageProxy(pageClient, process, pageID, configuration)); + return adoptRef(*new WebPageProxy(pageClient, process, pageID, WTFMove(configuration))); } -WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, const WebPageConfiguration& configuration) +WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uint64_t pageID, Ref<API::PageConfiguration>&& configuration) : m_pageClient(pageClient) + , m_configuration(WTFMove(configuration)) , m_loaderClient(std::make_unique<API::LoaderClient>()) , m_policyClient(std::make_unique<API::PolicyClient>()) + , m_formClient(std::make_unique<API::FormClient>()) + , m_uiClient(std::make_unique<API::UIClient>()) + , m_findClient(std::make_unique<API::FindClient>()) + , m_findMatchesClient(std::make_unique<API::FindMatchesClient>()) + , m_diagnosticLoggingClient(std::make_unique<API::DiagnosticLoggingClient>()) +#if ENABLE(CONTEXT_MENUS) + , m_contextMenuClient(std::make_unique<API::ContextMenuClient>()) +#endif + , m_navigationState(std::make_unique<WebNavigationState>()) , m_process(process) - , m_pageGroup(*configuration.pageGroup) + , m_pageGroup(*m_configuration->pageGroup()) + , m_preferences(*m_configuration->preferences()) + , m_userContentController(*m_configuration->userContentController()) + , m_visitedLinkStore(*m_configuration->visitedLinkStore()) + , m_websiteDataStore(m_configuration->websiteDataStore()->websiteDataStore()) , m_mainFrame(nullptr) , m_userAgent(standardUserAgent()) + , m_overrideContentSecurityPolicy { m_configuration->overrideContentSecurityPolicy() } + , m_treatsSHA1CertificatesAsInsecure(m_configuration->treatsSHA1SignedCertificatesAsInsecure()) +#if ENABLE(FULLSCREEN_API) + , m_fullscreenClient(std::make_unique<API::FullscreenClient>()) +#endif , m_geolocationPermissionRequestManager(*this) , m_notificationPermissionRequestManager(*this) - , m_viewState(ViewState::NoFlags) + , m_activityState(ActivityState::NoFlags) + , m_viewWasEverInWindow(false) +#if PLATFORM(IOS) + , m_alwaysRunsAtForegroundPriority(m_configuration->alwaysRunsAtForegroundPriority()) +#endif + , m_initialCapitalizationEnabled(m_configuration->initialCapitalizationEnabled()) , m_backForwardList(WebBackForwardList::create(*this)) - , m_loadStateAtProcessExit(FrameLoadState::State::Finished) - , m_temporarilyClosedComposition(false) + , m_maintainsInactiveSelection(false) + , m_waitsForPaintAfterViewDidMoveToWindow(m_configuration->waitsForPaintAfterViewDidMoveToWindow()) + , m_isEditable(false) , m_textZoomFactor(1) , m_pageZoomFactor(1) , m_pageScaleFactor(1) + , m_pluginZoomFactor(1) + , m_pluginScaleFactor(1) , m_intrinsicDeviceScaleFactor(1) , m_customDeviceScaleFactor(0) - , m_layerHostingMode(LayerHostingModeDefault) + , m_topContentInset(0) + , m_layerHostingMode(LayerHostingMode::InProcess) , m_drawsBackground(true) - , m_drawsTransparentBackground(false) - , m_areMemoryCacheClientCallsEnabled(true) , m_useFixedLayout(false) , m_suppressScrollbarAnimations(false) , m_paginationMode(Pagination::Unpaginated) , m_paginationBehavesLikeColumns(false) , m_pageLength(0) , m_gapBetweenPages(0) + , m_paginationLineGridEnabled(false) , m_isValid(true) , m_isClosed(false) , m_canRunModal(false) @@ -292,47 +388,76 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin , m_syncNavigationActionPolicyAction(PolicyUse) , m_syncNavigationActionPolicyDownloadID(0) , m_processingMouseMoveEvent(false) -#if ENABLE(TOUCH_EVENTS) - , m_needTouchEvents(false) -#endif , m_pageID(pageID) - , m_session(*configuration.session) + , m_sessionID(m_configuration->sessionID()) , m_isPageSuspended(false) -#if PLATFORM(MAC) + , m_addsVisitedLinks(true) + , m_controlledByAutomation(m_configuration->isControlledByAutomation()) +#if ENABLE(REMOTE_INSPECTOR) + , m_allowsRemoteInspection(true) +#endif +#if PLATFORM(COCOA) , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled()) #endif +#if PLATFORM(GTK) + , m_backgroundColor(Color::white) +#endif , m_spellDocumentTag(0) , m_hasSpellDocumentTag(false) , m_pendingLearnOrIgnoreWordMessageCount(0) + , m_mainFrameHasCustomContentProvider(false) +#if ENABLE(DRAG_SUPPORT) + , m_currentDragOperation(DragOperationNone) + , m_currentDragIsOverFileInput(false) + , m_currentDragNumberOfFilesToBeAccepted(0) +#endif + , m_pageLoadState(*this) + , m_delegatesScrolling(false) , m_mainFrameHasHorizontalScrollbar(false) , m_mainFrameHasVerticalScrollbar(false) , m_canShortCircuitHorizontalWheelEvents(true) - , m_mainFrameIsPinnedToLeftSide(false) - , m_mainFrameIsPinnedToRightSide(false) - , m_mainFrameIsPinnedToTopSide(false) - , m_mainFrameIsPinnedToBottomSide(false) - , m_useLegacyImplicitRubberBandControl(false) + , m_mainFrameIsPinnedToLeftSide(true) + , m_mainFrameIsPinnedToRightSide(true) + , m_mainFrameIsPinnedToTopSide(true) + , m_mainFrameIsPinnedToBottomSide(true) + , m_shouldUseImplicitRubberBandControl(false) , m_rubberBandsAtLeft(true) , m_rubberBandsAtRight(true) , m_rubberBandsAtTop(true) , m_rubberBandsAtBottom(true) + , m_enableVerticalRubberBanding(true) + , m_enableHorizontalRubberBanding(true) , m_backgroundExtendsBeyondPage(false) - , m_mainFrameInViewSourceMode(false) , m_shouldRecordNavigationSnapshots(false) + , m_isShowingNavigationGestureSnapshot(false) , m_pageCount(0) , m_renderTreeSize(0) - , m_shouldSendEventsSynchronously(false) + , m_sessionRestorationRenderTreeSize(0) + , m_hitRenderTreeSizeThreshold(false) , m_suppressVisibilityUpdates(false) , m_autoSizingShouldExpandToViewHeight(false) , m_mediaVolume(1) , m_mayStartMediaWhenInWindow(true) - , m_waitingForDidUpdateViewState(false) + , m_waitingForDidUpdateActivityState(false) +#if PLATFORM(COCOA) + , m_scrollPerformanceDataCollectionEnabled(false) +#endif , m_scrollPinningBehavior(DoNotPin) -{ - updateViewState(); - -#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) - m_layerHostingMode = m_viewState & ViewState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingModeInWindowServer; + , m_navigationID(0) + , m_configurationPreferenceValues(m_configuration->preferenceValues()) + , m_potentiallyChangedActivityStateFlags(ActivityState::NoFlags) + , m_activityStateChangeWantsSynchronousReply(false) + , m_weakPtrFactory(this) +{ + m_webProcessLifetimeTracker.addObserver(m_visitedLinkStore); + m_webProcessLifetimeTracker.addObserver(m_websiteDataStore); + + updateActivityState(); + updateThrottleState(); + updateHiddenPageThrottlingAutoIncreases(); + +#if HAVE(OUT_OF_PROCESS_LAYER_HOSTING) + m_layerHostingMode = m_activityState & ActivityState::IsInWindow ? m_pageClient.viewLayerHostingMode() : LayerHostingMode::OutOfProcess; #endif platformInitialize(); @@ -341,37 +466,59 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin webPageProxyCounter.increment(); #endif - WebContext::statistics().wkPageCount++; + WebProcessPool::statistics().wkPageCount++; + m_preferences->addPage(*this); m_pageGroup->addPage(this); -#if ENABLE(INSPECTOR) m_inspector = WebInspectorProxy::create(this); -#endif #if ENABLE(FULLSCREEN_API) m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient()); #endif +#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + m_playbackSessionManager = WebPlaybackSessionManagerProxy::create(*this); + m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager); +#endif #if ENABLE(VIBRATION) m_vibration = WebVibrationProxy::create(this); #endif +#if ENABLE(APPLE_PAY) + m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this); +#endif + m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this); - // FIXME: If we ever expose the session storage size as a preference, we need to pass it here. - m_process->context().storageManager().createSessionStorageNamespace(m_pageID, m_process->isValid() ? m_process->connection() : 0, std::numeric_limits<unsigned>::max()); - setSession(*configuration.session); + if (m_sessionID.isEphemeral()) { + m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(m_sessionID)); + m_process->processPool().sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession(m_sessionID)); + } + +#if PLATFORM(COCOA) + const CFIndex activityStateChangeRunLoopOrder = (CFIndex)RunLoopObserver::WellKnownRunLoopOrders::CoreAnimationCommit - 1; + m_activityStateChangeDispatcher = std::make_unique<RunLoopObserver>(activityStateChangeRunLoopOrder, [this] { + this->dispatchActivityStateChange(); + }); +#endif } WebPageProxy::~WebPageProxy() { + ASSERT(m_process->webPage(m_pageID) != this); +#if !ASSERT_DISABLED + for (WebPageProxy* page : m_process->pages()) + ASSERT(page != this); +#endif + if (!m_isClosed) close(); - WebContext::statistics().wkPageCount--; + WebProcessPool::statistics().wkPageCount--; if (m_hasSpellDocumentTag) TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag); + m_preferences->removePage(*this); m_pageGroup->removePage(this); #ifndef NDEBUG @@ -379,7 +526,12 @@ WebPageProxy::~WebPageProxy() #endif } -PlatformProcessIdentifier WebPageProxy::processIdentifier() const +const API::PageConfiguration& WebPageProxy::configuration() const +{ + return m_configuration.get(); +} + +pid_t WebPageProxy::processIdentifier() const { if (m_isClosed) return 0; @@ -396,20 +548,26 @@ bool WebPageProxy::isValid() const return m_isValid; } -PassRefPtr<API::Array> WebPageProxy::relatedPages() const +void WebPageProxy::setPreferences(WebPreferences& preferences) { - // pages() returns a list of pages in WebProcess, so this page may or may not be among them - a client can use a reference to WebPageProxy after the page has closed. - Vector<WebPageProxy*> pages = m_process->pages(); + if (&preferences == m_preferences.ptr()) + return; - Vector<RefPtr<API::Object>> result; - result.reserveInitialCapacity(pages.size()); + m_preferences->removePage(*this); + m_preferences = preferences; + m_preferences->addPage(*this); - for (const auto& page : pages) { - if (page != this) - result.uncheckedAppend(page); - } + preferencesDidChange(); +} + +void WebPageProxy::setHistoryClient(std::unique_ptr<API::HistoryClient> historyClient) +{ + m_historyClient = WTFMove(historyClient); +} - return API::Array::create(std::move(result)); +void WebPageProxy::setNavigationClient(std::unique_ptr<API::NavigationClient> navigationClient) +{ + m_navigationClient = WTFMove(navigationClient); } void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClient) @@ -419,7 +577,7 @@ void WebPageProxy::setLoaderClient(std::unique_ptr<API::LoaderClient> loaderClie return; } - m_loaderClient = std::move(loaderClient); + m_loaderClient = WTFMove(loaderClient); } void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClient) @@ -429,65 +587,158 @@ void WebPageProxy::setPolicyClient(std::unique_ptr<API::PolicyClient> policyClie return; } - m_policyClient = std::move(policyClient); + m_policyClient = WTFMove(policyClient); } -void WebPageProxy::initializeFormClient(const WKPageFormClientBase* formClient) +void WebPageProxy::setFormClient(std::unique_ptr<API::FormClient> formClient) { - m_formClient.initialize(formClient); + if (!formClient) { + m_formClient = std::make_unique<API::FormClient>(); + return; + } + + m_formClient = WTFMove(formClient); } -void WebPageProxy::initializeUIClient(const WKPageUIClientBase* client) +void WebPageProxy::setUIClient(std::unique_ptr<API::UIClient> uiClient) { + if (!uiClient) { + m_uiClient = std::make_unique<API::UIClient>(); + return; + } + + m_uiClient = WTFMove(uiClient); + if (!isValid()) return; - m_uiClient.initialize(client); + m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient->canRunBeforeUnloadConfirmPanel()), m_pageID); + setCanRunModal(m_uiClient->canRunModal()); +} - m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID); - setCanRunModal(m_uiClient.canRunModal()); +void WebPageProxy::setIconLoadingClient(std::unique_ptr<API::IconLoadingClient> iconLoadingClient) +{ + bool hasClient = iconLoadingClient.get(); + if (!iconLoadingClient) + m_iconLoadingClient = std::make_unique<API::IconLoadingClient>(); + else + m_iconLoadingClient = WTFMove(iconLoadingClient); + + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetUseIconLoadingClient(hasClient), m_pageID); } -void WebPageProxy::initializeFindClient(const WKPageFindClientBase* client) +void WebPageProxy::setFindClient(std::unique_ptr<API::FindClient> findClient) { - m_findClient.initialize(client); + if (!findClient) { + m_findClient = std::make_unique<API::FindClient>(); + return; + } + + m_findClient = WTFMove(findClient); } -void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClientBase* client) +void WebPageProxy::setFindMatchesClient(std::unique_ptr<API::FindMatchesClient> findMatchesClient) { - m_findMatchesClient.initialize(client); + if (!findMatchesClient) { + m_findMatchesClient = std::make_unique<API::FindMatchesClient>(); + return; + } + + m_findMatchesClient = WTFMove(findMatchesClient); +} + +void WebPageProxy::setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient> diagnosticLoggingClient) +{ + if (!diagnosticLoggingClient) { + m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>(); + return; + } + + m_diagnosticLoggingClient = WTFMove(diagnosticLoggingClient); } #if ENABLE(CONTEXT_MENUS) -void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClientBase* client) +void WebPageProxy::setContextMenuClient(std::unique_ptr<API::ContextMenuClient> contextMenuClient) { - m_contextMenuClient.initialize(client); + if (!contextMenuClient) { + m_contextMenuClient = std::make_unique<API::ContextMenuClient>(); + return; + } + + m_contextMenuClient = WTFMove(contextMenuClient); } #endif +void WebPageProxy::setInjectedBundleClient(const WKPageInjectedBundleClientBase* client) +{ + if (!client) { + m_injectedBundleClient = nullptr; + return; + } + + m_injectedBundleClient = std::make_unique<WebPageInjectedBundleClient>(); + m_injectedBundleClient->initialize(client); +} + +void WebPageProxy::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody) +{ + ASSERT(m_process->connection() == &connection); + + if (!m_injectedBundleClient) + return; + + m_injectedBundleClient->didReceiveMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get()); +} + +void WebPageProxy::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData) +{ + ASSERT(m_process->connection() == &connection); + + if (!m_injectedBundleClient) + return; + + RefPtr<API::Object> returnData; + m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(this, messageName, m_process->transformHandlesToObjects(messageBody.object()).get(), returnData); + returnUserData = UserData(m_process->transformObjectsToHandles(returnData.get())); +} + void WebPageProxy::reattachToWebProcess() { + ASSERT(!m_isClosed); ASSERT(!isValid()); - ASSERT(!m_process->isValid()); - ASSERT(!m_process->isLaunching()); - - updateViewState(); + ASSERT(m_process->state() == WebProcessProxy::State::Terminated); m_isValid = true; + m_wasKilledForBeingUnresponsiveWhileInBackground = false; + m_process->removeWebPage(m_pageID); + m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); - if (m_process->context().processModel() == ProcessModelSharedSecondaryProcess) - m_process = m_process->context().ensureSharedWebProcess(); - else - m_process = m_process->context().createNewWebProcessRespectingProcessCountLimit(); + m_process = m_process->processPool().createNewWebProcessRespectingProcessCountLimit(); + + ASSERT(m_process->state() != ChildProcessProxy::State::Terminated); + if (m_process->state() == ChildProcessProxy::State::Running) + processDidFinishLaunching(); m_process->addExistingWebPage(this, m_pageID); m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, *this); -#if ENABLE(INSPECTOR) + updateActivityState(); + updateThrottleState(); + m_inspector = WebInspectorProxy::create(this); -#endif #if ENABLE(FULLSCREEN_API) m_fullScreenManager = WebFullScreenManagerProxy::create(*this, m_pageClient.fullScreenManagerProxyClient()); #endif +#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + m_playbackSessionManager = WebPlaybackSessionManagerProxy::create(*this); + m_videoFullscreenManager = WebVideoFullscreenManagerProxy::create(*this, *m_playbackSessionManager); +#endif + +#if ENABLE(APPLE_PAY) + m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this); +#endif initializeWebPage(); @@ -495,28 +746,46 @@ void WebPageProxy::reattachToWebProcess() m_drawingArea->waitForBackingStoreUpdateOnNextPaint(); } -void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item) +RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessForReload() { - if (item && item != m_backForwardList->currentItem()) - m_backForwardList->goToItem(item); + if (m_isClosed) + return nullptr; + ASSERT(!isValid()); reattachToWebProcess(); - if (!item) - return; + if (!m_backForwardList->currentItem()) + return nullptr; + + auto navigation = m_navigationState->createReloadNavigation(); - m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID); - m_process->responsivenessTimer()->start(); + // We allow stale content when reloading a WebProcess that's been killed or crashed. + m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), m_backForwardList->currentItem()->itemID()), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } -void WebPageProxy::setSession(API::Session& session) +RefPtr<API::Navigation> WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item) { - m_session = session; - m_process->send(Messages::WebPage::SetSessionID(session.getID()), m_pageID); + if (m_isClosed) + return nullptr; -#if ENABLE(NETWORK_PROCESS) - m_process->context().sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(session.getID())); -#endif + ASSERT(!isValid()); + reattachToWebProcess(); + + if (!item) + return nullptr; + + if (item != m_backForwardList->currentItem()) + m_backForwardList->goToItem(item); + + auto navigation = m_navigationState->createBackForwardNavigation(); + + m_process->send(Messages::WebPage::GoToBackForwardItem(navigation->navigationID(), item->itemID()), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } void WebPageProxy::initializeWebPage() @@ -531,59 +800,86 @@ void WebPageProxy::initializeWebPage() ASSERT(m_drawingArea); #if ENABLE(ASYNC_SCROLLING) - if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) + if (m_drawingArea->type() == DrawingAreaTypeRemoteLayerTree) { m_scrollingCoordinatorProxy = std::make_unique<RemoteScrollingCoordinatorProxy>(*this); +#if PLATFORM(IOS) + // On iOS, main frame scrolls are sent in terms of visible rect updates. + m_scrollingCoordinatorProxy->setPropagatesMainFrameScrolls(false); +#endif + } #endif #if ENABLE(INSPECTOR_SERVER) - if (pageGroup().preferences()->developerExtrasEnabled()) + if (m_preferences->developerExtrasEnabled()) inspector()->enableRemoteInspection(); #endif process().send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0); -#if PLATFORM(MAC) - send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled)); -#endif + m_needsToFinishInitializingWebPageAfterProcessLaunch = true; + finishInitializingWebPageAfterProcessLaunch(); } -bool WebPageProxy::isProcessSuppressible() const +void WebPageProxy::finishInitializingWebPageAfterProcessLaunch() { - return (m_viewState & ViewState::IsVisuallyIdle) && m_pageGroup->preferences()->pageVisibilityBasedProcessSuppressionEnabled(); + if (!m_needsToFinishInitializingWebPageAfterProcessLaunch) + return; + if (m_process->state() != WebProcessProxy::State::Running) + return; + + m_needsToFinishInitializingWebPageAfterProcessLaunch = false; + + m_process->addWebUserContentControllerProxy(m_userContentController); + m_process->addVisitedLinkStore(m_visitedLinkStore); } void WebPageProxy::close() { - if (!isValid()) + if (m_isClosed) return; m_isClosed = true; + if (m_activePopupMenu) + m_activePopupMenu->cancelTracking(); + +#if ENABLE(CONTEXT_MENUS) + m_activeContextMenu = nullptr; +#endif + m_backForwardList->pageClosed(); m_pageClient.pageClosed(); m_process->disconnectFramesFromPage(this); - resetState(); + resetState(ResetStateReason::PageInvalidated); - m_loaderClient = nullptr; - m_policyClient = nullptr; - m_formClient.initialize(0); - m_uiClient.initialize(0); -#if PLATFORM(EFL) - m_uiPopupMenuClient.initialize(0); -#endif - m_findClient.initialize(0); - m_findMatchesClient.initialize(0); + m_loaderClient = std::make_unique<API::LoaderClient>(); + m_navigationClient = nullptr; + m_policyClient = std::make_unique<API::PolicyClient>(); + m_formClient = std::make_unique<API::FormClient>(); + m_uiClient = std::make_unique<API::UIClient>(); + m_findClient = std::make_unique<API::FindClient>(); + m_findMatchesClient = std::make_unique<API::FindMatchesClient>(); + m_diagnosticLoggingClient = std::make_unique<API::DiagnosticLoggingClient>(); #if ENABLE(CONTEXT_MENUS) - m_contextMenuClient.initialize(0); + m_contextMenuClient = std::make_unique<API::ContextMenuClient>(); #endif + m_webProcessLifetimeTracker.pageWasInvalidated(); + m_process->send(Messages::WebPage::Close(), m_pageID); m_process->removeWebPage(m_pageID); m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); - m_process->context().storageManager().destroySessionStorageNamespace(m_pageID); - m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this); + m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this); + + // Null out related WebPageProxy to avoid leaks. + m_configuration->setRelatedPage(nullptr); + +#if PLATFORM(IOS) + // Make sure we don't hold a process assertion after getting closed. + m_activityToken = nullptr; +#endif } bool WebPageProxy::tryClose() @@ -591,8 +887,13 @@ bool WebPageProxy::tryClose() if (!isValid()) return true; + // Close without delay if the process allows it. Our goal is to terminate + // the process, so we check a per-process status bit. + if (m_process->isSuddenTerminationEnabled()) + return true; + m_process->send(Messages::WebPage::TryClose(), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->responsivenessTimer().start(); return false; } @@ -604,17 +905,26 @@ bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const URL& url, Sandbox if (m_process->hasAssumedReadAccessToURL(url)) return false; -#if ENABLE(INSPECTOR) // Inspector resources are in a directory with assumed access. - ASSERT_WITH_SECURITY_IMPLICATION(!WebInspectorProxy::isInspectorPage(*this)); -#endif + ASSERT_WITH_SECURITY_IMPLICATION(!WebKit::isInspectorPage(*this)); SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle); return true; } -void WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* userData) +#if !PLATFORM(COCOA) +void WebPageProxy::addPlatformLoadParameters(LoadParameters&) { +} +#endif + +RefPtr<API::Navigation> WebPageProxy::loadRequest(const ResourceRequest& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData) +{ + if (m_isClosed) + return nullptr; + + auto navigation = m_navigationState->createLoadRequestNavigation(request); + auto transaction = m_pageLoadState.transaction(); m_pageLoadState.setPendingAPIRequestURL(transaction, request.url()); @@ -622,22 +932,33 @@ void WebPageProxy::loadRequest(const ResourceRequest& request, API::Object* user if (!isValid()) reattachToWebProcess(); - SandboxExtension::Handle sandboxExtensionHandle; - bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), sandboxExtensionHandle); + LoadParameters loadParameters; + loadParameters.navigationID = navigation->navigationID(); + loadParameters.request = request; + loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)shouldOpenExternalURLsPolicy; + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + bool createdExtension = maybeInitializeSandboxExtensionHandle(request.url(), loadParameters.sandboxExtensionHandle); if (createdExtension) m_process->willAcquireUniversalFileReadSandboxExtension(); - m_process->send(Messages::WebPage::LoadRequest(request, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + addPlatformLoadParameters(loadParameters); + + m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } -void WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData) +RefPtr<API::Navigation> WebPageProxy::loadFile(const String& fileURLString, const String& resourceDirectoryURLString, API::Object* userData) { + if (m_isClosed) + return nullptr; + if (!isValid()) reattachToWebProcess(); URL fileURL = URL(URL(), fileURLString); if (!fileURL.isLocalFile()) - return; + return nullptr; URL resourceDirectoryURL; if (resourceDirectoryURLString.isNull()) @@ -645,71 +966,187 @@ void WebPageProxy::loadFile(const String& fileURLString, const String& resourceD else { resourceDirectoryURL = URL(URL(), resourceDirectoryURLString); if (!resourceDirectoryURL.isLocalFile()) - return; + return nullptr; } + auto navigation = m_navigationState->createLoadRequestNavigation(ResourceRequest(fileURL)); + + auto transaction = m_pageLoadState.transaction(); + + m_pageLoadState.setPendingAPIRequestURL(transaction, fileURLString); + String resourceDirectoryPath = resourceDirectoryURL.fileSystemPath(); - SandboxExtension::Handle sandboxExtensionHandle; - SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, sandboxExtensionHandle); + LoadParameters loadParameters; + loadParameters.navigationID = navigation->navigationID(); + loadParameters.request = fileURL; + loadParameters.shouldOpenExternalURLsPolicy = (uint64_t)ShouldOpenExternalURLsPolicy::ShouldNotAllow; + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + SandboxExtension::createHandle(resourceDirectoryPath, SandboxExtension::ReadOnly, loadParameters.sandboxExtensionHandle); + addPlatformLoadParameters(loadParameters); + m_process->assumeReadAccessToBaseURL(resourceDirectoryURL); - m_process->send(Messages::WebPage::LoadRequest(fileURL, sandboxExtensionHandle, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->send(Messages::WebPage::LoadRequest(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } -void WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData) +RefPtr<API::Navigation> WebPageProxy::loadData(API::Data* data, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData) { + if (m_isClosed) + return nullptr; + + auto navigation = m_navigationState->createLoadDataNavigation(); + + auto transaction = m_pageLoadState.transaction(); + + m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string()); + if (!isValid()) reattachToWebProcess(); + LoadParameters loadParameters; + loadParameters.navigationID = navigation->navigationID(); + loadParameters.data = data->dataReference(); + loadParameters.MIMEType = MIMEType; + loadParameters.encodingName = encoding; + loadParameters.baseURLString = baseURL; + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + addPlatformLoadParameters(loadParameters); + m_process->assumeReadAccessToBaseURL(baseURL); - m_process->send(Messages::WebPage::LoadData(data->dataReference(), MIMEType, encoding, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } -void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData) +// FIXME: Get rid of loadHTMLString and just use loadData instead. +RefPtr<API::Navigation> WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData) { + if (m_isClosed) + return nullptr; + + auto navigation = m_navigationState->createLoadDataNavigation(); + + auto transaction = m_pageLoadState.transaction(); + + m_pageLoadState.setPendingAPIRequestURL(transaction, !baseURL.isEmpty() ? baseURL : blankURL().string()); + if (!isValid()) reattachToWebProcess(); + LoadParameters loadParameters; + loadParameters.navigationID = navigation->navigationID(); + loadParameters.string = htmlString; + loadParameters.MIMEType = ASCIILiteral("text/html"); + loadParameters.baseURLString = baseURL; + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + addPlatformLoadParameters(loadParameters); + m_process->assumeReadAccessToBaseURL(baseURL); - m_process->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); } void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData) { + // When the UIProcess is in the process of handling a failing provisional load, do not attempt to + // start a second alternative HTML load as this will prevent the page load state from being + // handled properly. + if (m_isClosed || m_isLoadingAlternateHTMLStringForFailingProvisionalLoad) + return; + + if (!m_failingProvisionalLoadURL.isEmpty()) + m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = true; + if (!isValid()) reattachToWebProcess(); auto transaction = m_pageLoadState.transaction(); + m_pageLoadState.setPendingAPIRequestURL(transaction, unreachableURL); m_pageLoadState.setUnreachableURL(transaction, unreachableURL); if (m_mainFrame) m_mainFrame->setUnreachableURL(unreachableURL); + LoadParameters loadParameters; + loadParameters.navigationID = 0; + loadParameters.string = htmlString; + loadParameters.baseURLString = baseURL; + loadParameters.unreachableURLString = unreachableURL; + loadParameters.provisionalLoadErrorURLString = m_failingProvisionalLoadURL; + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + addPlatformLoadParameters(loadParameters); + m_process->assumeReadAccessToBaseURL(baseURL); - m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->assumeReadAccessToBaseURL(unreachableURL); + m_process->send(Messages::WebPage::LoadAlternateHTMLString(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); } void WebPageProxy::loadPlainTextString(const String& string, API::Object* userData) { + if (m_isClosed) + return; + if (!isValid()) reattachToWebProcess(); - m_process->send(Messages::WebPage::LoadPlainTextString(string, WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + auto transaction = m_pageLoadState.transaction(); + m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string()); + + LoadParameters loadParameters; + loadParameters.navigationID = 0; + loadParameters.string = string; + loadParameters.MIMEType = ASCIILiteral("text/plain"); + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + addPlatformLoadParameters(loadParameters); + + m_process->send(Messages::WebPage::LoadString(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); } void WebPageProxy::loadWebArchiveData(API::Data* webArchiveData, API::Object* userData) { + if (m_isClosed) + return; + if (!isValid()) reattachToWebProcess(); - m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference(), WebContextUserMessageEncoder(userData, process())), m_pageID); - m_process->responsivenessTimer()->start(); + auto transaction = m_pageLoadState.transaction(); + m_pageLoadState.setPendingAPIRequestURL(transaction, blankURL().string()); + + LoadParameters loadParameters; + loadParameters.navigationID = 0; + loadParameters.data = webArchiveData->dataReference(); + loadParameters.MIMEType = ASCIILiteral("application/x-webarchive"); + loadParameters.encodingName = ASCIILiteral("utf-16"); + loadParameters.userData = UserData(process().transformObjectsToHandles(userData).get()); + addPlatformLoadParameters(loadParameters); + + m_process->send(Messages::WebPage::LoadData(loadParameters), m_pageID); + m_process->responsivenessTimer().start(); +} + +void WebPageProxy::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint) +{ + if (m_isClosed) + return; + + if (WebCore::protocolIsJavaScript(url)) + return; + + if (!isValid()) + reattachToWebProcess(); + + m_process->send(Messages::WebPage::NavigateToPDFLinkWithSimulatedClick(url, documentPoint, screenPoint), m_pageID); + m_process->responsivenessTimer().start(); } void WebPageProxy::stopLoading() @@ -718,15 +1155,18 @@ void WebPageProxy::stopLoading() return; m_process->send(Messages::WebPage::StopLoading(), m_pageID); - m_process->responsivenessTimer()->start(); + m_process->responsivenessTimer().start(); } -void WebPageProxy::reload(bool reloadFromOrigin) +RefPtr<API::Navigation> WebPageProxy::reload(bool reloadFromOrigin, bool contentBlockersEnabled) { SandboxExtension::Handle sandboxExtensionHandle; - if (m_backForwardList->currentItem()) { - String url = m_backForwardList->currentItem()->url(); + String url = m_pageLoadState.activeURL(); + if (url.isEmpty() && m_backForwardList->currentItem()) + url = m_backForwardList->currentItem()->url(); + + if (!url.isEmpty()) { auto transaction = m_pageLoadState.transaction(); m_pageLoadState.setPendingAPIRequestURL(transaction, url); @@ -736,82 +1176,101 @@ void WebPageProxy::reload(bool reloadFromOrigin) m_process->willAcquireUniversalFileReadSandboxExtension(); } - if (!isValid()) { - reattachToWebProcessWithItem(m_backForwardList->currentItem()); + if (!isValid()) + return reattachToWebProcessForReload(); + + auto navigation = m_navigationState->createReloadNavigation(); + + m_process->send(Messages::WebPage::Reload(navigation->navigationID(), reloadFromOrigin, contentBlockersEnabled, sandboxExtensionHandle), m_pageID); + m_process->responsivenessTimer().start(); + + return WTFMove(navigation); +} + +void WebPageProxy::recordAutomaticNavigationSnapshot() +{ + if (m_suppressAutomaticNavigationSnapshotting) return; - } - m_process->send(Messages::WebPage::Reload(reloadFromOrigin, sandboxExtensionHandle), m_pageID); - m_process->responsivenessTimer()->start(); + if (WebBackForwardListItem* item = m_backForwardList->currentItem()) + recordNavigationSnapshot(*item); } -void WebPageProxy::recordNavigationSnapshot() +void WebPageProxy::recordNavigationSnapshot(WebBackForwardListItem& item) { if (!m_shouldRecordNavigationSnapshots) return; -#if PLATFORM(MAC) && !PLATFORM(IOS) - ViewSnapshotStore::shared().recordSnapshot(*this); +#if PLATFORM(COCOA) + ViewSnapshotStore::singleton().recordSnapshot(*this, item); +#else + UNUSED_PARAM(item); #endif } -void WebPageProxy::goForward() +RefPtr<API::Navigation> WebPageProxy::goForward() { WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem(); if (!forwardItem) - return; - - recordNavigationSnapshot(); + return nullptr; auto transaction = m_pageLoadState.transaction(); m_pageLoadState.setPendingAPIRequestURL(transaction, forwardItem->url()); - if (!isValid()) { - reattachToWebProcessWithItem(forwardItem); - return; - } + if (!isValid()) + return reattachToWebProcessWithItem(forwardItem); - m_process->send(Messages::WebPage::GoForward(forwardItem->itemID()), m_pageID); - m_process->responsivenessTimer()->start(); + RefPtr<API::Navigation> navigation; + if (!m_backForwardList->currentItem()->itemIsInSameDocument(*forwardItem)) + navigation = m_navigationState->createBackForwardNavigation(); + + m_process->send(Messages::WebPage::GoForward(navigation ? navigation->navigationID() : 0, forwardItem->itemID()), m_pageID); + m_process->responsivenessTimer().start(); + + return navigation; } -void WebPageProxy::goBack() +RefPtr<API::Navigation> WebPageProxy::goBack() { WebBackForwardListItem* backItem = m_backForwardList->backItem(); if (!backItem) - return; - - recordNavigationSnapshot(); + return nullptr; auto transaction = m_pageLoadState.transaction(); m_pageLoadState.setPendingAPIRequestURL(transaction, backItem->url()); - if (!isValid()) { - reattachToWebProcessWithItem(backItem); - return; - } + if (!isValid()) + return reattachToWebProcessWithItem(backItem); + + RefPtr<API::Navigation> navigation; + if (!m_backForwardList->currentItem()->itemIsInSameDocument(*backItem)) + navigation = m_navigationState->createBackForwardNavigation(); + + m_process->send(Messages::WebPage::GoBack(navigation ? navigation->navigationID() : 0, backItem->itemID()), m_pageID); + m_process->responsivenessTimer().start(); - m_process->send(Messages::WebPage::GoBack(backItem->itemID()), m_pageID); - m_process->responsivenessTimer()->start(); + return navigation; } -void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item) +RefPtr<API::Navigation> WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item) { - if (!isValid()) { - reattachToWebProcessWithItem(item); - return; - } + if (!isValid()) + return reattachToWebProcessWithItem(item); - recordNavigationSnapshot(); - auto transaction = m_pageLoadState.transaction(); m_pageLoadState.setPendingAPIRequestURL(transaction, item->url()); - m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID); - m_process->responsivenessTimer()->start(); + RefPtr<API::Navigation> navigation; + if (!m_backForwardList->currentItem()->itemIsInSameDocument(*item)) + navigation = m_navigationState->createBackForwardNavigation(); + + m_process->send(Messages::WebPage::GoToBackForwardItem(navigation ? navigation->navigationID() : 0, item->itemID()), m_pageID); + m_process->responsivenessTimer().start(); + + return navigation; } void WebPageProxy::tryRestoreScrollPosition() @@ -822,20 +1281,31 @@ void WebPageProxy::tryRestoreScrollPosition() m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID); } -void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<API::Object>>* removed) +void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<WebBackForwardListItem>> removed) { - m_loaderClient->didChangeBackForwardList(this, added, removed); + PageClientProtector protector(m_pageClient); + + m_loaderClient->didChangeBackForwardList(*this, added, WTFMove(removed)); + + auto transaction = m_pageLoadState.transaction(); + + m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem()); + m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem()); } -void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder& decoder) +void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID)) - m_loaderClient->willGoToBackForwardListItem(this, item, userData.get()); + m_loaderClient->willGoToBackForwardListItem(*this, item, m_process->transformHandlesToObjects(userData.object()).get()); +} + +bool WebPageProxy::shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem* item) +{ + PageClientProtector protector(m_pageClient); + + return m_loaderClient->shouldKeepCurrentBackForwardListItemInList(*this, item); } bool WebPageProxy::canShowMIMEType(const String& mimeType) @@ -845,20 +1315,56 @@ bool WebPageProxy::canShowMIMEType(const String& mimeType) #if ENABLE(NETSCAPE_PLUGIN_API) String newMimeType = mimeType; - PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL()); - if (!plugin.path.isNull() && m_pageGroup->preferences()->pluginsEnabled()) + PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL()); + if (!plugin.path.isNull() && m_preferences->pluginsEnabled()) return true; #endif // ENABLE(NETSCAPE_PLUGIN_API) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // On Mac, we can show PDFs. - if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebContext::omitPDFSupport()) + if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType) && !WebProcessPool::omitPDFSupport()) return true; -#endif // PLATFORM(MAC) +#endif // PLATFORM(COCOA) return false; } +void WebPageProxy::setControlledByAutomation(bool controlled) +{ + if (m_controlledByAutomation == controlled) + return; + + m_controlledByAutomation = controlled; + + if (isValid()) + m_process->send(Messages::WebPage::SetControlledByAutomation(controlled), m_pageID); +} + +#if ENABLE(REMOTE_INSPECTOR) +void WebPageProxy::setAllowsRemoteInspection(bool allow) +{ + if (m_allowsRemoteInspection == allow) + return; + + m_allowsRemoteInspection = allow; + + if (isValid()) + m_process->send(Messages::WebPage::SetAllowsRemoteInspection(allow), m_pageID); +} + +void WebPageProxy::setRemoteInspectionNameOverride(const String& name) +{ + if (m_remoteInspectionNameOverride == name) + return; + + m_remoteInspectionNameOverride = name; + + if (isValid()) + m_process->send(Messages::WebPage::SetRemoteInspectionNameOverride(m_remoteInspectionNameOverride), m_pageID); +} + +#endif + void WebPageProxy::setDrawsBackground(bool drawsBackground) { if (m_drawsBackground == drawsBackground) @@ -870,15 +1376,23 @@ void WebPageProxy::setDrawsBackground(bool drawsBackground) m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID); } -void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground) +void WebPageProxy::setTopContentInset(float contentInset) { - if (m_drawsTransparentBackground == drawsTransparentBackground) + if (m_topContentInset == contentInset) return; - m_drawsTransparentBackground = drawsTransparentBackground; + m_topContentInset = contentInset; - if (isValid()) - m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID); + if (!isValid()) + return; +#if HAVE(COREANIMATION_FENCES) + MachSendRight fence = m_drawingArea->createFence(); + + auto fenceAttachment = IPC::Attachment(fence.leakSendRight(), MACH_MSG_TYPE_MOVE_SEND); + m_process->send(Messages::WebPage::SetTopContentInsetFenced(contentInset, fenceAttachment), m_pageID); +#else + m_process->send(Messages::WebPage::SetTopContentInset(contentInset), m_pageID); +#endif } void WebPageProxy::setUnderlayColor(const Color& color) @@ -896,7 +1410,7 @@ void WebPageProxy::viewWillStartLiveResize() { if (!isValid()) return; -#if ENABLE(INPUT_TYPE_COLOR_POPOVER) +#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR) if (m_colorPicker) endColorPicker(); #endif @@ -910,102 +1424,269 @@ void WebPageProxy::viewWillEndLiveResize() m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID); } -void WebPageProxy::setViewNeedsDisplay(const IntRect& rect) +void WebPageProxy::setViewNeedsDisplay(const Region& region) { - m_pageClient.setViewNeedsDisplay(rect); + m_pageClient.setViewNeedsDisplay(region); } -void WebPageProxy::displayView() +void WebPageProxy::requestScroll(const FloatPoint& scrollPosition, const IntPoint& scrollOrigin, bool isProgrammaticScroll) { - m_pageClient.displayView(); + m_pageClient.requestScroll(scrollPosition, scrollOrigin, isProgrammaticScroll); } -bool WebPageProxy::canScrollView() +void WebPageProxy::setSuppressVisibilityUpdates(bool flag) { - return m_pageClient.canScrollView(); + if (m_suppressVisibilityUpdates == flag) + return; + m_suppressVisibilityUpdates = flag; + + if (!m_suppressVisibilityUpdates) { +#if PLATFORM(COCOA) + m_activityStateChangeDispatcher->schedule(); +#else + dispatchActivityStateChange(); +#endif + } +} + +void WebPageProxy::updateActivityState(ActivityState::Flags flagsToUpdate) +{ + m_activityState &= ~flagsToUpdate; + if (flagsToUpdate & ActivityState::IsFocused && m_pageClient.isViewFocused()) + m_activityState |= ActivityState::IsFocused; + if (flagsToUpdate & ActivityState::WindowIsActive && m_pageClient.isViewWindowActive()) + m_activityState |= ActivityState::WindowIsActive; + if (flagsToUpdate & ActivityState::IsVisible && m_pageClient.isViewVisible()) + m_activityState |= ActivityState::IsVisible; + if (flagsToUpdate & ActivityState::IsVisibleOrOccluded && m_pageClient.isViewVisibleOrOccluded()) + m_activityState |= ActivityState::IsVisibleOrOccluded; + if (flagsToUpdate & ActivityState::IsInWindow && m_pageClient.isViewInWindow()) + m_activityState |= ActivityState::IsInWindow; + if (flagsToUpdate & ActivityState::IsVisuallyIdle && m_pageClient.isVisuallyIdle()) + m_activityState |= ActivityState::IsVisuallyIdle; + if (flagsToUpdate & ActivityState::IsAudible && m_mediaState & MediaProducer::IsPlayingAudio && !(m_mutedState & MediaProducer::AudioIsMuted)) + m_activityState |= ActivityState::IsAudible; + if (flagsToUpdate & ActivityState::IsLoading && m_pageLoadState.isLoading()) + m_activityState |= ActivityState::IsLoading; +} + +void WebPageProxy::activityStateDidChange(ActivityState::Flags mayHaveChanged, bool wantsSynchronousReply, ActivityStateChangeDispatchMode dispatchMode) +{ + m_potentiallyChangedActivityStateFlags |= mayHaveChanged; + m_activityStateChangeWantsSynchronousReply = m_activityStateChangeWantsSynchronousReply || wantsSynchronousReply; + + if (m_suppressVisibilityUpdates && dispatchMode != ActivityStateChangeDispatchMode::Immediate) + return; + +#if PLATFORM(COCOA) + bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ActivityState::IsInWindow) && m_pageClient.isViewInWindow(); + if (dispatchMode == ActivityStateChangeDispatchMode::Immediate || isNewlyInWindow) { + dispatchActivityStateChange(); + return; + } + m_activityStateChangeDispatcher->schedule(); +#else + UNUSED_PARAM(dispatchMode); + dispatchActivityStateChange(); +#endif } -void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) +void WebPageProxy::viewDidLeaveWindow() { - m_pageClient.scrollView(scrollRect, scrollOffset); +#if ENABLE(INPUT_TYPE_COLOR_POPOVER) && ENABLE(INPUT_TYPE_COLOR) + // When leaving the current page, close the popover color well. + if (m_colorPicker) + endColorPicker(); +#endif +#if PLATFORM(IOS) && HAVE(AVKIT) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + // When leaving the current page, close the video fullscreen. + if (m_videoFullscreenManager) + m_videoFullscreenManager->requestHideAndExitFullscreen(); +#endif } -void WebPageProxy::updateViewState(ViewState::Flags flagsToUpdate) +void WebPageProxy::viewDidEnterWindow() { - m_viewState &= ~flagsToUpdate; - if (flagsToUpdate & ViewState::IsFocused && m_pageClient.isViewFocused()) - m_viewState |= ViewState::IsFocused; - if (flagsToUpdate & ViewState::WindowIsActive && m_pageClient.isViewWindowActive()) - m_viewState |= ViewState::WindowIsActive; - if (flagsToUpdate & ViewState::IsVisible && m_pageClient.isViewVisible()) - m_viewState |= ViewState::IsVisible; - if (flagsToUpdate & ViewState::IsInWindow && m_pageClient.isViewInWindow()) - m_viewState |= ViewState::IsInWindow; - if (flagsToUpdate & ViewState::IsVisuallyIdle && m_pageClient.isVisuallyIdle()) - m_viewState |= ViewState::IsVisuallyIdle; + LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode(); + if (m_layerHostingMode != layerHostingMode) { + m_layerHostingMode = layerHostingMode; + m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID); + } } -void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, WantsReplyOrNot wantsReply) +void WebPageProxy::reloadAfterBeingKilledInBackground() { - if (!isValid()) + ASSERT(!isValid()); + + RELEASE_LOG_IF_ALLOWED("%p - Reloading tab that was killed in the background", this); + + // Only report as a crash if the page was ever visible, otherwise silently reload. + if (m_hasEverBeenVisible) + processDidCrash(); + else + reattachToWebProcessForReload(); +} + +void WebPageProxy::dispatchActivityStateChange() +{ +#if PLATFORM(COCOA) + m_activityStateChangeDispatcher->invalidate(); +#endif + + if (!isValid()) { + if (m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible && m_wasKilledForBeingUnresponsiveWhileInBackground) + reloadAfterBeingKilledInBackground(); return; + } - // If the visibility state may have changed, then so may the visually idle. - if (mayHaveChanged & ViewState::IsVisible) - mayHaveChanged |= ViewState::IsVisuallyIdle; + // If the visibility state may have changed, then so may the visually idle & occluded agnostic state. + if (m_potentiallyChangedActivityStateFlags & ActivityState::IsVisible) + m_potentiallyChangedActivityStateFlags |= ActivityState::IsVisibleOrOccluded | ActivityState::IsVisuallyIdle; // Record the prior view state, update the flags that may have changed, // and check which flags have actually changed. - ViewState::Flags previousViewState = m_viewState; - updateViewState(mayHaveChanged); - ViewState::Flags changed = m_viewState ^ previousViewState; - - if (changed) - m_process->send(Messages::WebPage::SetViewState(m_viewState, wantsReply == WantsReplyOrNot::DoesWantReply), m_pageID); - - if (changed & ViewState::IsVisuallyIdle) - m_process->pageSuppressibilityChanged(this); - - // If we've started the responsiveness timer as part of telling the web process to update the backing store - // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we - // stop the unresponsiveness timer here. - if ((changed & ViewState::IsVisible) && !isViewVisible()) - m_process->responsivenessTimer()->stop(); - - if ((mayHaveChanged & ViewState::IsInWindow) && (m_viewState & ViewState::IsInWindow)) { - LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode(); - if (m_layerHostingMode != layerHostingMode) { - m_layerHostingMode = layerHostingMode; - m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID); + ActivityState::Flags previousActivityState = m_activityState; + updateActivityState(m_potentiallyChangedActivityStateFlags); + ActivityState::Flags changed = m_activityState ^ previousActivityState; + + bool isNowInWindow = (changed & ActivityState::IsInWindow) && isInWindow(); + // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window. + if (m_viewWasEverInWindow && isNowInWindow) { + if (m_drawingArea->hasVisibleContent() && m_waitsForPaintAfterViewDidMoveToWindow && !m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow) + m_activityStateChangeWantsSynchronousReply = true; + m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow = false; + } + + // Don't wait synchronously if the view state is not visible. (This matters in particular on iOS, where a hidden page may be suspended.) + if (!(m_activityState & ActivityState::IsVisible)) + m_activityStateChangeWantsSynchronousReply = false; + + if (changed || m_activityStateChangeWantsSynchronousReply || !m_nextActivityStateChangeCallbacks.isEmpty()) + m_process->send(Messages::WebPage::SetActivityState(m_activityState, m_activityStateChangeWantsSynchronousReply, m_nextActivityStateChangeCallbacks), m_pageID); + + m_nextActivityStateChangeCallbacks.clear(); + + // This must happen after the SetActivityState message is sent, to ensure the page visibility event can fire. + updateThrottleState(); + +#if ENABLE(POINTER_LOCK) + if (((changed & ActivityState::IsVisible) && !isViewVisible()) || ((changed & ActivityState::WindowIsActive) && !m_pageClient.isViewWindowActive()) + || ((changed & ActivityState::IsFocused) && !(m_activityState & ActivityState::IsFocused))) + requestPointerUnlock(); +#endif + + if (changed & ActivityState::IsVisible) { + if (isViewVisible()) { + m_hasEverBeenVisible = true; + m_visiblePageToken = m_process->visiblePageToken(); + } else { + m_visiblePageToken = nullptr; + + // If we've started the responsiveness timer as part of telling the web process to update the backing store + // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we + // stop the unresponsiveness timer here. + m_process->responsivenessTimer().stop(); } } -#if ENABLE(INPUT_TYPE_COLOR_POPOVER) - if ((mayHaveChanged & ViewState::IsInWindow) && !(m_viewState & ViewState::IsInWindow)) { - // When leaving the current page, close the popover color well. - if (m_colorPicker) - endColorPicker(); + if (changed & ActivityState::IsInWindow) { + if (isInWindow()) + viewDidEnterWindow(); + else + viewDidLeaveWindow(); } -#endif updateBackingStoreDiscardableState(); + + if (m_activityStateChangeWantsSynchronousReply) + waitForDidUpdateActivityState(); + + m_potentiallyChangedActivityStateFlags = ActivityState::NoFlags; + m_activityStateChangeWantsSynchronousReply = false; + m_viewWasEverInWindow |= isNowInWindow; } -void WebPageProxy::waitForDidUpdateViewState() +bool WebPageProxy::isAlwaysOnLoggingAllowed() const { - // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding. - if (m_waitingForDidUpdateViewState) + return sessionID().isAlwaysOnLoggingAllowed(); +} + +void WebPageProxy::updateThrottleState() +{ + bool processSuppressionEnabled = m_preferences->pageVisibilityBasedProcessSuppressionEnabled(); + + // If process suppression is not enabled take a token on the process pool to disable suppression of support processes. + if (!processSuppressionEnabled) + m_preventProcessSuppressionCount = m_process->processPool().processSuppressionDisabledForPageCount(); + else if (!m_preventProcessSuppressionCount) + m_preventProcessSuppressionCount = nullptr; + + if (m_activityState & ActivityState::IsVisuallyIdle) + m_pageIsUserObservableCount = nullptr; + else if (!m_pageIsUserObservableCount) + m_pageIsUserObservableCount = m_process->processPool().userObservablePageCount(); + +#if PLATFORM(IOS) + if (!isViewVisible() && !m_alwaysRunsAtForegroundPriority) { + if (m_activityToken) { + RELEASE_LOG_IF_ALLOWED("%p - UIProcess is releasing a foreground assertion because the view is no longer visible", this); + m_activityToken = nullptr; + } + } else if (!m_activityToken) { + if (isViewVisible()) + RELEASE_LOG_IF_ALLOWED("%p - UIProcess is taking a foreground assertion because the view is visible", this); + else + RELEASE_LOG_IF_ALLOWED("%p - UIProcess is taking a foreground assertion even though the view is not visible because m_alwaysRunsAtForegroundPriority is true", this); + m_activityToken = m_process->throttler().foregroundActivityToken(); + } +#endif +} + +void WebPageProxy::updateHiddenPageThrottlingAutoIncreases() +{ + if (!m_preferences->hiddenPageDOMTimerThrottlingAutoIncreases()) + m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = nullptr; + else if (!m_hiddenPageDOMTimerThrottlingAutoIncreasesCount) + m_hiddenPageDOMTimerThrottlingAutoIncreasesCount = m_process->processPool().hiddenPageThrottlingAutoIncreasesCount(); +} + +void WebPageProxy::layerHostingModeDidChange() +{ + if (!isValid()) return; + LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode(); + if (m_layerHostingMode == layerHostingMode) + return; + + m_layerHostingMode = layerHostingMode; + m_process->send(Messages::WebPage::SetLayerHostingMode(layerHostingMode), m_pageID); +} + +void WebPageProxy::waitForDidUpdateActivityState() +{ if (!isValid()) return; - m_waitingForDidUpdateViewState = true; + if (m_process->state() != WebProcessProxy::State::Running) + return; + + // If we have previously timed out with no response from the WebProcess, don't block the UIProcess again until it starts responding. + if (m_waitingForDidUpdateActivityState) + return; - if (!m_process->isLaunching()) { - auto viewStateUpdateTimeout = std::chrono::milliseconds(250); - m_process->connection()->waitForAndDispatchImmediately<Messages::WebPageProxy::DidUpdateViewState>(m_pageID, viewStateUpdateTimeout); +#if PLATFORM(IOS) + // Hail Mary check. Should not be possible (dispatchActivityStateChange should force async if not visible, + // and if visible we should be holding an assertion) - but we should never block on a suspended process. + if (!m_activityToken) { + ASSERT_NOT_REACHED(); + return; } +#endif + + m_waitingForDidUpdateActivityState = true; + + m_drawingArea->waitForDidUpdateActivityState(); } IntSize WebPageProxy::viewSize() const @@ -1013,36 +1694,39 @@ IntSize WebPageProxy::viewSize() const return m_pageClient.viewSize(); } -void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent) +void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent, std::function<void (CallbackBase::Error)> callbackFunction) { - if (!isValid()) + if (!isValid()) { + callbackFunction(CallbackBase::Error::OwnerWasInvalidated); return; - m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID); + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent, callbackID), m_pageID); } -void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize) +void WebPageProxy::clearSelection() { if (!isValid()) return; - m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID); + m_process->send(Messages::WebPage::ClearSelection(), m_pageID); } - -void WebPageProxy::clearSelection() + +void WebPageProxy::restoreSelectionInFocusedEditableElement() { if (!isValid()) return; - m_process->send(Messages::WebPage::ClearSelection(), m_pageID); + m_process->send(Messages::WebPage::RestoreSelectionInFocusedEditableElement(), m_pageID); } -void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback) +void WebPageProxy::validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)> callbackFunction) { if (!isValid()) { - callback->invalidate(); + callbackFunction(String(), false, 0, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_validateCommandCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID); } @@ -1051,7 +1735,7 @@ void WebPageProxy::setMaintainsInactiveSelection(bool newValue) m_maintainsInactiveSelection = newValue; } -void WebPageProxy::executeEditCommand(const String& commandName) +void WebPageProxy::executeEditCommand(const String& commandName, const String& argument) { static NeverDestroyed<String> ignoreSpellingCommandName(ASCIILiteral("ignoreSpelling")); @@ -1061,16 +1745,27 @@ void WebPageProxy::executeEditCommand(const String& commandName) if (commandName == ignoreSpellingCommandName) ++m_pendingLearnOrIgnoreWordMessageCount; - m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID); + m_process->send(Messages::WebPage::ExecuteEditCommand(commandName, argument), m_pageID); } - -#if USE(TILED_BACKING_STORE) -void WebPageProxy::commitPageTransitionViewport() + +void WebPageProxy::setEditable(bool editable) { + if (editable == m_isEditable) + return; if (!isValid()) return; - process().send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID); + m_isEditable = editable; + m_process->send(Messages::WebPage::SetEditable(editable), m_pageID); +} + +#if !PLATFORM(IOS) +void WebPageProxy::didCommitLayerTree(const RemoteLayerTreeTransaction&) +{ +} + +void WebPageProxy::layerTreeCommitComplete() +{ } #endif @@ -1096,9 +1791,9 @@ void WebPageProxy::dragExited(DragData& dragData, const String& dragStorageName) performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray); } -void WebPageProxy::performDrag(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload) +void WebPageProxy::performDragOperation(DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload) { - performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload); + performDragControllerAction(DragControllerActionPerformDragOperation, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload); } void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData& dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload) @@ -1106,31 +1801,38 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag if (!isValid()) return; #if PLATFORM(GTK) - String url = dragData.asURL(nullptr); + UNUSED_PARAM(dragStorageName); + UNUSED_PARAM(sandboxExtensionHandle); + UNUSED_PARAM(sandboxExtensionsForUpload); + + String url = dragData.asURL(); if (!url.isEmpty()) m_process->assumeReadAccessToBaseURL(url); - m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData), m_pageID); + + ASSERT(dragData.platformData()); + WebSelectionData selection(*dragData.platformData()); + m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), selection, dragData.flags()), m_pageID); #else - m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), dragStorageName, dragData.flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID); + m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData, sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID); #endif } -void WebPageProxy::didPerformDragControllerAction(WebCore::DragSession dragSession) +void WebPageProxy::didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted) { - m_currentDragSession = dragSession; + MESSAGE_CHECK(dragOperation <= DragOperationDelete); + + m_currentDragOperation = static_cast<DragOperation>(dragOperation); + m_currentDragIsOverFileInput = mouseIsOverFileInput; + m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted; } #if PLATFORM(GTK) -void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle) +void WebPageProxy::startDrag(WebSelectionData&& selection, uint64_t dragOperation, const ShareableBitmap::Handle& dragImageHandle) { - RefPtr<ShareableBitmap> dragImage = 0; - if (!dragImageHandle.isNull()) { - dragImage = ShareableBitmap::create(dragImageHandle); - if (!dragImage) - return; - } + RefPtr<ShareableBitmap> dragImage = !dragImageHandle.isNull() ? ShareableBitmap::create(dragImageHandle) : nullptr; + m_pageClient.startDrag(WTFMove(selection.selectionData), static_cast<WebCore::DragOperation>(dragOperation), WTFMove(dragImage)); - m_pageClient.startDrag(dragData, dragImage.release()); + m_process->send(Messages::WebPage::DidStartDrag(), m_pageID); } #endif @@ -1140,6 +1842,12 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo return; m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID); } + +void WebPageProxy::dragCancelled() +{ + if (isValid()) + m_process->send(Messages::WebPage::DragCancelled(), m_pageID); +} #endif // ENABLE(DRAG_SUPPORT) void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event) @@ -1147,12 +1855,15 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event) if (!isValid()) return; + if (m_pageClient.windowIsFrontWindowUnderMouse(event)) + setToolTip(String()); + // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction. if (event.type() != WebEvent::MouseMove) - m_process->responsivenessTimer()->start(); + m_process->responsivenessTimer().start(); else { if (m_processingMouseMoveEvent) { - m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event)); + m_nextMouseMoveEvent = std::make_unique<NativeWebMouseEvent>(event); return; } @@ -1164,14 +1875,9 @@ void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event) // we fake a mouse up event by using this stored down event. This event gets cleared // when the mouse up message is received from WebProcess. if (event.type() == WebEvent::MouseDown) - m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event)); + m_currentlyProcessedMouseDownEvent = std::make_unique<NativeWebMouseEvent>(event); - if (m_shouldSendEventsSynchronously) { - bool handled = false; - m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID); - didReceiveEvent(event.type(), handled); - } else - m_process->send(Messages::WebPage::MouseEvent(event), m_pageID); + m_process->send(Messages::WebPage::MouseEvent(event), m_pageID); } #if MERGE_WHEEL_EVENTS @@ -1185,7 +1891,7 @@ static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b) return false; if (a.granularity() != b.granularity()) return false; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (a.phase() != b.phase()) return false; if (a.momentumPhase() != b.momentumPhase()) @@ -1204,7 +1910,7 @@ static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b) FloatSize mergedDelta = a.delta() + b.delta(); FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks(); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta(); return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp()); @@ -1248,6 +1954,8 @@ void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event) if (!isValid()) return; + hideValidationMessage(); + if (!m_currentlyProcessedWheelEvents.isEmpty()) { m_wheelEventQueue.append(event); if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold) @@ -1260,40 +1968,35 @@ void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event) return; } - OwnPtr<Vector<NativeWebWheelEvent>> coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>); + auto coalescedWheelEvent = std::make_unique<Vector<NativeWebWheelEvent>>(); coalescedWheelEvent->append(event); - m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release()); + m_currentlyProcessedWheelEvents.append(WTFMove(coalescedWheelEvent)); sendWheelEvent(event); } void WebPageProxy::processNextQueuedWheelEvent() { - OwnPtr<Vector<NativeWebWheelEvent>> nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>); + auto nextCoalescedEvent = std::make_unique<Vector<NativeWebWheelEvent>>(); WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get()); - m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release()); + m_currentlyProcessedWheelEvents.append(WTFMove(nextCoalescedEvent)); sendWheelEvent(nextWheelEvent); } void WebPageProxy::sendWheelEvent(const WebWheelEvent& event) { - m_process->responsivenessTimer()->start(); - - if (m_shouldSendEventsSynchronously) { - bool handled = false; - m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID); - didReceiveEvent(event.type(), handled); - return; - } - m_process->send( Messages::EventDispatcher::WheelEvent( m_pageID, event, - m_useLegacyImplicitRubberBandControl ? !m_backForwardList->backItem() : rubberBandsAtLeft(), - m_useLegacyImplicitRubberBandControl ? !m_backForwardList->forwardItem() : rubberBandsAtRight(), + shouldUseImplicitRubberBandControl() ? !m_backForwardList->backItem() : rubberBandsAtLeft(), + shouldUseImplicitRubberBandControl() ? !m_backForwardList->forwardItem() : rubberBandsAtRight(), rubberBandsAtTop(), rubberBandsAtBottom() ), 0); + + // Manually ping the web process to check for responsiveness since our wheel + // event will dispatch to a non-main thread, which always responds. + m_process->isResponsive(nullptr); } void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event) @@ -1305,25 +2008,37 @@ void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event) m_keyEventQueue.append(event); - m_process->responsivenessTimer()->start(); - if (m_shouldSendEventsSynchronously) { - bool handled = false; - m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID); - didReceiveEvent(event.type(), handled); - } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler. + m_process->responsivenessTimer().start(); + if (m_keyEventQueue.size() == 1) { // Otherwise, sent from DidReceiveEvent message handler. + LOG(KeyHandling, " UI process: sent keyEvent from handleKeyboardEvent"); m_process->send(Messages::WebPage::KeyEvent(event), m_pageID); + } +} + +WebPreferencesStore WebPageProxy::preferencesStore() const +{ + if (m_configurationPreferenceValues.isEmpty()) + return m_preferences->store(); + + WebPreferencesStore store = m_preferences->store(); + for (const auto& preference : m_configurationPreferenceValues) + store.m_values.set(preference.key, preference.value); + + return store; } #if ENABLE(NETSCAPE_PLUGIN_API) void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, uint64_t& pluginProcessToken, String& newMimeType, uint32_t& pluginLoadPolicy, String& unavailabilityDescription) { + PageClientProtector protector(m_pageClient); + MESSAGE_CHECK_URL(urlString); - newMimeType = mimeType.lower(); + newMimeType = mimeType.convertToASCIILowercase(); pluginLoadPolicy = PluginModuleLoadNormally; PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins; - PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes); + PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), urlString), allowedPluginTypes); if (!plugin.path) { pluginProcessToken = 0; return; @@ -1331,9 +2046,12 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons pluginLoadPolicy = PluginInfoStore::defaultLoadPolicyForPlugin(plugin); -#if PLATFORM(MAC) - RefPtr<ImmutableDictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String()); - pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription); +#if PLATFORM(COCOA) + RefPtr<API::Dictionary> pluginInformation = createPluginInformationDictionary(plugin, frameURLString, String(), pageURLString, String(), String()); + if (m_navigationClient) + pluginLoadPolicy = m_navigationClient->decidePolicyForPluginLoad(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription); + else + pluginLoadPolicy = m_loaderClient->pluginLoadPolicy(*this, static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy), pluginInformation.get(), unavailabilityDescription); #else UNUSED_PARAM(frameURLString); UNUSED_PARAM(pageURLString); @@ -1349,34 +2067,178 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons pluginProcessSandboxPolicy = PluginProcessSandboxPolicyUnsandboxed; break; - case PluginModuleBlocked: + case PluginModuleBlockedForSecurity: + case PluginModuleBlockedForCompatibility: pluginProcessToken = 0; return; } - pluginProcessToken = PluginProcessManager::shared().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy); + pluginProcessToken = PluginProcessManager::singleton().pluginProcessToken(plugin, static_cast<PluginProcessType>(processType), pluginProcessSandboxPolicy); } #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(TOUCH_EVENTS) + +static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b) +{ + if (static_cast<uintptr_t>(b) > static_cast<uintptr_t>(a)) + return b; + return a; +} + +void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent) +{ +#if ENABLE(ASYNC_SCROLLING) + const EventNames& names = eventNames(); + for (auto& touchPoint : touchStartEvent.touchPoints()) { + IntPoint location = touchPoint.location(); + auto updateTrackingType = [this, location](TrackingType& trackingType, const AtomicString& eventName) { + if (trackingType == TrackingType::Synchronous) + return; + + TrackingType trackingTypeForLocation = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(eventName, location); + + trackingType = mergeTrackingTypes(trackingType, trackingTypeForLocation); + }; + updateTrackingType(m_touchEventTracking.touchForceChangedTracking, names.touchforcechangeEvent); + updateTrackingType(m_touchEventTracking.touchStartTracking, names.touchstartEvent); + updateTrackingType(m_touchEventTracking.touchMoveTracking, names.touchmoveEvent); + updateTrackingType(m_touchEventTracking.touchEndTracking, names.touchendEvent); + } +#else + UNUSED_PARAM(touchStartEvent); + m_touchEventTracking.touchForceChangedTracking = TrackingType::Synchronous; + m_touchEventTracking.touchStartTracking = TrackingType::Synchronous; + m_touchEventTracking.touchMoveTracking = TrackingType::Synchronous; + m_touchEventTracking.touchEndTracking = TrackingType::Synchronous; +#endif // ENABLE(ASYNC_SCROLLING) +} + +TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const +{ + // We send all events if any type is needed, we just do it asynchronously for the types that are not tracked. + // + // Touch events define a sequence with strong dependencies. For example, we can expect + // a TouchMove to only appear after a TouchStart, and the ids of the touch points is consistent between + // the two. + // + // WebCore should not have to set up its state correctly after some events were dismissed. + // For example, we don't want to send a TouchMoved without a TouchPressed. + // We send everything, WebCore updates its internal state and dispatch what is needed to the page. + TrackingType globalTrackingType = m_touchEventTracking.isTrackingAnything() ? TrackingType::Asynchronous : TrackingType::NotTracking; + + globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchForceChangedTracking); + for (auto& touchPoint : touchStartEvent.touchPoints()) { + switch (touchPoint.state()) { + case WebPlatformTouchPoint::TouchReleased: + globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchEndTracking); + break; + case WebPlatformTouchPoint::TouchPressed: + globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchStartTracking); + break; + case WebPlatformTouchPoint::TouchMoved: + case WebPlatformTouchPoint::TouchStationary: + globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchMoveTracking); + break; + case WebPlatformTouchPoint::TouchCancelled: + globalTrackingType = mergeTrackingTypes(globalTrackingType, TrackingType::Asynchronous); + break; + } + } + + return globalTrackingType; +} + +#endif + +#if ENABLE(MAC_GESTURE_EVENTS) +void WebPageProxy::handleGestureEvent(const NativeWebGestureEvent& event) +{ + if (!isValid()) + return; + + m_gestureEventQueue.append(event); + // FIXME: Consider doing some coalescing here. + m_process->responsivenessTimer().start(); + + m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0); +} +#endif + +#if ENABLE(IOS_TOUCH_EVENTS) +void WebPageProxy::handleTouchEventSynchronously(NativeWebTouchEvent& event) +{ + if (!isValid()) + return; + + if (event.type() == WebEvent::TouchStart) { + updateTouchEventTracking(event); + m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID(); + } + + TrackingType touchEventsTrackingType = touchEventTrackingType(event); + if (touchEventsTrackingType == TrackingType::NotTracking) + return; + + if (touchEventsTrackingType == TrackingType::Asynchronous) { + // We can end up here if a native gesture has not started but the event handlers are passive. + // + // The client of WebPageProxy asks the event to be sent synchronously since the touch event + // can prevent a native gesture. + // But, here we know that all events handlers that can handle this events are passive. + // We can use asynchronous dispatch and pretend to the client that the page does nothing with the events. + event.setCanPreventNativeGestures(false); + handleTouchEventAsynchronously(event); + didReceiveEvent(event.type(), false); + return; + } + + m_process->responsivenessTimer().start(); + bool handled = false; + m_process->sendSync(Messages::WebPage::TouchEventSync(event), Messages::WebPage::TouchEventSync::Reply(handled), m_pageID); + didReceiveEvent(event.type(), handled); + m_pageClient.doneWithTouchEvent(event, handled); + m_process->responsivenessTimer().stop(); + + if (event.allTouchPointsAreReleased()) + m_touchEventTracking.reset(); +} + +void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event) +{ + if (!isValid()) + return; + + TrackingType touchEventsTrackingType = touchEventTrackingType(event); + if (touchEventsTrackingType == TrackingType::NotTracking) + return; + + m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0); + + if (event.allTouchPointsAreReleased()) + m_touchEventTracking.reset(); +} + +#elif ENABLE(TOUCH_EVENTS) void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) { if (!isValid()) return; + if (event.type() == WebEvent::TouchStart) + updateTouchEventTracking(event); + + if (touchEventTrackingType(event) == TrackingType::NotTracking) + return; + // If the page is suspended, which should be the case during panning, pinching // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then // we do not send any of the events to the page even if is has listeners. - if (m_needTouchEvents && !m_isPageSuspended) { + if (!m_isPageSuspended) { m_touchEventQueue.append(event); - m_process->responsivenessTimer()->start(); - if (m_shouldSendEventsSynchronously) { - bool handled = false; - m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID); - didReceiveEvent(event.type(), handled); - } else - m_process->send(Messages::WebPage::TouchEvent(event), m_pageID); + m_process->responsivenessTimer().start(); + m_process->send(Messages::WebPage::TouchEvent(event), m_pageID); } else { if (m_touchEventQueue.isEmpty()) { bool isEventHandled = false; @@ -1388,8 +2250,11 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) lastEvent.deferredTouchEvents.append(event); } } + + if (event.allTouchPointsAreReleased()) + m_touchEventTracking.reset(); } -#endif +#endif // ENABLE(TOUCH_EVENTS) void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity) { @@ -1407,7 +2272,7 @@ void WebPageProxy::centerSelectionInVisibleArea() m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID); } -void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID) +void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy& frame, uint64_t listenerID, API::Navigation* navigation, const WebsitePolicies& websitePolicies) { if (!isValid()) return; @@ -1417,15 +2282,19 @@ void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* fr if (action == PolicyIgnore) m_pageLoadState.clearPendingAPIRequestURL(transaction); - uint64_t downloadID = 0; +#if ENABLE(DOWNLOAD_ATTRIBUTE) + if (m_syncNavigationActionHasDownloadAttribute && action == PolicyUse) + action = PolicyDownload; +#endif + + DownloadID downloadID = { }; if (action == PolicyDownload) { // Create a download proxy. - DownloadProxy* download = m_process->context().createDownloadProxy(); + // FIXME: We should ensure that the downloadRequest is never empty. + const ResourceRequest& downloadRequest = m_decidePolicyForResponseRequest ? *m_decidePolicyForResponseRequest : ResourceRequest(); + DownloadProxy* download = m_process->processPool().createDownloadProxy(downloadRequest); downloadID = download->downloadID(); -#if PLATFORM(EFL) || PLATFORM(GTK) - // Our design does not suppport downloads without a WebPage. handleDownloadRequest(download); -#endif } // If we received a policy decision while in decidePolicyForResponse the decision will @@ -1443,10 +2312,11 @@ void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* fr m_syncNavigationActionPolicyActionIsValid = true; m_syncNavigationActionPolicyAction = action; m_syncNavigationActionPolicyDownloadID = downloadID; + m_syncNavigationActionPolicyWebsitePolicies = websitePolicies; return; } - m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID); + m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame.frameID(), listenerID, action, navigation ? navigation->navigationID() : 0, downloadID), m_pageID); } void WebPageProxy::setUserAgent(const String& userAgent) @@ -1524,7 +2394,7 @@ void WebPageProxy::setCustomTextEncodingName(const String& encodingName) m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID); } -void WebPageProxy::terminateProcess() +void WebPageProxy::terminateProcess(TerminationReason terminationReason) { // NOTE: This uses a check of m_isValid rather than calling isValid() since // we want this to run even for pages being closed or that already closed. @@ -1533,20 +2403,68 @@ void WebPageProxy::terminateProcess() m_process->requestTermination(); resetStateAfterProcessExited(); + m_wasKilledForBeingUnresponsiveWhileInBackground = terminationReason == TerminationReason::UnresponsiveWhileInBackground; } -#if !USE(CF) -PassRefPtr<API::Data> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* /*context*/) const +SessionState WebPageProxy::sessionState(const std::function<bool (WebBackForwardListItem&)>& filter) const { - // FIXME: Return session state data for saving Page state. - return 0; + SessionState sessionState; + + sessionState.backForwardListState = m_backForwardList->backForwardListState(filter); + + String provisionalURLString = m_pageLoadState.pendingAPIRequestURL(); + if (provisionalURLString.isEmpty()) + provisionalURLString = m_pageLoadState.provisionalURL(); + + if (!provisionalURLString.isEmpty()) + sessionState.provisionalURL = URL(URL(), provisionalURLString); + + sessionState.renderTreeSize = renderTreeSize(); + return sessionState; } -void WebPageProxy::restoreFromSessionStateData(API::Data*) +RefPtr<API::Navigation> WebPageProxy::restoreFromSessionState(SessionState sessionState, bool navigate) { - // FIXME: Restore the Page from the passed in session state data. + m_sessionRestorationRenderTreeSize = 0; + m_hitRenderTreeSizeThreshold = false; + + bool hasBackForwardList = !!sessionState.backForwardListState.currentIndex; + + if (hasBackForwardList) { + m_backForwardList->restoreFromState(WTFMove(sessionState.backForwardListState)); + + for (const auto& entry : m_backForwardList->entries()) + process().registerNewWebBackForwardListItem(entry.get()); + + process().send(Messages::WebPage::RestoreSession(m_backForwardList->itemStates()), m_pageID); + + auto transaction = m_pageLoadState.transaction(); + m_pageLoadState.setCanGoBack(transaction, m_backForwardList->backItem()); + m_pageLoadState.setCanGoForward(transaction, m_backForwardList->forwardItem()); + + // The back / forward list was restored from a sessionState so we don't want to snapshot the current + // page when navigating away. Suppress navigation snapshotting until the next load has committed + m_suppressAutomaticNavigationSnapshotting = true; + } + + // FIXME: Navigating should be separate from state restoration. + if (navigate) { + m_sessionRestorationRenderTreeSize = sessionState.renderTreeSize; + if (!m_sessionRestorationRenderTreeSize) + m_hitRenderTreeSizeThreshold = true; // If we didn't get data on renderTreeSize, just don't fire the milestone. + + if (!sessionState.provisionalURL.isNull()) + return loadRequest(sessionState.provisionalURL); + + if (hasBackForwardList) { + // FIXME: Do we have to null check the back forward list item here? + if (WebBackForwardListItem* item = m_backForwardList->currentItem()) + return goToBackForwardItem(item); + } + } + + return nullptr; } -#endif bool WebPageProxy::supportsTextZoom() const { @@ -1577,6 +2495,8 @@ void WebPageProxy::setPageZoomFactor(double zoomFactor) if (m_pageZoomFactor == zoomFactor) return; + hideValidationMessage(); + m_pageZoomFactor = zoomFactor; m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); } @@ -1589,13 +2509,35 @@ void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZ if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor) return; + hideValidationMessage(); + m_pageZoomFactor = pageZoomFactor; m_textZoomFactor = textZoomFactor; m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); } +double WebPageProxy::pageZoomFactor() const +{ + // Zoom factor for non-PDF pages persists across page loads. We maintain a separate member variable for PDF + // zoom which ensures that we don't use the PDF zoom for a normal page. + if (m_mainFramePluginHandlesPageScaleGesture) + return m_pluginZoomFactor; + return m_pageZoomFactor; +} + +double WebPageProxy::pageScaleFactor() const +{ + // PDF documents use zoom and scale factors to size themselves appropriately in the window. We store them + // separately but decide which to return based on the main frame. + if (m_mainFramePluginHandlesPageScaleGesture) + return m_pluginScaleFactor; + return m_pageScaleFactor; +} + void WebPageProxy::scalePage(double scale, const IntPoint& origin) { + ASSERT(scale > 0); + if (!isValid()) return; @@ -1603,6 +2545,28 @@ void WebPageProxy::scalePage(double scale, const IntPoint& origin) m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID); } +void WebPageProxy::scalePageInViewCoordinates(double scale, const IntPoint& centerInViewCoordinates) +{ + ASSERT(scale > 0); + + if (!isValid()) + return; + + m_pageScaleFactor = scale; + m_process->send(Messages::WebPage::ScalePageInViewCoordinates(scale, centerInViewCoordinates), m_pageID); +} + +void WebPageProxy::scaleView(double scale) +{ + ASSERT(scale > 0); + + if (!isValid()) + return; + + m_viewScaleFactor = scale; + m_process->send(Messages::WebPage::ScaleView(scale), m_pageID); +} + void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor) { if (m_intrinsicDeviceScaleFactor == scaleFactor) @@ -1651,6 +2615,14 @@ void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor) m_drawingArea->deviceScaleFactorDidChange(); } +void WebPageProxy::accessibilitySettingsDidChange() +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::AccessibilitySettingsDidChange(), m_pageID); +} + void WebPageProxy::setUseFixedLayout(bool fixed) { if (!isValid()) @@ -1683,17 +2655,14 @@ void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestone { if (!isValid()) return; + + if (milestones == m_observedLayoutMilestones) + return; + m_observedLayoutMilestones = milestones; m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID); } -void WebPageProxy::setVisibilityStatePrerender() -{ - if (!isValid()) - return; - m_process->send(Messages::WebPage::SetVisibilityStatePrerender(), m_pageID); -} - void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations) { if (!isValid()) @@ -1745,6 +2714,40 @@ void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom) { m_rubberBandsAtBottom = rubberBandsAtBottom; } + +void WebPageProxy::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding) +{ + if (enableVerticalRubberBanding == m_enableVerticalRubberBanding) + return; + + m_enableVerticalRubberBanding = enableVerticalRubberBanding; + + if (!isValid()) + return; + m_process->send(Messages::WebPage::SetEnableVerticalRubberBanding(enableVerticalRubberBanding), m_pageID); +} + +bool WebPageProxy::verticalRubberBandingIsEnabled() const +{ + return m_enableVerticalRubberBanding; +} + +void WebPageProxy::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding) +{ + if (enableHorizontalRubberBanding == m_enableHorizontalRubberBanding) + return; + + m_enableHorizontalRubberBanding = enableHorizontalRubberBanding; + + if (!isValid()) + return; + m_process->send(Messages::WebPage::SetEnableHorizontalRubberBanding(enableHorizontalRubberBanding), m_pageID); +} + +bool WebPageProxy::horizontalRubberBandingIsEnabled() const +{ + return m_enableHorizontalRubberBanding; +} void WebPageProxy::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage) { @@ -1811,26 +2814,31 @@ void WebPageProxy::setGapBetweenPages(double gap) m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID); } +void WebPageProxy::setPaginationLineGridEnabled(bool lineGridEnabled) +{ + if (lineGridEnabled == m_paginationLineGridEnabled) + return; + + m_paginationLineGridEnabled = lineGridEnabled; + + if (!isValid()) + return; + m_process->send(Messages::WebPage::SetPaginationLineGridEnabled(lineGridEnabled), m_pageID); +} + void WebPageProxy::pageScaleFactorDidChange(double scaleFactor) { m_pageScaleFactor = scaleFactor; } -void WebPageProxy::pageZoomFactorDidChange(double zoomFactor) +void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor) { - m_pageZoomFactor = zoomFactor; + m_pluginScaleFactor = pluginScaleFactor; } -void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled) +void WebPageProxy::pluginZoomFactorDidChange(double pluginZoomFactor) { - if (!isValid()) - return; - - if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled) - return; - - m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled; - m_process->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID); + m_pluginZoomFactor = pluginZoomFactor; } void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) @@ -1871,137 +2879,154 @@ void WebPageProxy::countStringMatches(const String& string, FindOptions options, m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID); } -void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback) +void WebPageProxy::runJavaScriptInMainFrame(const String& script, std::function<void (API::SerializedScriptValue*, bool hadException, const ExceptionDetails&, CallbackBase::Error)> callbackFunction) { - RefPtr<ScriptValueCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(nullptr, false, { }, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_scriptValueCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID); } -void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback) +void WebPageProxy::getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)> callbackFunction) { - RefPtr<StringCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(String(), CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_stringCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID); } -void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback) +void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, std::function<void (const String&, CallbackBase::Error)> callbackFunction) { - RefPtr<StringCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(String(), CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_loadDependentStringCallbackIDs.add(callbackID); - m_stringCallbacks.set(callbackID, callback.get()); m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID); } -void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback) +void WebPageProxy::getContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction) { - RefPtr<StringCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(String(), CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_loadDependentStringCallbackIDs.add(callbackID); - m_stringCallbacks.set(callbackID, callback.get()); m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID); } +void WebPageProxy::getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(String(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + m_loadDependentStringCallbackIDs.add(callbackID); + m_process->send(Messages::WebPage::GetBytecodeProfile(callbackID), m_pageID); +} + +void WebPageProxy::getSamplingProfilerOutput(std::function<void (const String&, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(String(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + m_loadDependentStringCallbackIDs.add(callbackID); + m_process->send(Messages::WebPage::GetSamplingProfilerOutput(callbackID), m_pageID); +} + +void WebPageProxy::isWebProcessResponsive(std::function<void (bool isWebProcessResponsive)> callbackFunction) +{ + if (!isValid()) { + RunLoop::main().dispatch([callbackFunction = WTFMove(callbackFunction)] { + bool isWebProcessResponsive = true; + callbackFunction(isWebProcessResponsive); + }); + return; + } + + m_process->isResponsive(callbackFunction); +} + #if ENABLE(MHTML) -void WebPageProxy::getContentsAsMHTMLData(PassRefPtr<DataCallback> prpCallback, bool useBinaryEncoding) +void WebPageProxy::getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { - RefPtr<DataCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); - m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID), m_pageID); } #endif -void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback) +void WebPageProxy::getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)> callbackFunction) { - RefPtr<StringCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(String(), CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_stringCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID); } -void WebPageProxy::getSelectionAsWebArchiveData(PassRefPtr<DataCallback> prpCallback) +void WebPageProxy::getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { - RefPtr<DataCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID); } -void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback) +void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { - RefPtr<DataCallback> callback = prpCallback; - if (!isValid()) { - callback->invalidate(); + if (!isValid() || !frame) { + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID); } -void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, PassRefPtr<DataCallback> prpCallback) +void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, API::URL* resourceURL, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { - RefPtr<DataCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID); } -void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback) +void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { - RefPtr<DataCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + callbackFunction(nullptr, CallbackBase::Error::Unknown); return; } - uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID); } @@ -2009,27 +3034,57 @@ void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback) { RefPtr<VoidCallback> callback = prpCallback; if (!isValid()) { - callback->invalidate(); + // FIXME: If the page is invalid we should not call the callback. It'd be better to just return false from forceRepaint. + callback->invalidate(CallbackBase::Error::OwnerWasInvalidated); return; } - uint64_t callbackID = callback->callbackID(); - m_voidCallbacks.set(callbackID, callback.get()); + std::function<void (CallbackBase::Error)> didForceRepaintCallback = [this, callback](CallbackBase::Error error) { + if (error != CallbackBase::Error::None) { + callback->invalidate(error); + return; + } + + if (!isValid()) { + callback->invalidate(CallbackBase::Error::OwnerWasInvalidated); + return; + } + + callAfterNextPresentationUpdate([callback](CallbackBase::Error error) { + if (error != CallbackBase::Error::None) { + callback->invalidate(error); + return; + } + + callback->performCallback(); + }); + }; + + uint64_t callbackID = m_callbacks.put(didForceRepaintCallback, m_process->throttler().backgroundActivityToken()); m_drawingArea->waitForBackingStoreUpdateOnNextPaint(); m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); } +static OptionSet<IPC::SendOption> printingSendOptions(bool isPerformingDOMPrintOperation) +{ + if (isPerformingDOMPrintOperation) + return IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply; + + return { }; +} + void WebPageProxy::preferencesDidChange() { if (!isValid()) return; #if ENABLE(INSPECTOR_SERVER) - if (m_pageGroup->preferences()->developerExtrasEnabled()) + if (m_preferences->developerExtrasEnabled()) inspector()->enableRemoteInspection(); #endif - m_process->pagePreferencesChanged(this); + updateThrottleState(); + updateHiddenPageThrottlingAutoIncreases(); m_pageClient.preferencesDidChange(); @@ -2038,11 +3093,13 @@ void WebPageProxy::preferencesDidChange() // even if nothing changed in UI process, so that overrides get removed. // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox. - m_process->send(Messages::WebPage::PreferencesDidChange(pageGroup().preferences()->store()), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_process->send(Messages::WebPage::PreferencesDidChange(preferencesStore()), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } void WebPageProxy::didCreateMainFrame(uint64_t frameID) { + PageClientProtector protector(m_pageClient); + MESSAGE_CHECK(!m_mainFrame); MESSAGE_CHECK(m_process->canCreateFrame(frameID)); @@ -2054,6 +3111,8 @@ void WebPageProxy::didCreateMainFrame(uint64_t frameID) void WebPageProxy::didCreateSubframe(uint64_t frameID) { + PageClientProtector protector(m_pageClient); + MESSAGE_CHECK(m_mainFrame); MESSAGE_CHECK(m_process->canCreateFrame(frameID)); @@ -2070,69 +3129,103 @@ double WebPageProxy::estimatedProgress() const void WebPageProxy::didStartProgress() { + PageClientProtector protector(m_pageClient); + auto transaction = m_pageLoadState.transaction(); m_pageLoadState.didStartProgress(transaction); m_pageLoadState.commitChanges(); - m_loaderClient->didStartProgress(this); + m_loaderClient->didStartProgress(*this); } void WebPageProxy::didChangeProgress(double value) { + PageClientProtector protector(m_pageClient); + auto transaction = m_pageLoadState.transaction(); m_pageLoadState.didChangeProgress(transaction, value); m_pageLoadState.commitChanges(); - m_loaderClient->didChangeProgress(this); + m_loaderClient->didChangeProgress(*this); } void WebPageProxy::didFinishProgress() { + PageClientProtector protector(m_pageClient); + auto transaction = m_pageLoadState.transaction(); m_pageLoadState.didFinishProgress(transaction); m_pageLoadState.commitChanges(); - m_loaderClient->didFinishProgress(this); + m_loaderClient->didFinishProgress(*this); } -void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, IPC::MessageDecoder& decoder) +void WebPageProxy::setNetworkRequestsInProgress(bool networkRequestsInProgress) { auto transaction = m_pageLoadState.transaction(); + m_pageLoadState.setNetworkRequestsInProgress(transaction, networkRequestsInProgress); +} - m_pageLoadState.clearPendingAPIRequestURL(transaction); +void WebPageProxy::hasInsecureContent(HasInsecureContent& hasInsecureContent) +{ + hasInsecureContent = m_pageLoadState.committedHasInsecureContent() ? HasInsecureContent::Yes : HasInsecureContent::No; +} - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; +void WebPageProxy::didDestroyNavigation(uint64_t navigationID) +{ + PageClientProtector protector(m_pageClient); + + // FIXME: Message check the navigationID. + m_navigationState->didDestroyNavigation(navigationID); +} + +void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData& userData) +{ + PageClientProtector protector(m_pageClient); + + auto transaction = m_pageLoadState.transaction(); + + m_pageLoadState.clearPendingAPIRequestURL(transaction); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); MESSAGE_CHECK_URL(url); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + if (frame->isMainFrame()) { - recordNavigationSnapshot(); m_pageLoadState.didStartProvisionalLoad(transaction, url, unreachableURL); + m_pageClient.didStartProvisionalLoadForMainFrame(); + hideValidationMessage(); } frame->setUnreachableURL(unreachableURL); frame->didStartProvisionalLoad(url); m_pageLoadState.commitChanges(); - m_loaderClient->didStartProvisionalLoadForFrame(this, frame, userData.get()); + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didStartProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didStartProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, IPC::MessageDecoder& decoder) +void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); MESSAGE_CHECK_URL(url); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + auto transaction = m_pageLoadState.transaction(); if (frame->isMainFrame()) @@ -2141,28 +3234,69 @@ void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t f frame->didReceiveServerRedirectForProvisionalLoad(url); m_pageLoadState.commitChanges(); - m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get()); + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didReceiveServerRedirectForProvisionalNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didReceiveServerRedirectForProvisionalLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder) +void WebPageProxy::didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t, const String& url) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); + MESSAGE_CHECK(frame->frameLoadState().state() == FrameLoadState::State::Provisional); + MESSAGE_CHECK_URL(url); auto transaction = m_pageLoadState.transaction(); + // Internally, we handle this the same way we handle a server redirect. There are no client callbacks + // for this, but if this is the main frame, clients may observe a change to the page's URL. if (frame->isMainFrame()) + m_pageLoadState.didReceiveServerRedirectForProvisionalLoad(transaction, url); + + frame->didReceiveServerRedirectForProvisionalLoad(url); +} + +void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const ResourceError& error, const UserData& userData) +{ + PageClientProtector protector(m_pageClient); + + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = navigationState().takeNavigation(navigationID); + + auto transaction = m_pageLoadState.transaction(); + + if (frame->isMainFrame()) { m_pageLoadState.didFailProvisionalLoad(transaction); + m_pageClient.didFailProvisionalLoadForMainFrame(); + } frame->didFailProvisionalLoad(); m_pageLoadState.commitChanges(); - m_loaderClient->didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get()); + + ASSERT(!m_failingProvisionalLoadURL); + m_failingProvisionalLoadURL = provisionalURL; + + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didFailProvisionalNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get()); + else { + // FIXME: Get the main frame's current navigation. + m_navigationClient->didFailProvisionalLoadInSubframeWithError(*this, *frame, frameSecurityOrigin, nullptr, error, m_process->transformHandlesToObjects(userData.object()).get()); + } + } else + m_loaderClient->didFailProvisionalLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get()); + + m_failingProvisionalLoadURL = { }; } void WebPageProxy::clearLoadDependentCallbacks() @@ -2172,138 +3306,232 @@ void WebPageProxy::clearLoadDependentCallbacks() m_loadDependentStringCallbackIDs.clear(); for (size_t i = 0; i < callbackIDsCopy.size(); ++i) { - RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]); + auto callback = m_callbacks.take<StringCallback>(callbackIDsCopy[i]); if (callback) callback->invalidate(); } } -void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, IPC::MessageDecoder& decoder) +void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t opaqueFrameLoadType, const WebCore::CertificateInfo& certificateInfo, bool containsPluginDocument, std::optional<HasInsecureContent> hasInsecureContent, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - auto transaction = m_pageLoadState.transaction(); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); +#if PLATFORM(IOS) if (frame->isMainFrame()) { - m_pageLoadState.didCommitLoad(transaction); - m_pageClient.didCommitLoadForMainFrame(); + m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = false; + m_firstLayerTreeTransactionIdAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).nextLayerTreeTransactionID(); } +#endif + + auto transaction = m_pageLoadState.transaction(); + Ref<WebCertificateInfo> webCertificateInfo = WebCertificateInfo::create(certificateInfo); + bool markPageInsecure = hasInsecureContent ? hasInsecureContent.value() == HasInsecureContent::Yes : m_treatsSHA1CertificatesAsInsecure && certificateInfo.containsNonRootSHA1SignedCertificate(); + + if (frame->isMainFrame()) { + m_pageLoadState.didCommitLoad(transaction, webCertificateInfo, markPageInsecure); + m_suppressAutomaticNavigationSnapshotting = false; + } else if (markPageInsecure) + m_pageLoadState.didDisplayOrRunInsecureContent(transaction); #if USE(APPKIT) // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields. // FIXME: A load going on in one frame shouldn't affect text editing in other frames on the page. m_pageClient.resetSecureInputState(); - dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); - m_pageClient.dismissDictionaryLookupPanel(); + m_pageClient.dismissContentRelativeChildWindows(); #endif clearLoadDependentCallbacks(); - frame->didCommitLoad(mimeType, certificateInfo); + frame->didCommitLoad(mimeType, webCertificateInfo, containsPluginDocument); + + if (frame->isMainFrame()) { + m_mainFrameHasCustomContentProvider = frameHasCustomContentProvider; + + if (m_mainFrameHasCustomContentProvider) { + // Always assume that the main frame is pinned here, since the custom representation view will handle + // any wheel events and dispatch them to the WKView when necessary. + m_mainFrameIsPinnedToLeftSide = true; + m_mainFrameIsPinnedToRightSide = true; + m_mainFrameIsPinnedToTopSide = true; + m_mainFrameIsPinnedToBottomSide = true; + + m_uiClient->pinnedStateDidChange(*this); + } + m_pageClient.didCommitLoadForMainFrame(mimeType, frameHasCustomContentProvider); + } // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it), // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a // plugin is handling page scaling itself) so we should reset it to the default // for standard main frame loads. - if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadTypeStandard) - m_pageScaleFactor = 1; + if (frame->isMainFrame()) { + if (static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadType::Standard) { + m_pageScaleFactor = 1; + m_pluginScaleFactor = 1; + m_mainFramePluginHandlesPageScaleGesture = false; + } + } + +#if ENABLE(POINTER_LOCK) + if (frame->isMainFrame()) + requestPointerUnlock(); +#endif m_pageLoadState.commitChanges(); - m_loaderClient->didCommitLoadForFrame(this, frame, userData.get()); + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didCommitNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didCommitLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_loaderClient->didFinishDocumentLoadForFrame(this, frame, userData.get()); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didFinishDocumentLoad(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didFinishDocumentLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + auto transaction = m_pageLoadState.transaction(); - if (frame->isMainFrame()) + bool isMainFrame = frame->isMainFrame(); + if (isMainFrame) m_pageLoadState.didFinishLoad(transaction); + if (isMainFrame && m_controlledByAutomation) { + if (auto* automationSession = process().processPool().automationSession()) + automationSession->navigationOccurredForPage(*this); + } + frame->didFinishLoad(); m_pageLoadState.commitChanges(); - m_loaderClient->didFinishLoadForFrame(this, frame, userData.get()); + if (m_navigationClient) { + if (isMainFrame) + m_navigationClient->didFinishNavigation(*this, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didFinishLoadForFrame(*this, *frame, navigation.get(), m_process->transformHandlesToObjects(userData.object()).get()); + + if (isMainFrame) + m_pageClient.didFinishLoadForMainFrame(); + + m_isLoadingAlternateHTMLStringForFailingProvisionalLoad = false; } -void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder) +void WebPageProxy::didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const ResourceError& error, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + clearLoadDependentCallbacks(); auto transaction = m_pageLoadState.transaction(); - if (frame->isMainFrame()) + bool isMainFrame = frame->isMainFrame(); + + if (isMainFrame) m_pageLoadState.didFailLoad(transaction); + if (isMainFrame && m_controlledByAutomation) { + if (auto* automationSession = process().processPool().automationSession()) + automationSession->navigationOccurredForPage(*this); + } + frame->didFailLoad(); m_pageLoadState.commitChanges(); - m_loaderClient->didFailLoadWithErrorForFrame(this, frame, error, userData.get()); + if (m_navigationClient) { + if (frame->isMainFrame()) + m_navigationClient->didFailNavigationWithError(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didFailLoadWithErrorForFrame(*this, *frame, navigation.get(), error, m_process->transformHandlesToObjects(userData.object()).get()); + + if (isMainFrame) + m_pageClient.didFailLoadForMainFrame(); } -void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, IPC::MessageDecoder& decoder) +void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t opaqueSameDocumentNavigationType, const String& url, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); MESSAGE_CHECK_URL(url); + // FIXME: We should message check that navigationID is not zero here, but it's currently zero for some navigations through the page cache. + RefPtr<API::Navigation> navigation; + if (frame->isMainFrame() && navigationID) + navigation = &navigationState().navigation(navigationID); + auto transaction = m_pageLoadState.transaction(); - if (frame->isMainFrame()) + bool isMainFrame = frame->isMainFrame(); + if (isMainFrame) m_pageLoadState.didSameDocumentNavigation(transaction, url); + if (isMainFrame && m_controlledByAutomation) { + if (auto* automationSession = process().processPool().automationSession()) + automationSession->navigationOccurredForPage(*this); + } + m_pageLoadState.clearPendingAPIRequestURL(transaction); frame->didSameDocumentNavigation(url); m_pageLoadState.commitChanges(); - m_loaderClient->didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get()); + + SameDocumentNavigationType navigationType = static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType); + if (m_navigationClient) { + if (isMainFrame) + m_navigationClient->didSameDocumentNavigation(*this, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_loaderClient->didSameDocumentNavigationForFrame(*this, *frame, navigation.get(), navigationType, m_process->transformHandlesToObjects(userData.object()).get()); + + if (isMainFrame) + m_pageClient.didSameDocumentNavigationForMainFrame(navigationType); } -void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, IPC::MessageDecoder& decoder) +void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); @@ -2316,64 +3544,50 @@ void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title frame->didChangeTitle(title); m_pageLoadState.commitChanges(); - m_loaderClient->didReceiveTitleForFrame(this, title, frame, userData.get()); + m_loaderClient->didReceiveTitleForFrame(*this, title, *frame, m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_loaderClient->didFirstLayoutForFrame(this, frame, userData.get()); + m_loaderClient->didFirstLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get()); + m_loaderClient->didFirstVisuallyNonEmptyLayoutForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get()); + + if (frame->isMainFrame()) + m_pageClient.didFirstVisuallyNonEmptyLayoutForMainFrame(); } -void WebPageProxy::didLayout(uint32_t layoutMilestones, IPC::MessageDecoder& decoder) +void WebPageProxy::didLayoutForCustomContentProvider() { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; - - m_loaderClient->didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get()); + didReachLayoutMilestone(DidFirstLayout | DidFirstVisuallyNonEmptyLayout | DidHitRelevantRepaintedObjectsAreaThreshold); } -void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didReachLayoutMilestone(uint32_t layoutMilestones) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); - WebFrameProxy* frame = m_process->webFrame(frameID); - MESSAGE_CHECK(frame); - - m_loaderClient->didRemoveFrameFromHierarchy(this, frame, userData.get()); + if (m_navigationClient) + m_navigationClient->renderingProgressDidChange(*this, static_cast<LayoutMilestones>(layoutMilestones)); + else + m_loaderClient->didReachLayoutMilestone(*this, static_cast<LayoutMilestones>(layoutMilestones)); } -void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); @@ -2382,15 +3596,12 @@ void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, IPC::Mess m_pageLoadState.didDisplayOrRunInsecureContent(transaction); m_pageLoadState.commitChanges(); - m_loaderClient->didDisplayInsecureContentForFrame(this, frame, userData.get()); + m_loaderClient->didDisplayInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); @@ -2399,24 +3610,28 @@ void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageD m_pageLoadState.didDisplayOrRunInsecureContent(transaction); m_pageLoadState.commitChanges(); - m_loaderClient->didRunInsecureContentForFrame(this, frame, userData.get()); + m_loaderClient->didRunInsecureContentForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder& decoder) +void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_loaderClient->didDetectXSSForFrame(this, frame, userData.get()); + m_loaderClient->didDetectXSSForFrame(*this, *frame, m_process->transformHandlesToObjects(userData.object()).get()); +} + +void WebPageProxy::mainFramePluginHandlesPageScaleGestureDidChange(bool mainFramePluginHandlesPageScaleGesture) +{ + m_mainFramePluginHandlesPageScaleGesture = mainFramePluginHandlesPageScaleGesture; } void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value) { + PageClientProtector protector(m_pageClient); + WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); @@ -2425,12 +3640,9 @@ void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value) m_frameSetLargestFrame = value ? m_mainFrame : 0; } -void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID) +void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData& navigationActionData, uint64_t originatingFrameID, const SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const ResourceRequest& request, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, DownloadID& downloadID, WebsitePolicies& websitePolicies) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); auto transaction = m_pageLoadState.transaction(); @@ -2444,15 +3656,51 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Navig WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameID); - RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); + Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); + if (!navigationID && frame->isMainFrame()) { + auto navigation = m_navigationState->createLoadRequestNavigation(request); + newNavigationID = navigation->navigationID(); + listener->setNavigation(WTFMove(navigation)); + } + +#if ENABLE(CONTENT_FILTERING) + if (frame->didHandleContentFilterUnblockNavigation(request)) { + receivedPolicyAction = true; + policyAction = PolicyIgnore; + return; + } +#endif ASSERT(!m_inDecidePolicyForNavigationAction); m_inDecidePolicyForNavigationAction = true; m_syncNavigationActionPolicyActionIsValid = false; +#if ENABLE(DOWNLOAD_ATTRIBUTE) + m_syncNavigationActionHasDownloadAttribute = !navigationActionData.downloadAttribute.isNull(); +#endif + + if (m_navigationClient) { + RefPtr<API::FrameInfo> destinationFrameInfo; + RefPtr<API::FrameInfo> sourceFrameInfo; - m_policyClient->decidePolicyForNavigationAction(this, frame, navigationActionData, originatingFrame, originalRequest, request, listener.get(), userData.get()); + if (frame) + destinationFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()); + if (originatingFrame == frame) + sourceFrameInfo = destinationFrameInfo; + else if (originatingFrame) + sourceFrameInfo = API::FrameInfo::create(*originatingFrame, originatingFrameSecurityOrigin.securityOrigin()); + + auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier); + bool shouldOpenAppLinks = !m_shouldSuppressAppLinksInNextNavigationPolicyDecision && (!destinationFrameInfo || destinationFrameInfo->isMainFrame()) && !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url()) && navigationActionData.navigationType != WebCore::NavigationType::BackForward; + + auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), destinationFrameInfo.get(), request, originalRequest.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity)); + + m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_policyClient->decidePolicyForNavigationAction(*this, frame, navigationActionData, originatingFrame, originalRequest, request, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); + + m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false; m_inDecidePolicyForNavigationAction = false; // Check if we received a policy decision already. If we did, we can just pass it back. @@ -2460,51 +3708,64 @@ void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, const Navig if (m_syncNavigationActionPolicyActionIsValid) { policyAction = m_syncNavigationActionPolicyAction; downloadID = m_syncNavigationActionPolicyDownloadID; + websitePolicies = m_syncNavigationActionPolicyWebsitePolicies; } } -void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, IPC::MessageDecoder& decoder) +void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const NavigationActionData& navigationActionData, const ResourceRequest& request, const String& frameName, uint64_t listenerID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); MESSAGE_CHECK_URL(request.url()); - RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); + Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); - m_policyClient->decidePolicyForNewWindowAction(this, frame, navigationActionData.navigationType, navigationActionData.modifiers, navigationActionData.mouseButton, request, frameName, listener.get(), userData.get()); + if (m_navigationClient) { + RefPtr<API::FrameInfo> sourceFrameInfo; + if (frame) + sourceFrameInfo = API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()); + + auto userInitiatedActivity = m_process->userInitiatedActivity(navigationActionData.userGestureTokenIdentifier); + bool shouldOpenAppLinks = !hostsAreEqual(URL(ParsedURLString, m_mainFrame->url()), request.url()); + auto navigationAction = API::NavigationAction::create(navigationActionData, sourceFrameInfo.get(), nullptr, request, request.url(), shouldOpenAppLinks, WTFMove(userInitiatedActivity)); + + m_navigationClient->decidePolicyForNavigationAction(*this, navigationAction.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); + + } else + m_policyClient->decidePolicyForNewWindowAction(*this, *frame, navigationActionData, request, frameName, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder) +void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + PageClientProtector protector(m_pageClient); WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); MESSAGE_CHECK_URL(request.url()); MESSAGE_CHECK_URL(response.url()); - RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); + Ref<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID); - m_policyClient->decidePolicyForResponse(this, frame, response, request, canShowMIMEType, listener.get(), userData.get()); + if (m_navigationClient) { + auto navigationResponse = API::NavigationResponse::create(API::FrameInfo::create(*frame, frameSecurityOrigin.securityOrigin()).get(), request, response, canShowMIMEType); + m_navigationClient->decidePolicyForNavigationResponse(*this, navigationResponse.get(), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); + } else + m_policyClient->decidePolicyForResponse(*this, *frame, response, request, canShowMIMEType, WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID) +void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const ResourceResponse& response, const ResourceRequest& request, bool canShowMIMEType, uint64_t listenerID, const UserData& userData, bool& receivedPolicyAction, uint64_t& policyAction, DownloadID& downloadID) { + PageClientProtector protector(m_pageClient); + ASSERT(!m_inDecidePolicyForResponseSync); m_inDecidePolicyForResponseSync = true; m_decidePolicyForResponseRequest = &request; m_syncMimeTypePolicyActionIsValid = false; - decidePolicyForResponse(frameID, response, request, canShowMIMEType, listenerID, decoder); + decidePolicyForResponse(frameID, frameSecurityOrigin, response, request, canShowMIMEType, listenerID, userData); m_inDecidePolicyForResponseSync = false; m_decidePolicyForResponseRequest = 0; @@ -2517,44 +3778,118 @@ void WebPageProxy::decidePolicyForResponseSync(uint64_t frameID, const ResourceR } } -void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, IPC::MessageDecoder& decoder) +void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; - + PageClientProtector protector(m_pageClient); + WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_policyClient->unableToImplementPolicy(this, frame, error, userData.get()); + m_policyClient->unableToImplementPolicy(*this, *frame, error, m_process->transformHandlesToObjects(userData.object()).get()); } // FormClient -void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder& decoder) +void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; - WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID); MESSAGE_CHECK(sourceFrame); - RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID); - if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get())) - listener->continueSubmission(); + Ref<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID); + m_formClient->willSubmitForm(*this, *frame, *sourceFrame, textFieldValues, m_process->transformHandlesToObjects(userData.object()).get(), listener.get()); +} + +void WebPageProxy::didNavigateWithNavigationData(const WebNavigationDataStore& store, uint64_t frameID) +{ + PageClientProtector protector(m_pageClient); + + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + MESSAGE_CHECK(frame->page() == this); + + if (m_historyClient) { + if (frame->isMainFrame()) + m_historyClient->didNavigateWithNavigationData(*this, store); + } else + m_loaderClient->didNavigateWithNavigationData(*this, store, *frame); + process().processPool().historyClient().didNavigateWithNavigationData(process().processPool(), *this, store, *frame); +} + +void WebPageProxy::didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID) +{ + PageClientProtector protector(m_pageClient); + + if (sourceURLString.isEmpty() || destinationURLString.isEmpty()) + return; + + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + MESSAGE_CHECK(frame->page() == this); + + MESSAGE_CHECK_URL(sourceURLString); + MESSAGE_CHECK_URL(destinationURLString); + + if (m_historyClient) { + if (frame->isMainFrame()) + m_historyClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString); + } else + m_loaderClient->didPerformClientRedirect(*this, sourceURLString, destinationURLString, *frame); + process().processPool().historyClient().didPerformClientRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame); +} + +void WebPageProxy::didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID) +{ + PageClientProtector protector(m_pageClient); + + if (sourceURLString.isEmpty() || destinationURLString.isEmpty()) + return; + + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + MESSAGE_CHECK(frame->page() == this); + + MESSAGE_CHECK_URL(sourceURLString); + MESSAGE_CHECK_URL(destinationURLString); + + if (m_historyClient) { + if (frame->isMainFrame()) + m_historyClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString); + } else + m_loaderClient->didPerformServerRedirect(*this, sourceURLString, destinationURLString, *frame); + process().processPool().historyClient().didPerformServerRedirect(process().processPool(), *this, sourceURLString, destinationURLString, *frame); +} + +void WebPageProxy::didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID) +{ + PageClientProtector protector(m_pageClient); + + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + MESSAGE_CHECK(frame->page() == this); + + MESSAGE_CHECK_URL(url); + + if (m_historyClient) { + if (frame->isMainFrame()) + m_historyClient->didUpdateHistoryTitle(*this, title, url); + } else + m_loaderClient->didUpdateHistoryTitle(*this, title, url, *frame); + process().processPool().historyClient().didUpdateHistoryTitle(process().processPool(), *this, title, url, *frame); } // UIClient -void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters) +void WebPageProxy::createNewPage(uint64_t frameID, const SecurityOriginData& securityOriginData, const ResourceRequest& request, const WindowFeatures& windowFeatures, const NavigationActionData& navigationActionData, uint64_t& newPageID, WebPageCreationParameters& newPageParameters) { - RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, request, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton)); + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + + auto mainFrameURL = m_mainFrame->url(); + + RefPtr<WebPageProxy> newPage = m_uiClient->createNewPage(this, frame, securityOriginData, request, windowFeatures, navigationActionData); if (!newPage) { newPageID = 0; return; @@ -2562,93 +3897,107 @@ void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFea newPageID = newPage->pageID(); newPageParameters = newPage->creationParameters(); - process().context().storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID()); + + WebsiteDataStore::cloneSessionData(*this, *newPage); + newPage->m_shouldSuppressAppLinksInNextNavigationPolicyDecision = hostsAreEqual(URL(ParsedURLString, mainFrameURL), request.url()); } void WebPageProxy::showPage() { - m_uiClient.showPage(this); + m_uiClient->showPage(this); +} + +void WebPageProxy::fullscreenMayReturnToInline() +{ + m_uiClient->fullscreenMayReturnToInline(this); +} + +void WebPageProxy::didEnterFullscreen() +{ + m_uiClient->didEnterFullscreen(this); +} + +void WebPageProxy::didExitFullscreen() +{ + m_uiClient->didExitFullscreen(this); } void WebPageProxy::closePage(bool stopResponsivenessTimer) { if (stopResponsivenessTimer) - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); m_pageClient.clearAllEditCommands(); - m_uiClient.close(this); + m_uiClient->close(this); } -void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message) +void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply>&& reply) { WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); - m_uiClient.runJavaScriptAlert(this, message, frame); + m_uiClient->runJavaScriptAlert(this, message, frame, securityOrigin, [reply = WTFMove(reply)] { + reply->send(); + }); } -void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result) +void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, Ref<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply>&& reply) { WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); - result = m_uiClient.runJavaScriptConfirm(this, message, frame); + m_uiClient->runJavaScriptConfirm(this, message, frame, securityOrigin, [reply = WTFMove(reply)](bool result) { + reply->send(result); + }); } -void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result) +void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const SecurityOriginData& securityOrigin, const String& message, const String& defaultValue, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply> reply) { WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); - - result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame); -} - -void WebPageProxy::shouldInterruptJavaScript(bool& result) -{ - // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); - result = m_uiClient.shouldInterruptJavaScript(this); + m_uiClient->runJavaScriptPrompt(this, message, defaultValue, frame, securityOrigin, [reply](const String& result) { reply->send(result); }); } void WebPageProxy::setStatusText(const String& text) { - m_uiClient.setStatusText(this, text); + m_uiClient->setStatusText(this, text); } -void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, IPC::MessageDecoder& decoder) +void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResultData& hitTestResultData, uint32_t opaqueModifiers, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; + m_lastMouseMoveHitTestResult = API::HitTestResult::create(hitTestResultData); WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers); - m_uiClient.mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get()); + m_uiClient->mouseDidMoveOverElement(this, hitTestResultData, modifiers, m_process->transformHandlesToObjects(userData.object()).get()); } -void WebPageProxy::connectionWillOpen(IPC::Connection* connection) +void WebPageProxy::connectionWillOpen(IPC::Connection& connection) { - ASSERT(connection == m_process->connection()); + ASSERT(&connection == m_process->connection()); - m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection); + m_webProcessLifetimeTracker.connectionWillOpen(connection); } -void WebPageProxy::connectionWillClose(IPC::Connection* connection) +void WebPageProxy::webProcessWillShutDown() { - ASSERT_UNUSED(connection, connection == m_process->connection()); + m_webProcessLifetimeTracker.webProcessWillShutDown(); +} - m_process->context().storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0); +void WebPageProxy::processDidFinishLaunching() +{ + ASSERT(m_process->state() == WebProcessProxy::State::Running); + finishInitializingWebPageAfterProcessLaunch(); } #if ENABLE(NETSCAPE_PLUGIN_API) @@ -2659,9 +4008,9 @@ void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailab MESSAGE_CHECK_URL(frameURLString); MESSAGE_CHECK_URL(pageURLString); - RefPtr<ImmutableDictionary> pluginInformation; + RefPtr<API::Dictionary> pluginInformation; String newMimeType = mimeType; - PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString)); + PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString)); pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, pluginspageAttributeURLString, pluginURLString); WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing; @@ -2679,105 +4028,104 @@ void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailab ASSERT_NOT_REACHED(); } - m_uiClient.unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get()); + m_uiClient->unavailablePluginButtonClicked(this, pluginUnavailabilityReason, pluginInformation.get()); } #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(WEBGL) void WebPageProxy::webGLPolicyForURL(const String& url, uint32_t& loadPolicy) { - loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(this, url)); + loadPolicy = static_cast<uint32_t>(m_loaderClient->webGLLoadPolicy(*this, url)); +} + +void WebPageProxy::resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy) +{ + loadPolicy = static_cast<uint32_t>(m_loaderClient->resolveWebGLLoadPolicy(*this, url)); } #endif // ENABLE(WEBGL) void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible) { - m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible); + m_uiClient->setToolbarsAreVisible(this, toolbarsAreVisible); } void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible) { - toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this); + toolbarsAreVisible = m_uiClient->toolbarsAreVisible(this); } void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible) { - m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible); + m_uiClient->setMenuBarIsVisible(this, menuBarIsVisible); } void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible) { - menuBarIsVisible = m_uiClient.menuBarIsVisible(this); + menuBarIsVisible = m_uiClient->menuBarIsVisible(this); } void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible) { - m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible); + m_uiClient->setStatusBarIsVisible(this, statusBarIsVisible); } void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible) { - statusBarIsVisible = m_uiClient.statusBarIsVisible(this); + statusBarIsVisible = m_uiClient->statusBarIsVisible(this); } void WebPageProxy::setIsResizable(bool isResizable) { - m_uiClient.setIsResizable(this, isResizable); + m_uiClient->setIsResizable(this, isResizable); } void WebPageProxy::getIsResizable(bool& isResizable) { - isResizable = m_uiClient.isResizable(this); + isResizable = m_uiClient->isResizable(this); } void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame) { - m_uiClient.setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame)); + m_uiClient->setWindowFrame(this, m_pageClient.convertToDeviceSpace(newWindowFrame)); } void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame) { - newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient.windowFrame(this)); + newWindowFrame = m_pageClient.convertToUserSpace(m_uiClient->windowFrame(this)); } -void WebPageProxy::screenToWindow(const IntPoint& screenPoint, IntPoint& windowPoint) +void WebPageProxy::screenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint) { - windowPoint = m_pageClient.screenToWindow(screenPoint); + windowPoint = m_pageClient.screenToRootView(screenPoint); } -void WebPageProxy::windowToScreen(const IntRect& viewRect, IntRect& result) +void WebPageProxy::rootViewToScreen(const IntRect& viewRect, IntRect& result) { - result = m_pageClient.windowToScreen(viewRect); + result = m_pageClient.rootViewToScreen(viewRect); } -void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose) +#if PLATFORM(IOS) +void WebPageProxy::accessibilityScreenToRootView(const IntPoint& screenPoint, IntPoint& windowPoint) { - WebFrameProxy* frame = m_process->webFrame(frameID); - MESSAGE_CHECK(frame); - - // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); - - shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame); + windowPoint = m_pageClient.accessibilityScreenToRootView(screenPoint); } -#if USE(TILED_BACKING_STORE) -void WebPageProxy::pageDidRequestScroll(const IntPoint& point) +void WebPageProxy::rootViewToAccessibilityScreen(const IntRect& viewRect, IntRect& result) { - m_pageClient.pageDidRequestScroll(point); + result = m_pageClient.rootViewToAccessibilityScreen(viewRect); } +#endif -void WebPageProxy::pageTransitionViewportReady() +void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply> reply) { - m_pageClient.pageTransitionViewportReady(); -} + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); -void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect) -{ - m_pageClient.didRenderFrame(contentsSize, coveredRect); -} + // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer. + m_process->responsivenessTimer().stop(); -#endif + m_uiClient->runBeforeUnloadConfirmPanel(this, message, frame, [reply](bool result) { reply->send(result); }); +} void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr) { @@ -2786,30 +4134,37 @@ void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr) void WebPageProxy::pageDidScroll() { - m_uiClient.pageDidScroll(this); -#if !PLATFORM(IOS) && PLATFORM(MAC) - dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); + m_uiClient->pageDidScroll(this); + +#if PLATFORM(IOS) + // Do not hide the validation message if the scrolling was caused by the keyboard showing up. + if (m_isKeyboardAnimatingIn) + return; #endif + hideValidationMessage(); } -void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings) +void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings) { if (m_openPanelResultListener) { m_openPanelResultListener->invalidate(); - m_openPanelResultListener = 0; + m_openPanelResultListener = nullptr; } WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings); + Ref<API::OpenPanelParameters> parameters = API::OpenPanelParameters::create(settings); m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this); // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); - if (!m_uiClient.runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get())) - didCancelForOpenPanel(); + + if (!m_uiClient->runOpenPanel(this, frame, frameSecurityOrigin, parameters.ptr(), m_openPanelResultListener.get())) { + if (!m_pageClient.handleRunOpenPanel(this, frame, parameters.ptr(), m_openPanelResultListener.get())) + didCancelForOpenPanel(); + } } void WebPageProxy::printFrame(uint64_t frameID) @@ -2820,7 +4175,7 @@ void WebPageProxy::printFrame(uint64_t frameID) WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); - m_uiClient.printFrame(this, frame); + m_uiClient->printFrame(this, frame); endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true. m_isPerformingDOMPrintOperation = false; @@ -2844,6 +4199,39 @@ void WebPageProxy::setMediaVolume(float volume) m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID); } +void WebPageProxy::setMuted(WebCore::MediaProducer::MutedStateFlags state) +{ + if (m_mutedState == state) + return; + + m_mutedState = state; + + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetMuted(state), m_pageID); + + activityStateDidChange(ActivityState::IsAudible); +} + +#if ENABLE(MEDIA_SESSION) +void WebPageProxy::handleMediaEvent(MediaEventType eventType) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::HandleMediaEvent(eventType), m_pageID); +} + +void WebPageProxy::setVolumeOfMediaElement(double volume, uint64_t elementID) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetVolumeOfMediaElement(volume, elementID), m_pageID); +} +#endif + void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia) { if (mayStartMedia == m_mayStartMediaWhenInWindow) @@ -2857,26 +4245,15 @@ void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia) process().send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID); } -#if PLATFORM(EFL) || PLATFORM(GTK) void WebPageProxy::handleDownloadRequest(DownloadProxy* download) { m_pageClient.handleDownloadRequest(download); } -#endif // PLATFORM(EFL) || PLATFORM(GTK) -#if PLATFORM(EFL) || PLATFORM(IOS) void WebPageProxy::didChangeContentSize(const IntSize& size) { m_pageClient.didChangeContentSize(size); } -#endif - -#if ENABLE(TOUCH_EVENTS) -void WebPageProxy::needTouchEvents(bool needTouchEvents) -{ - m_needTouchEvents = needTouchEvents; -} -#endif #if ENABLE(INPUT_TYPE_COLOR) void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const IntRect& elementRect) @@ -2884,7 +4261,7 @@ void WebPageProxy::showColorPicker(const WebCore::Color& initialColor, const Int #if ENABLE(INPUT_TYPE_COLOR_POPOVER) // A new popover color well needs to be created (and the previous one destroyed) for // each activation of a color element. - m_colorPicker = 0; + m_colorPicker = nullptr; #endif if (!m_colorPicker) m_colorPicker = m_pageClient.createColorPicker(this, initialColor, elementRect); @@ -2918,40 +4295,80 @@ void WebPageProxy::didEndColorPicker() if (!isValid()) return; +#if ENABLE(INPUT_TYPE_COLOR) if (m_colorPicker) { m_colorPicker->invalidate(); m_colorPicker = nullptr; } +#endif m_process->send(Messages::WebPage::DidEndColorPicker(), m_pageID); } #endif -void WebPageProxy::didDraw() -{ - m_uiClient.didDraw(this); -} - // Inspector - -#if ENABLE(INSPECTOR) - -WebInspectorProxy* WebPageProxy::inspector() +WebInspectorProxy* WebPageProxy::inspector() const { if (isClosed() || !isValid()) return 0; return m_inspector.get(); } -#endif - #if ENABLE(FULLSCREEN_API) WebFullScreenManagerProxy* WebPageProxy::fullScreenManager() { return m_fullScreenManager.get(); } + +void WebPageProxy::setFullscreenClient(std::unique_ptr<API::FullscreenClient> client) +{ + m_fullscreenClient = WTFMove(client); +} +#endif + +#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) +WebPlaybackSessionManagerProxy* WebPageProxy::playbackSessionManager() +{ + return m_playbackSessionManager.get(); +} + +WebVideoFullscreenManagerProxy* WebPageProxy::videoFullscreenManager() +{ + return m_videoFullscreenManager.get(); +} +#endif + +#if PLATFORM(IOS) +bool WebPageProxy::allowsMediaDocumentInlinePlayback() const +{ + return m_allowsMediaDocumentInlinePlayback; +} + +void WebPageProxy::setAllowsMediaDocumentInlinePlayback(bool allows) +{ + if (m_allowsMediaDocumentInlinePlayback == allows) + return; + m_allowsMediaDocumentInlinePlayback = allows; + + m_process->send(Messages::WebPage::SetAllowsMediaDocumentInlinePlayback(allows), m_pageID); +} #endif +void WebPageProxy::setHasHadSelectionChangesFromUserInteraction(bool hasHadUserSelectionChanges) +{ + m_hasHadSelectionChangesFromUserInteraction = hasHadUserSelectionChanges; +} + +void WebPageProxy::setNeedsHiddenContentEditableQuirk(bool needsHiddenContentEditableQuirk) +{ + m_needsHiddenContentEditableQuirk = needsHiddenContentEditableQuirk; +} + +void WebPageProxy::setNeedsPlainTextQuirk(bool needsPlainTextQuirk) +{ + m_needsPlainTextQuirk = needsPlainTextQuirk; +} + // BackForwardList void WebPageProxy::backForwardAddItem(uint64_t itemID) @@ -2987,40 +4404,10 @@ void WebPageProxy::backForwardForwardListCount(int32_t& count) count = m_backForwardList->forwardListCount(); } -void WebPageProxy::editorStateChanged(const EditorState& editorState) +void WebPageProxy::compositionWasCanceled() { -#if PLATFORM(MAC) - bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone; - bool closedComposition = !editorState.shouldIgnoreCompositionSelectionChange && !editorState.hasComposition && (m_editorState.hasComposition || m_temporarilyClosedComposition); - m_temporarilyClosedComposition = editorState.shouldIgnoreCompositionSelectionChange && (m_temporarilyClosedComposition || m_editorState.hasComposition) && !editorState.hasComposition; -#endif - - m_editorState = editorState; - -#if PLATFORM(MAC) - // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood). - if (couldChangeSecureInputState && !editorState.selectionIsNone) - m_pageClient.updateSecureInputState(); - - if (editorState.shouldIgnoreCompositionSelectionChange) - return; - - if (closedComposition) - m_pageClient.notifyInputContextAboutDiscardedComposition(); - if (editorState.hasComposition) { - // Abandon the current inline input session if selection changed for any other reason but an input method changing the composition. - // FIXME: This logic should be in WebCore, no need to round-trip to UI process to cancel the composition. - cancelComposition(); - m_pageClient.notifyInputContextAboutDiscardedComposition(); - } -#if PLATFORM(IOS) - else { - // We need to notify the client on iOS to make sure the selection is redrawn. - notifyRevealedSelection(); - } -#endif -#elif PLATFORM(EFL) || PLATFORM(GTK) - m_pageClient.updateTextInputState(); +#if PLATFORM(COCOA) + m_pageClient.notifyInputContextAboutDiscardedComposition(); #endif } @@ -3030,6 +4417,13 @@ void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editA { registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo); } + +void WebPageProxy::registerInsertionUndoGrouping() +{ +#if USE(INSERTION_UNDO_GROUPING) + m_pageClient.registerInsertionUndoGrouping(); +#endif +} void WebPageProxy::canUndoRedo(uint32_t action, bool& result) { @@ -3049,51 +4443,65 @@ void WebPageProxy::clearAllEditCommands() void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount) { - m_findClient.didCountStringMatches(this, string, matchCount); + m_findClient->didCountStringMatches(this, string, matchCount); } void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex) { - m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex); + auto bitmap = ShareableBitmap::create(contentImageHandle); + if (!bitmap) { + ASSERT_NOT_REACHED(); + return; + } + m_findMatchesClient->didGetImageForMatchResult(this, WebImage::create(bitmap.releaseNonNull()).ptr(), matchIndex); } -void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate) +void WebPageProxy::setTextIndicator(const TextIndicatorData& indicatorData, uint64_t lifetime) { - RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle); - m_pageClient.setFindIndicator(findIndicator.release(), fadeOut, animate); + // FIXME: Make TextIndicatorWindow a platform-independent presentational thing ("TextIndicatorPresentation"?). +#if PLATFORM(COCOA) + m_pageClient.setTextIndicator(TextIndicator::create(indicatorData), static_cast<TextIndicatorWindowLifetime>(lifetime)); +#else + ASSERT_NOT_REACHED(); +#endif } -void WebPageProxy::didFindString(const String& string, uint32_t matchCount) +void WebPageProxy::clearTextIndicator() { - m_findClient.didFindString(this, string, matchCount); +#if PLATFORM(COCOA) + m_pageClient.clearTextIndicator(TextIndicatorWindowDismissalAnimation::FadeOut); +#else + ASSERT_NOT_REACHED(); +#endif } -void WebPageProxy::didFindStringMatches(const String& string, Vector<Vector<WebCore::IntRect>> matchRects, int32_t firstIndexAfterSelection) +void WebPageProxy::setTextIndicatorAnimationProgress(float progress) { - Vector<RefPtr<API::Object>> matches; - matches.reserveInitialCapacity(matchRects.size()); - - for (const auto& rects : matchRects) { - Vector<RefPtr<API::Object>> apiRects; - apiRects.reserveInitialCapacity(rects.size()); - - for (const auto& rect : rects) - apiRects.uncheckedAppend(API::Rect::create(toAPI(rect))); +#if PLATFORM(COCOA) + m_pageClient.setTextIndicatorAnimationProgress(progress); +#else + ASSERT_NOT_REACHED(); +#endif +} - matches.uncheckedAppend(API::Array::create(std::move(apiRects))); - } +void WebPageProxy::didFindString(const String& string, const Vector<WebCore::IntRect>& matchRects, uint32_t matchCount, int32_t matchIndex) +{ + m_findClient->didFindString(this, string, matchRects, matchCount, matchIndex); +} - m_findMatchesClient.didFindStringMatches(this, string, API::Array::create(std::move(matches)).get(), firstIndexAfterSelection); +void WebPageProxy::didFindStringMatches(const String& string, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection) +{ + m_findMatchesClient->didFindStringMatches(this, string, matchRects, firstIndexAfterSelection); } void WebPageProxy::didFailToFindString(const String& string) { - m_findClient.didFailToFindString(this, string); + m_findClient->didFailToFindString(this, string); } -bool WebPageProxy::sendMessage(std::unique_ptr<IPC::MessageEncoder> encoder, unsigned messageSendFlags) +bool WebPageProxy::sendMessage(std::unique_ptr<IPC::Encoder> encoder, OptionSet<IPC::SendOption> sendOptions) { - return m_process->sendMessage(std::move(encoder), messageSendFlags); + return m_process->sendMessage(WTFMove(encoder), sendOptions); } IPC::Connection* WebPageProxy::messageSenderConnection() @@ -3123,7 +4531,7 @@ NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent() void WebPageProxy::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody) { - process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody, process())), m_pageID); + process().send(Messages::WebPage::PostInjectedBundleMessage(messageName, UserData(process().transformObjectsToHandles(messageBody).get())), m_pageID); } #if PLATFORM(GTK) @@ -3136,36 +4544,22 @@ void WebPageProxy::failedToShowPopupMenu() void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data) { if (m_activePopupMenu) { -#if PLATFORM(EFL) - m_uiPopupMenuClient.hidePopupMenu(this); -#else m_activePopupMenu->hidePopupMenu(); -#endif m_activePopupMenu->invalidate(); - m_activePopupMenu = 0; + m_activePopupMenu = nullptr; } - m_activePopupMenu = m_pageClient.createPopupMenuProxy(this); + m_activePopupMenu = m_pageClient.createPopupMenuProxy(*this); if (!m_activePopupMenu) return; // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); - -#if PLATFORM(EFL) - UNUSED_PARAM(data); - m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex); -#else - RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu; - - protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex); + m_process->responsivenessTimer().stop(); - // Since Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid. - // FIXME: The above comment doesn't make any sense since this code is compiled out for EFL. - protectedActivePopupMenu->invalidate(); - protectedActivePopupMenu = 0; -#endif + // Showing a popup menu runs a nested runloop, which can handle messages that cause |this| to get closed. + Ref<WebPageProxy> protect(*this); + m_activePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex); } void WebPageProxy::hidePopupMenu() @@ -3173,65 +4567,46 @@ void WebPageProxy::hidePopupMenu() if (!m_activePopupMenu) return; -#if PLATFORM(EFL) - m_uiPopupMenuClient.hidePopupMenu(this); -#else m_activePopupMenu->hidePopupMenu(); -#endif m_activePopupMenu->invalidate(); - m_activePopupMenu = 0; + m_activePopupMenu = nullptr; } #if ENABLE(CONTEXT_MENUS) -void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder) +void WebPageProxy::showContextMenu(const ContextMenuContextData& contextMenuContextData, const UserData& userData) { - internalShowContextMenu(menuLocation, hitTestResultData, proposedItems, decoder); + // Showing a context menu runs a nested runloop, which can handle messages that cause |this| to get closed. + Ref<WebPageProxy> protect(*this); + + internalShowContextMenu(contextMenuContextData, userData); // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again. m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID); } -void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, IPC::MessageDecoder& decoder) +void WebPageProxy::internalShowContextMenu(const ContextMenuContextData& contextMenuContextData, const UserData& userData) { - RefPtr<API::Object> userData; - WebContextUserMessageDecoder messageDecoder(userData, process()); - if (!decoder.decode(messageDecoder)) - return; - - m_activeContextMenuHitTestResultData = hitTestResultData; - - if (!m_contextMenuClient.hideContextMenu(this) && m_activeContextMenu) { - m_activeContextMenu->hideContextMenu(); - m_activeContextMenu = 0; - } + m_activeContextMenuContextData = contextMenuContextData; - m_activeContextMenu = m_pageClient.createContextMenuProxy(this); + m_activeContextMenu = m_pageClient.createContextMenuProxy(*this, contextMenuContextData, userData); if (!m_activeContextMenu) return; // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); - - // Give the PageContextMenuClient one last swipe at changing the menu. - Vector<WebContextMenuItemData> items; - if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, hitTestResultData, userData.get())) { - if (!m_contextMenuClient.showContextMenu(this, menuLocation, proposedItems)) - m_activeContextMenu->showContextMenu(menuLocation, proposedItems); - } else if (!m_contextMenuClient.showContextMenu(this, menuLocation, items)) - m_activeContextMenu->showContextMenu(menuLocation, items); - - m_contextMenuClient.contextMenuDismissed(this); + m_process->responsivenessTimer().stop(); + + m_activeContextMenu->show(); } void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item) { // Application custom items don't need to round-trip through to WebCore in the WebProcess. if (item.action() >= ContextMenuItemBaseApplicationTag) { - m_contextMenuClient.customContextMenuItemSelected(this, item); + m_contextMenuClient->customContextMenuItemSelected(*this, item); return; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (item.action() == ContextMenuItemTagSmartCopyPaste) { setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled()); return; @@ -3267,15 +4642,16 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item) } #endif if (item.action() == ContextMenuItemTagDownloadImageToDisk) { - m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteImageURL)); + m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteImageURL)); return; } if (item.action() == ContextMenuItemTagDownloadLinkToDisk) { - m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteLinkURL)); + auto& hitTestResult = m_activeContextMenuContextData.webHitTestResultData(); + m_process->processPool().download(this, URL(URL(), hitTestResult.absoluteLinkURL), hitTestResult.linkSuggestedFilename); return; } if (item.action() == ContextMenuItemTagDownloadMediaToDisk) { - m_process->context().download(this, URL(URL(), m_activeContextMenuHitTestResultData.absoluteMediaURL)); + m_process->processPool().download(this, URL(URL(), m_activeContextMenuContextData.webHitTestResultData().absoluteMediaURL)); return; } if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) { @@ -3299,14 +4675,20 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item) m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID); } + +void WebPageProxy::handleContextMenuKeyEvent() +{ + m_process->send(Messages::WebPage::ContextMenuForKeyEvent(), m_pageID); +} #endif // ENABLE(CONTEXT_MENUS) -void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs) +#if PLATFORM(IOS) +void WebPageProxy::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& fileURLs, const String& displayString, const API::Data* iconData) { if (!isValid()) return; -#if ENABLE(WEB_PROCESS_SANDBOX) +#if ENABLE(SANDBOX_EXTENSIONS) // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This // is gated on a way of passing SandboxExtension::Handles in a Vector. for (size_t i = 0; i < fileURLs.size(); ++i) { @@ -3316,10 +4698,38 @@ void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs) } #endif + m_process->send(Messages::WebPage::DidChooseFilesForOpenPanelWithDisplayStringAndIcon(fileURLs, displayString, iconData ? iconData->dataReference() : IPC::DataReference()), m_pageID); + + m_openPanelResultListener->invalidate(); + m_openPanelResultListener = nullptr; +} +#endif + +void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs) +{ + if (!isValid()) + return; + +#if ENABLE(SANDBOX_EXTENSIONS) + // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This + // is gated on a way of passing SandboxExtension::Handles in a Vector. + for (size_t i = 0; i < fileURLs.size(); ++i) { + SandboxExtension::Handle sandboxExtensionHandle; + bool createdExtension = SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle); + if (!createdExtension) { + // This can legitimately fail if a directory containing the file is deleted after the file was chosen. + // We also have reports of cases where this likely fails for some unknown reason, <rdar://problem/10156710>. + WTFLogAlways("WebPageProxy::didChooseFilesForOpenPanel: could not create a sandbox extension for '%s'\n", fileURLs[i].utf8().data()); + continue; + } + m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID); + } +#endif + m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID); m_openPanelResultListener->invalidate(); - m_openPanelResultListener = 0; + m_openPanelResultListener = nullptr; } void WebPageProxy::didCancelForOpenPanel() @@ -3330,7 +4740,7 @@ void WebPageProxy::didCancelForOpenPanel() m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID); m_openPanelResultListener->invalidate(); - m_openPanelResultListener = 0; + m_openPanelResultListener = nullptr; } void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection) @@ -3381,20 +4791,20 @@ int64_t WebPageProxy::spellDocumentTag() } #if USE(UNIFIED_TEXT_CHECKING) -void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results) +void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, int32_t insertionPoint, Vector<TextCheckingResult>& results) { - results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.deprecatedCharacters(), text.length(), checkingTypes); + results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text, insertionPoint, checkingTypes, m_initialCapitalizationEnabled); } #endif void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength) { - TextChecker::checkSpellingOfString(spellDocumentTag(), text.deprecatedCharacters(), text.length(), misspellingLocation, misspellingLength); + TextChecker::checkSpellingOfString(spellDocumentTag(), text, misspellingLocation, misspellingLength); } void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength) { - TextChecker::checkGrammarOfString(spellDocumentTag(), text.deprecatedCharacters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength); + TextChecker::checkGrammarOfString(spellDocumentTag(), text, grammarDetails, badGrammarLocation, badGrammarLength); } void WebPageProxy::spellingUIIsShowing(bool& isShowing) @@ -3412,9 +4822,9 @@ void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhr TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail); } -void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) +void WebPageProxy::getGuessesForWord(const String& word, const String& context, int32_t insertionPoint, Vector<String>& guesses) { - TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses); + TextChecker::getGuessesForWord(spellDocumentTag(), word, context, insertionPoint, guesses, m_initialCapitalizationEnabled); } void WebPageProxy::learnWord(const String& word) @@ -3433,9 +4843,9 @@ void WebPageProxy::ignoreWord(const String& word) TextChecker::ignoreWord(spellDocumentTag(), word); } -void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request) +void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request, int32_t insertionPoint) { - TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this)); + TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this), insertionPoint); } void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result) @@ -3452,14 +4862,14 @@ void WebPageProxy::didCancelCheckingText(uint64_t requestID) void WebPageProxy::setFocus(bool focused) { if (focused) - m_uiClient.focus(this); + m_uiClient->focus(this); else - m_uiClient.unfocus(this); + m_uiClient->unfocus(this); } void WebPageProxy::takeFocus(uint32_t direction) { - m_uiClient.takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward); + m_uiClient->takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward); } void WebPageProxy::setToolTip(const String& toolTip) @@ -3489,11 +4899,14 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) switch (type) { case WebEvent::NoType: case WebEvent::MouseMove: + case WebEvent::Wheel: break; case WebEvent::MouseDown: case WebEvent::MouseUp: - case WebEvent::Wheel: + case WebEvent::MouseForceChanged: + case WebEvent::MouseForceDown: + case WebEvent::MouseForceUp: case WebEvent::KeyDown: case WebEvent::KeyUp: case WebEvent::RawKeyDown: @@ -3504,7 +4917,12 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) case WebEvent::TouchEnd: case WebEvent::TouchCancel: #endif - m_process->responsivenessTimer()->stop(); +#if ENABLE(MAC_GESTURE_EVENTS) + case WebEvent::GestureStart: + case WebEvent::GestureChange: + case WebEvent::GestureEnd: +#endif + m_process->responsivenessTimer().stop(); break; } @@ -3513,29 +4931,29 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) break; case WebEvent::MouseMove: m_processingMouseMoveEvent = false; - if (m_nextMouseMoveEvent) { - handleMouseEvent(*m_nextMouseMoveEvent); - m_nextMouseMoveEvent = nullptr; - } + if (m_nextMouseMoveEvent) + handleMouseEvent(*std::exchange(m_nextMouseMoveEvent, nullptr)); break; case WebEvent::MouseDown: break; case WebEvent::MouseUp: m_currentlyProcessedMouseDownEvent = nullptr; break; + case WebEvent::MouseForceChanged: + case WebEvent::MouseForceDown: + case WebEvent::MouseForceUp: + break; case WebEvent::Wheel: { MESSAGE_CHECK(!m_currentlyProcessedWheelEvents.isEmpty()); - OwnPtr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst(); + std::unique_ptr<Vector<NativeWebWheelEvent>> oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst(); // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function. if (!handled) { - if (m_uiClient.implementsDidNotHandleWheelEvent()) - m_uiClient.didNotHandleWheelEvent(this, oldestCoalescedEvent->last()); -#if PLATFORM(MAC) + if (m_uiClient->implementsDidNotHandleWheelEvent()) + m_uiClient->didNotHandleWheelEvent(this, oldestCoalescedEvent->last()); m_pageClient.wheelEventWasNotHandledByWebCore(oldestCoalescedEvent->last()); -#endif } if (!m_wheelEventQueue.isEmpty()) @@ -3547,25 +4965,55 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) case WebEvent::KeyUp: case WebEvent::RawKeyDown: case WebEvent::Char: { - LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type)); + LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s (queue empty %d)", webKeyboardEventTypeString(type), m_keyEventQueue.isEmpty()); MESSAGE_CHECK(!m_keyEventQueue.isEmpty()); NativeWebKeyboardEvent event = m_keyEventQueue.takeFirst(); MESSAGE_CHECK(type == event.type()); - if (!m_keyEventQueue.isEmpty()) + if (!m_keyEventQueue.isEmpty()) { + LOG(KeyHandling, " UI process: sent keyEvent from didReceiveEvent"); m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID); + } else { + if (auto* automationSession = process().processPool().automationSession()) + automationSession->keyboardEventsFlushedForPage(*this); + } + + // The call to doneWithKeyEvent may close this WebPage. + // Protect against this being destroyed. + Ref<WebPageProxy> protect(*this); m_pageClient.doneWithKeyEvent(event, handled); if (handled) break; - if (m_uiClient.implementsDidNotHandleKeyEvent()) - m_uiClient.didNotHandleKeyEvent(this, event); + if (m_uiClient->implementsDidNotHandleKeyEvent()) + m_uiClient->didNotHandleKeyEvent(this, event); break; } -#if ENABLE(TOUCH_EVENTS) +#if ENABLE(MAC_GESTURE_EVENTS) + case WebEvent::GestureStart: + case WebEvent::GestureChange: + case WebEvent::GestureEnd: { + MESSAGE_CHECK(!m_gestureEventQueue.isEmpty()); + NativeWebGestureEvent event = m_gestureEventQueue.takeFirst(); + + MESSAGE_CHECK(type == event.type()); + + if (!handled) + m_pageClient.gestureEventWasNotHandledByWebCore(event); + break; + } + break; +#endif +#if ENABLE(IOS_TOUCH_EVENTS) + case WebEvent::TouchStart: + case WebEvent::TouchMove: + case WebEvent::TouchEnd: + case WebEvent::TouchCancel: + break; +#elif ENABLE(TOUCH_EVENTS) case WebEvent::TouchStart: case WebEvent::TouchMove: case WebEvent::TouchEnd: @@ -3588,12 +5036,12 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) void WebPageProxy::stopResponsivenessTimer() { - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); } void WebPageProxy::voidCallback(uint64_t callbackID) { - RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID); + auto callback = m_callbacks.take<VoidCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; @@ -3604,18 +5052,18 @@ void WebPageProxy::voidCallback(uint64_t callbackID) void WebPageProxy::dataCallback(const IPC::DataReference& dataReference, uint64_t callbackID) { - RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID); + auto callback = m_callbacks.take<DataCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; } - callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).get()); + callback->performCallbackWithReturnValue(API::Data::create(dataReference.data(), dataReference.size()).ptr()); } void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID) { - RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID); + auto callback = m_callbacks.take<ImageCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; @@ -3626,7 +5074,7 @@ void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, ui void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID) { - RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID); + auto callback = m_callbacks.take<StringCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. // this can validly happen if a load invalidated the callback, though @@ -3638,11 +5086,30 @@ void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackI callback->performCallbackWithReturnValue(resultString.impl()); } -void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, uint64_t callbackID) +void WebPageProxy::invalidateStringCallback(uint64_t callbackID) { - RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID); + auto callback = m_callbacks.take<StringCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. + // this can validly happen if a load invalidated the callback, though + return; + } + + m_loadDependentStringCallbackIDs.remove(callbackID); + + callback->invalidate(); +} + +void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, bool hadException, const ExceptionDetails& details, uint64_t callbackID) +{ + auto callback = m_callbacks.take<ScriptValueCallback>(callbackID); + if (!callback) { + // FIXME: Log error or assert. + return; + } + + if (dataReference.isEmpty()) { + callback->performCallbackWithReturnValue(nullptr, hadException, details); return; } @@ -3650,12 +5117,12 @@ void WebPageProxy::scriptValueCallback(const IPC::DataReference& dataReference, data.reserveInitialCapacity(dataReference.size()); data.append(dataReference.data(), dataReference.size()); - callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0); + callback->performCallbackWithReturnValue(API::SerializedScriptValue::adopt(WTFMove(data)).ptr(), hadException, details); } void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID) { - RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID); + auto callback = m_callbacks.take<ComputedPagesCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; @@ -3666,7 +5133,7 @@ void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, doubl void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID) { - RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID); + auto callback = m_callbacks.take<ValidateCommandCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; @@ -3675,24 +5142,106 @@ void WebPageProxy::validateCommandCallback(const String& commandName, bool isEna callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state); } +void WebPageProxy::unsignedCallback(uint64_t result, uint64_t callbackID) +{ + auto callback = m_callbacks.take<UnsignedCallback>(callbackID); + if (!callback) { + // FIXME: Log error or assert. + // this can validly happen if a load invalidated the callback, though + return; + } + + callback->performCallbackWithReturnValue(result); +} + +void WebPageProxy::editingRangeCallback(const EditingRange& range, uint64_t callbackID) +{ + MESSAGE_CHECK(range.isValid()); + + auto callback = m_callbacks.take<EditingRangeCallback>(callbackID); + if (!callback) { + // FIXME: Log error or assert. + // this can validly happen if a load invalidated the callback, though + return; + } + + callback->performCallbackWithReturnValue(range); +} + +#if PLATFORM(COCOA) +void WebPageProxy::machSendRightCallback(const MachSendRight& sendRight, uint64_t callbackID) +{ + auto callback = m_callbacks.take<MachSendRightCallback>(callbackID); + if (!callback) + return; + + callback->performCallbackWithReturnValue(sendRight); +} +#endif + +void WebPageProxy::logDiagnosticMessage(const String& message, const String& description, WebCore::ShouldSample shouldSample) +{ + if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) + return; + + m_diagnosticLoggingClient->logDiagnosticMessage(this, message, description); +} + +void WebPageProxy::logDiagnosticMessageWithResult(const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample) +{ + if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) + return; + + m_diagnosticLoggingClient->logDiagnosticMessageWithResult(this, message, description, static_cast<WebCore::DiagnosticLoggingResultType>(result)); +} + +void WebPageProxy::logDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, ShouldSample shouldSample) +{ + if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) + return; + + m_diagnosticLoggingClient->logDiagnosticMessageWithValue(this, message, description, String::number(value, significantFigures)); +} + +void WebPageProxy::logDiagnosticMessageWithEnhancedPrivacy(const String& message, const String& description, ShouldSample shouldSample) +{ + if (!DiagnosticLoggingClient::shouldLogAfterSampling(shouldSample)) + return; + + m_diagnosticLoggingClient->logDiagnosticMessageWithEnhancedPrivacy(this, message, description); +} + +void WebPageProxy::rectForCharacterRangeCallback(const IntRect& rect, const EditingRange& actualRange, uint64_t callbackID) +{ + MESSAGE_CHECK(actualRange.isValid()); + + auto callback = m_callbacks.take<RectForCharacterRangeCallback>(callbackID); + if (!callback) { + // FIXME: Log error or assert. + // this can validly happen if a load invalidated the callback, though + return; + } + + callback->performCallbackWithReturnValue(rect, actualRange); +} + #if PLATFORM(GTK) void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID) { - RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID); + auto callback = m_callbacks.take<PrintFinishedCallback>(callbackID); if (!callback) { // FIXME: Log error or assert. return; } - RefPtr<API::Error> error = API::Error::create(printError); - callback->performCallbackWithReturnValue(error.get()); + callback->performCallbackWithReturnValue(API::Error::create(printError).ptr()); } #endif void WebPageProxy::focusedFrameChanged(uint64_t frameID) { if (!frameID) { - m_focusedFrame = 0; + m_focusedFrame = nullptr; return; } @@ -3705,7 +5254,7 @@ void WebPageProxy::focusedFrameChanged(uint64_t frameID) void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID) { if (!frameID) { - m_frameSetLargestFrame = 0; + m_frameSetLargestFrame = nullptr; return; } @@ -3722,53 +5271,93 @@ void WebPageProxy::processDidBecomeUnresponsive() updateBackingStoreDiscardableState(); - m_loaderClient->processDidBecomeUnresponsive(this); + if (m_navigationClient) + m_navigationClient->processDidBecomeUnresponsive(*this); + else + m_loaderClient->processDidBecomeUnresponsive(*this); } -void WebPageProxy::interactionOccurredWhileProcessUnresponsive() +void WebPageProxy::processDidBecomeResponsive() { if (!isValid()) return; + + updateBackingStoreDiscardableState(); - m_loaderClient->interactionOccurredWhileProcessUnresponsive(this); + if (m_navigationClient) + m_navigationClient->processDidBecomeResponsive(*this); + else + m_loaderClient->processDidBecomeResponsive(*this); } -void WebPageProxy::processDidBecomeResponsive() +void WebPageProxy::willChangeProcessIsResponsive() { - if (!isValid()) - return; - - updateBackingStoreDiscardableState(); + m_pageLoadState.willChangeProcessIsResponsive(); +} - m_loaderClient->processDidBecomeResponsive(this); +void WebPageProxy::didChangeProcessIsResponsive() +{ + m_pageLoadState.didChangeProcessIsResponsive(); } void WebPageProxy::processDidCrash() { ASSERT(m_isValid); + // There is a nested transaction in resetStateAfterProcessExited() that we don't want to commit before the client call. + PageLoadState::Transaction transaction = m_pageLoadState.transaction(); + resetStateAfterProcessExited(); - auto transaction = m_pageLoadState.transaction(); + navigationState().clearAllNavigations(); - m_pageLoadState.reset(transaction); + if (m_navigationClient) + m_navigationClient->processDidCrash(*this); + else + m_loaderClient->processDidCrash(*this); - m_pageClient.processDidCrash(); + if (m_controlledByAutomation) { + if (auto* automationSession = process().processPool().automationSession()) + automationSession->terminate(); + } +} + +#if PLATFORM(IOS) +void WebPageProxy::processWillBecomeSuspended() +{ + if (!isValid()) + return; + + m_hasNetworkRequestsOnSuspended = m_pageLoadState.networkRequestsInProgress(); + if (m_hasNetworkRequestsOnSuspended) + setNetworkRequestsInProgress(false); +} + +void WebPageProxy::processWillBecomeForeground() +{ + if (!isValid()) + return; - m_loaderClient->processDidCrash(this); + if (m_hasNetworkRequestsOnSuspended) { + setNetworkRequestsInProgress(true); + m_hasNetworkRequestsOnSuspended = false; + } } +#endif -void WebPageProxy::resetState() +void WebPageProxy::resetState(ResetStateReason resetStateReason) { m_mainFrame = nullptr; +#if PLATFORM(COCOA) + m_scrollingPerformanceData = nullptr; +#endif m_drawingArea = nullptr; + hideValidationMessage(); -#if ENABLE(INSPECTOR) if (m_inspector) { m_inspector->invalidate(); m_inspector = nullptr; } -#endif #if ENABLE(FULLSCREEN_API) if (m_fullScreenManager) { @@ -3786,6 +5375,10 @@ void WebPageProxy::resetState() m_openPanelResultListener = nullptr; } +#if ENABLE(TOUCH_EVENTS) + m_touchEventTracking.reset(); +#endif + #if ENABLE(INPUT_TYPE_COLOR) if (m_colorPicker) { m_colorPicker->invalidate(); @@ -3797,6 +5390,10 @@ void WebPageProxy::resetState() m_geolocationPermissionRequestManager.invalidateRequests(); #endif +#if ENABLE(MEDIA_STREAM) + m_userMediaPermissionRequestManager = nullptr; +#endif + m_notificationPermissionRequestManager.invalidateRequests(); m_toolTip = String(); @@ -3804,38 +5401,70 @@ void WebPageProxy::resetState() m_mainFrameHasHorizontalScrollbar = false; m_mainFrameHasVerticalScrollbar = false; - m_mainFrameIsPinnedToLeftSide = false; - m_mainFrameIsPinnedToRightSide = false; - m_mainFrameIsPinnedToTopSide = false; - m_mainFrameIsPinnedToBottomSide = false; + m_mainFrameIsPinnedToLeftSide = true; + m_mainFrameIsPinnedToRightSide = true; + m_mainFrameIsPinnedToTopSide = true; + m_mainFrameIsPinnedToBottomSide = true; m_visibleScrollerThumbRect = IntRect(); - invalidateCallbackMap(m_voidCallbacks); - invalidateCallbackMap(m_dataCallbacks); - invalidateCallbackMap(m_imageCallbacks); - invalidateCallbackMap(m_stringCallbacks); - m_loadDependentStringCallbackIDs.clear(); - invalidateCallbackMap(m_scriptValueCallbacks); - invalidateCallbackMap(m_computedPagesCallbacks); - invalidateCallbackMap(m_validateCommandCallbacks); +#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + if (m_playbackSessionManager) { + m_playbackSessionManager->invalidate(); + m_playbackSessionManager = nullptr; + } + if (m_videoFullscreenManager) { + m_videoFullscreenManager->invalidate(); + m_videoFullscreenManager = nullptr; + } +#endif + #if PLATFORM(IOS) - invalidateCallbackMap(m_gestureCallbacks); - invalidateCallbackMap(m_touchesCallbacks); - invalidateCallbackMap(m_autocorrectionCallbacks); - invalidateCallbackMap(m_autocorrectionContextCallbacks); + m_firstLayerTreeTransactionIdAfterDidCommitLoad = 0; + m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo(); + m_dynamicViewportSizeUpdateWaitingForTarget = false; + m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false; + m_dynamicViewportSizeUpdateLayerTreeTransactionID = 0; + m_layerTreeTransactionIdAtLastTouchStart = 0; + m_hasNetworkRequestsOnSuspended = false; + m_isKeyboardAnimatingIn = false; + m_isScrollingOrZooming = false; #endif -#if PLATFORM(GTK) - invalidateCallbackMap(m_printFinishedCallbacks); + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + m_pageClient.mediaSessionManager().removeAllPlaybackTargetPickerClients(*this); +#endif + +#if ENABLE(APPLE_PAY) + m_paymentCoordinator = nullptr; #endif + CallbackBase::Error error; + switch (resetStateReason) { + case ResetStateReason::PageInvalidated: + error = CallbackBase::Error::OwnerWasInvalidated; + break; + + case ResetStateReason::WebProcessExited: + error = CallbackBase::Error::ProcessExited; + break; + } + + m_callbacks.invalidate(error); + m_loadDependentStringCallbackIDs.clear(); + Vector<WebEditCommandProxy*> editCommandVector; copyToVector(m_editCommandSet, editCommandVector); m_editCommandSet.clear(); for (size_t i = 0, size = editCommandVector.size(); i < size; ++i) editCommandVector[i]->invalidate(); - m_activePopupMenu = 0; + m_activePopupMenu = nullptr; + m_mediaState = MediaProducer::IsNotPlaying; + +#if ENABLE(POINTER_LOCK) + requestPointerUnlock(); +#endif } void WebPageProxy::resetStateAfterProcessExited() @@ -3843,18 +5472,25 @@ void WebPageProxy::resetStateAfterProcessExited() if (!isValid()) return; - m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID); + // FIXME: It's weird that resetStateAfterProcessExited() is called even though the process is launching. + ASSERT(m_process->state() == WebProcessProxy::State::Launching || m_process->state() == WebProcessProxy::State::Terminated); + +#if PLATFORM(IOS) + m_activityToken = nullptr; +#endif + m_pageIsUserObservableCount = nullptr; + m_visiblePageToken = nullptr; m_isValid = false; m_isPageSuspended = false; - m_waitingForDidUpdateViewState = false; - if (m_mainFrame) { - m_urlAtProcessExit = m_mainFrame->url(); - m_loadStateAtProcessExit = m_mainFrame->frameLoadState().m_state; - } + m_needsToFinishInitializingWebPageAfterProcessLaunch = false; + + m_editorState = EditorState(); - resetState(); + m_pageClient.processDidExit(); + + resetState(ResetStateReason::WebProcessExited); m_pageClient.clearAllEditCommands(); m_pendingLearnOrIgnoreWordMessageCount = 0; @@ -3869,19 +5505,18 @@ void WebPageProxy::resetStateAfterProcessExited() m_processingMouseMoveEvent = false; -#if ENABLE(TOUCH_EVENTS) - m_needTouchEvents = false; +#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS) m_touchEventQueue.clear(); #endif - // FIXME: Reset m_editorState. - // FIXME: Notify input methods about abandoned composition. - m_temporarilyClosedComposition = false; - -#if !PLATFORM(IOS) && PLATFORM(MAC) - dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored); - m_pageClient.dismissDictionaryLookupPanel(); +#if PLATFORM(MAC) + m_pageClient.dismissContentRelativeChildWindows(); #endif + + PageLoadState::Transaction transaction = m_pageLoadState.transaction(); + m_pageLoadState.reset(transaction); + + m_process->responsivenessTimer().processTerminated(); } WebPageCreationParameters WebPageProxy::creationParameters() @@ -3889,14 +5524,13 @@ WebPageCreationParameters WebPageProxy::creationParameters() WebPageCreationParameters parameters; parameters.viewSize = m_pageClient.viewSize(); - parameters.viewState = m_viewState; + parameters.activityState = m_activityState; parameters.drawingAreaType = m_drawingArea->type(); - parameters.store = m_pageGroup->preferences()->store(); + parameters.store = preferencesStore(); parameters.pageGroupData = m_pageGroup->data(); parameters.drawsBackground = m_drawsBackground; - parameters.drawsTransparentBackground = m_drawsTransparentBackground; + parameters.isEditable = m_isEditable; parameters.underlayColor = m_underlayColor; - parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled; parameters.useFixedLayout = m_useFixedLayout; parameters.fixedLayoutSize = m_fixedLayoutSize; parameters.suppressScrollbarAnimations = m_suppressScrollbarAnimations; @@ -3904,28 +5538,63 @@ WebPageCreationParameters WebPageProxy::creationParameters() parameters.paginationBehavesLikeColumns = m_paginationBehavesLikeColumns; parameters.pageLength = m_pageLength; parameters.gapBetweenPages = m_gapBetweenPages; + parameters.paginationLineGridEnabled = m_paginationLineGridEnabled; parameters.userAgent = userAgent(); - parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex()); - parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID(); - parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel(); + parameters.itemStates = m_backForwardList->itemStates(); + parameters.sessionID = m_sessionID; + parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highestUsedItemID(); + parameters.userContentControllerID = m_userContentController->identifier(); + parameters.visitedLinkTableID = m_visitedLinkStore->identifier(); + parameters.websiteDataStoreID = m_websiteDataStore->identifier(); + parameters.canRunBeforeUnloadConfirmPanel = m_uiClient->canRunBeforeUnloadConfirmPanel(); parameters.canRunModal = m_canRunModal; parameters.deviceScaleFactor = deviceScaleFactor(); + parameters.viewScaleFactor = m_viewScaleFactor; + parameters.topContentInset = m_topContentInset; parameters.mediaVolume = m_mediaVolume; + parameters.muted = m_mutedState; parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow; parameters.minimumLayoutSize = m_minimumLayoutSize; parameters.autoSizingShouldExpandToViewHeight = m_autoSizingShouldExpandToViewHeight; parameters.scrollPinningBehavior = m_scrollPinningBehavior; + if (m_scrollbarOverlayStyle) + parameters.scrollbarOverlayStyle = m_scrollbarOverlayStyle.value(); + else + parameters.scrollbarOverlayStyle = std::nullopt; parameters.backgroundExtendsBeyondPage = m_backgroundExtendsBeyondPage; parameters.layerHostingMode = m_layerHostingMode; - -#if PLATFORM(MAC) && !PLATFORM(IOS) + parameters.controlledByAutomation = m_controlledByAutomation; +#if ENABLE(REMOTE_INSPECTOR) + parameters.allowsRemoteInspection = m_allowsRemoteInspection; + parameters.remoteInspectionNameOverride = m_remoteInspectionNameOverride; +#endif +#if PLATFORM(MAC) parameters.colorSpace = m_pageClient.colorSpace(); #endif +#if PLATFORM(IOS) + parameters.screenSize = screenSize(); + parameters.availableScreenSize = availableScreenSize(); + parameters.textAutosizingWidth = textAutosizingWidth(); + parameters.mimeTypesWithCustomContentProviders = m_pageClient.mimeTypesWithCustomContentProviders(); + parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable; +#endif + +#if PLATFORM(MAC) + parameters.appleMailPaginationQuirkEnabled = appleMailPaginationQuirkEnabled(); +#else + parameters.appleMailPaginationQuirkEnabled = false; +#endif +#if PLATFORM(COCOA) + parameters.smartInsertDeleteEnabled = m_isSmartInsertDeleteEnabled; +#endif + parameters.shouldScaleViewToFitDocument = m_shouldScaleViewToFitDocument; + parameters.userInterfaceLayoutDirection = m_pageClient.userInterfaceLayoutDirection(); + parameters.observedLayoutMilestones = m_observedLayoutMilestones; + parameters.overrideContentSecurityPolicy = m_overrideContentSecurityPolicy; return parameters; } -#if USE(ACCELERATED_COMPOSITING) void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { m_pageClient.enterAcceleratedCompositingMode(layerTreeContext); @@ -3940,21 +5609,37 @@ void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& laye { m_pageClient.updateAcceleratedCompositingMode(layerTreeContext); } -#endif // USE(ACCELERATED_COMPOSITING) void WebPageProxy::backForwardClear() { m_backForwardList->clear(); } -void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const ProtectionSpace& coreProtectionSpace, bool& canAuthenticate) +#if ENABLE(GAMEPAD) + +void WebPageProxy::gamepadActivity(const Vector<GamepadData>& gamepadDatas, bool shouldMakeGamepadsVisible) { + m_process->send(Messages::WebPage::GamepadActivity(gamepadDatas, shouldMakeGamepadsVisible), m_pageID); +} + +#endif + +void WebPageProxy::canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t frameID, const ProtectionSpace& coreProtectionSpace) +{ +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace); - canAuthenticate = m_loaderClient->canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get()); + bool canAuthenticate; + if (m_navigationClient) + canAuthenticate = m_navigationClient->canAuthenticateAgainstProtectionSpace(*this, protectionSpace.get()); + else + canAuthenticate = m_loaderClient->canAuthenticateAgainstProtectionSpaceInFrame(*this, *frame, protectionSpace.get()); + + m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::ContinueCanAuthenticateAgainstProtectionSpace(loaderID, canAuthenticate)); +#endif } void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const AuthenticationChallenge& coreChallenge, uint64_t challengeID) @@ -3970,16 +5655,19 @@ void WebPageProxy::didReceiveAuthenticationChallengeProxy(uint64_t frameID, Pass MESSAGE_CHECK(frame); RefPtr<AuthenticationChallengeProxy> authenticationChallenge = prpAuthenticationChallenge; - m_loaderClient->didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get()); + if (m_navigationClient) + m_navigationClient->didReceiveAuthenticationChallenge(*this, authenticationChallenge.get()); + else + m_loaderClient->didReceiveAuthenticationChallengeInFrame(*this, *frame, authenticationChallenge.get()); } void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply) { - ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared(); - OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID, + ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::singleton(); + std::unique_ptr<ExceededDatabaseQuotaRecords::Record> newRecord = records.createRecord(frameID, originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, reply); - records.add(newRecord.release()); + records.add(WTFMove(newRecord)); if (records.areBeingProcessed()) return; @@ -3989,27 +5677,33 @@ void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originI WebFrameProxy* frame = m_process->webFrame(record->frameID); MESSAGE_CHECK(frame); - RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier); - - uint64_t newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(), + RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(record->originIdentifier)->securityOrigin()); + auto currentReply = record->reply; + m_uiClient->exceededDatabaseQuota(this, frame, origin.get(), record->databaseName, record->displayName, record->currentQuota, - record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage); + record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage, + [currentReply](unsigned long long newQuota) { currentReply->send(newQuota); }); - record->reply->send(newQuota); record = records.next(); } } +void WebPageProxy::reachedApplicationCacheOriginQuota(const String& originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, PassRefPtr<Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply> reply) +{ + Ref<SecurityOrigin> securityOrigin = SecurityOriginData::fromDatabaseIdentifier(originIdentifier)->securityOrigin(); + m_uiClient->reachedApplicationCacheOriginQuota(this, securityOrigin.get(), currentQuota, totalBytesNeeded, [reply](unsigned long long newQuota) { reply->send(newQuota); }); +} + void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier) { WebFrameProxy* frame = m_process->webFrame(frameID); MESSAGE_CHECK(frame); // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier(). - RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier); + RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::create(SecurityOriginData::fromDatabaseIdentifier(originIdentifier)->securityOrigin()); RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID); - if (m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get())) + if (m_uiClient->decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get())) return; if (m_pageClient.decidePolicyForGeolocationPermissionRequest(*frame, *origin, *request)) @@ -4018,70 +5712,119 @@ void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, request->deny(); } +#if ENABLE(MEDIA_STREAM) +UserMediaPermissionRequestManagerProxy& WebPageProxy::userMediaPermissionRequestManager() +{ + if (m_userMediaPermissionRequestManager) + return *m_userMediaPermissionRequestManager; + + m_userMediaPermissionRequestManager = std::make_unique<UserMediaPermissionRequestManagerProxy>(*this); + return *m_userMediaPermissionRequestManager; +} +#endif + +void WebPageProxy::requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraintsData, const WebCore::MediaConstraintsData& videoConstraintsData) +{ +#if ENABLE(MEDIA_STREAM) + MESSAGE_CHECK(m_process->webFrame(frameID)); + + userMediaPermissionRequestManager().requestUserMediaPermissionForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier, audioConstraintsData, videoConstraintsData); +#else + UNUSED_PARAM(userMediaID); + UNUSED_PARAM(frameID); + UNUSED_PARAM(userMediaDocumentOriginIdentifier); + UNUSED_PARAM(topLevelDocumentOriginIdentifier); + UNUSED_PARAM(audioConstraintsData); + UNUSED_PARAM(videoConstraintsData); +#endif +} + +void WebPageProxy::enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier) +{ +#if ENABLE(MEDIA_STREAM) + WebFrameProxy* frame = m_process->webFrame(frameID); + MESSAGE_CHECK(frame); + + userMediaPermissionRequestManager().enumerateMediaDevicesForFrame(userMediaID, frameID, userMediaDocumentOriginIdentifier, topLevelDocumentOriginIdentifier); +#else + UNUSED_PARAM(userMediaID); + UNUSED_PARAM(frameID); + UNUSED_PARAM(userMediaDocumentOriginIdentifier); + UNUSED_PARAM(topLevelDocumentOriginIdentifier); +#endif +} + +void WebPageProxy::clearUserMediaState() +{ +#if ENABLE(MEDIA_STREAM) + userMediaPermissionRequestManager().clearCachedState(); +#endif +} + void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString) { if (!isRequestIDValid(requestID)) return; - RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString); + RefPtr<API::SecurityOrigin> origin = API::SecurityOrigin::createFromString(originString); RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID); - if (!m_uiClient.decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get())) + if (!m_uiClient->decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get())) request->deny(); } void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID) { - m_process->context().supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID); + m_process->processPool().supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID); } void WebPageProxy::cancelNotification(uint64_t notificationID) { - m_process->context().supplement<WebNotificationManagerProxy>()->cancel(this, notificationID); + m_process->processPool().supplement<WebNotificationManagerProxy>()->cancel(this, notificationID); } void WebPageProxy::clearNotifications(const Vector<uint64_t>& notificationIDs) { - m_process->context().supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs); + m_process->processPool().supplement<WebNotificationManagerProxy>()->clearNotifications(this, notificationIDs); } void WebPageProxy::didDestroyNotification(uint64_t notificationID) { - m_process->context().supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID); + m_process->processPool().supplement<WebNotificationManagerProxy>()->didDestroyNotification(this, notificationID); } float WebPageProxy::headerHeight(WebFrameProxy* frame) { if (frame->isDisplayingPDFDocument()) return 0; - return m_uiClient.headerHeight(this, frame); + return m_uiClient->headerHeight(this, frame); } float WebPageProxy::footerHeight(WebFrameProxy* frame) { if (frame->isDisplayingPDFDocument()) return 0; - return m_uiClient.footerHeight(this, frame); + return m_uiClient->footerHeight(this, frame); } void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect) { if (frame->isDisplayingPDFDocument()) return; - m_uiClient.drawHeader(this, frame, rect); + m_uiClient->drawHeader(this, frame, rect); } void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect) { if (frame->isDisplayingPDFDocument()) return; - m_uiClient.drawFooter(this, frame, rect); + m_uiClient->drawFooter(this, frame, rect); } void WebPageProxy::runModal() { // Since runModal() can (and probably will) spin a nested run loop we need to turn off the responsiveness timer. - m_process->responsivenessTimer()->stop(); + m_process->responsivenessTimer().stop(); // Our Connection's run loop might have more messages waiting to be handled after this RunModal message. // To make sure they are handled inside of the the nested modal run loop we must first signal the Connection's @@ -4089,7 +5832,7 @@ void WebPageProxy::runModal() // See http://webkit.org/b/89590 for more discussion. m_process->connection()->wakeUpRunLoop(); - m_uiClient.runModal(this); + m_uiClient->runModal(this); } void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb) @@ -4100,7 +5843,7 @@ void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThu void WebPageProxy::recommendedScrollbarStyleDidChange(int32_t newStyle) { #if USE(APPKIT) - m_pageClient.recommendedScrollbarStyleDidChange(newStyle); + m_pageClient.recommendedScrollbarStyleDidChange(static_cast<WebCore::ScrollbarStyle>(newStyle)); #else UNUSED_PARAM(newStyle); #endif @@ -4118,6 +5861,8 @@ void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSid m_mainFrameIsPinnedToRightSide = pinnedToRightSide; m_mainFrameIsPinnedToTopSide = pinnedToTopSide; m_mainFrameIsPinnedToBottomSide = pinnedToBottomSide; + + m_uiClient->pinnedStateDidChange(*this); } void WebPageProxy::didChangePageCount(unsigned pageCount) @@ -4125,19 +5870,24 @@ void WebPageProxy::didChangePageCount(unsigned pageCount) m_pageCount = pageCount; } +void WebPageProxy::pageExtendedBackgroundColorDidChange(const Color& backgroundColor) +{ + m_pageExtendedBackgroundColor = backgroundColor; +} + #if ENABLE(NETSCAPE_PLUGIN_API) void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString) { - m_loaderClient->didFailToInitializePlugin(this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).get()); + m_loaderClient->didFailToInitializePlugin(*this, createPluginInformationDictionary(mimeType, frameURLString, pageURLString).ptr()); } void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured) { - RefPtr<ImmutableDictionary> pluginInformation; + RefPtr<API::Dictionary> pluginInformation; -#if PLATFORM(MAC) && ENABLE(NETSCAPE_PLUGIN_API) +#if PLATFORM(COCOA) && ENABLE(NETSCAPE_PLUGIN_API) String newMimeType = mimeType; - PluginModuleInfo plugin = m_process->context().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString)); + PluginModuleInfo plugin = m_process->processPool().pluginInfoStore().findPlugin(newMimeType, URL(URL(), pluginURLString)); pluginInformation = createPluginInformationDictionary(plugin, frameURLString, mimeType, pageURLString, String(), String(), replacementObscured); #else UNUSED_PARAM(mimeType); @@ -4147,7 +5897,7 @@ void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const S UNUSED_PARAM(replacementObscured); #endif - m_loaderClient->didBlockInsecurePluginVersion(this, pluginInformation.get()); + m_loaderClient->didBlockInsecurePluginVersion(*this, pluginInformation.get()); } #endif // ENABLE(NETSCAPE_PLUGIN_API) @@ -4156,8 +5906,19 @@ bool WebPageProxy::willHandleHorizontalScrollEvents() const return !m_canShortCircuitHorizontalWheelEvents; } +void WebPageProxy::updateWebsitePolicies(const WebsitePolicies& websitePolicies) +{ + m_process->send(Messages::WebPage::UpdateWebsitePolicies(websitePolicies), m_pageID); +} + +void WebPageProxy::didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference& dataReference) +{ + m_pageClient.didFinishLoadingDataForCustomContentProvider(suggestedFilename, dataReference); +} + void WebPageProxy::backForwardRemovedItem(uint64_t itemID) { + m_process->removeBackForwardItem(itemID); m_process->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID); } @@ -4169,7 +5930,7 @@ void WebPageProxy::setCanRunModal(bool canRunModal) // It's only possible to change the state for a WebPage which // already qualifies for running modal child web pages, otherwise // there's no other possibility than not allowing it. - m_canRunModal = m_uiClient.canRunModal() && canRunModal; + m_canRunModal = m_uiClient->canRunModal() && canRunModal; m_process->send(Messages::WebPage::SetCanRunModal(m_canRunModal), m_pageID); } @@ -4184,7 +5945,7 @@ void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInf return; m_isInPrintingMode = true; - m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } void WebPageProxy::endPrinting() @@ -4193,7 +5954,7 @@ void WebPageProxy::endPrinting() return; m_isInPrintingMode = false; - m_process->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_process->send(Messages::WebPage::EndPrinting(), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback) @@ -4205,12 +5966,12 @@ void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo } uint64_t callbackID = callback->callbackID(); - m_computedPagesCallbacks.set(callbackID, callback.get()); + m_callbacks.put(callback); m_isInPrintingMode = true; - m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, PassRefPtr<ImageCallback> prpCallback) { RefPtr<ImageCallback> callback = prpCallback; @@ -4220,8 +5981,8 @@ void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printI } uint64_t callbackID = callback->callbackID(); - m_imageCallbacks.set(callbackID, callback.get()); - m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_callbacks.put(callback); + m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback) @@ -4233,8 +5994,8 @@ void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printIn } uint64_t callbackID = callback->callbackID(); - m_dataCallbacks.set(callbackID, callback.get()); - m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_callbacks.put(callback); + m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } #elif PLATFORM(GTK) void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<PrintFinishedCallback> didPrintCallback) @@ -4246,9 +6007,9 @@ void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& p } uint64_t callbackID = callback->callbackID(); - m_printFinishedCallbacks.set(callbackID, callback.get()); + m_callbacks.put(callback); m_isInPrintingMode = true; - m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? IPC::DispatchMessageEvenWhenWaitingForSyncReply : 0); + m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, printingSendOptions(m_isPerformingDOMPrintOperation)); } #endif @@ -4258,7 +6019,7 @@ void WebPageProxy::updateBackingStoreDiscardableState() bool isDiscardable; - if (!m_process->responsivenessTimer()->isResponsive()) + if (!m_process->responsivenessTimer().isResponsive()) isDiscardable = false; else isDiscardable = !m_pageClient.isViewWindowActive() || !isViewVisible(); @@ -4268,7 +6029,7 @@ void WebPageProxy::updateBackingStoreDiscardableState() void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data* data) { - m_uiClient.saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data); + m_uiClient->saveDataToFileInDownloadsFolder(this, suggestedFilename, mimeType, originatingURLString, data); } void WebPageProxy::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const IPC::DataReference& dataReference) @@ -4276,9 +6037,8 @@ void WebPageProxy::savePDFToFileInDownloadsFolder(const String& suggestedFilenam if (!suggestedFilename.endsWith(".pdf", false)) return; - RefPtr<API::Data> data = API::Data::create(dataReference.data(), dataReference.size()); - - saveDataToFileInDownloadsFolder(suggestedFilename, "application/pdf", originatingURLString, data.get()); + saveDataToFileInDownloadsFolder(suggestedFilename, "application/pdf", originatingURLString, + API::Data::create(dataReference.data(), dataReference.size()).ptr()); } void WebPageProxy::setMinimumLayoutSize(const IntSize& minimumLayoutSize) @@ -4291,7 +6051,7 @@ void WebPageProxy::setMinimumLayoutSize(const IntSize& minimumLayoutSize) if (!isValid()) return; - m_process->send(Messages::WebPage::SetMinimumLayoutSize(minimumLayoutSize), m_pageID, 0); + m_process->send(Messages::WebPage::SetMinimumLayoutSize(minimumLayoutSize), m_pageID); m_drawingArea->minimumLayoutSizeDidChange(); #if USE(APPKIT) @@ -4310,10 +6070,44 @@ void WebPageProxy::setAutoSizingShouldExpandToViewHeight(bool shouldExpand) if (!isValid()) return; - m_process->send(Messages::WebPage::SetAutoSizingShouldExpandToViewHeight(shouldExpand), m_pageID, 0); + m_process->send(Messages::WebPage::SetAutoSizingShouldExpandToViewHeight(shouldExpand), m_pageID); } -#if !PLATFORM(IOS) && PLATFORM(MAC) +#if USE(AUTOMATIC_TEXT_REPLACEMENT) + +void WebPageProxy::toggleSmartInsertDelete() +{ + if (TextChecker::isTestingMode()) + TextChecker::setSmartInsertDeleteEnabled(!TextChecker::isSmartInsertDeleteEnabled()); +} + +void WebPageProxy::toggleAutomaticQuoteSubstitution() +{ + if (TextChecker::isTestingMode()) + TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled); +} + +void WebPageProxy::toggleAutomaticLinkDetection() +{ + if (TextChecker::isTestingMode()) + TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled); +} + +void WebPageProxy::toggleAutomaticDashSubstitution() +{ + if (TextChecker::isTestingMode()) + TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled); +} + +void WebPageProxy::toggleAutomaticTextReplacement() +{ + if (TextChecker::isTestingMode()) + TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled); +} + +#endif + +#if PLATFORM(MAC) void WebPageProxy::substitutionsPanelIsShowing(bool& isShowing) { @@ -4335,15 +6129,15 @@ void WebPageProxy::dismissCorrectionPanelSoon(int32_t reason, String& result) result = m_pageClient.dismissCorrectionPanelSoon((ReasonForDismissingAlternativeText)reason); } -void WebPageProxy::recordAutocorrectionResponse(int32_t responseType, const String& replacedString, const String& replacementString) +void WebPageProxy::recordAutocorrectionResponse(int32_t response, const String& replacedString, const String& replacementString) { - m_pageClient.recordAutocorrectionResponse((AutocorrectionResponseType)responseType, replacedString, replacementString); + m_pageClient.recordAutocorrectionResponse(static_cast<AutocorrectionResponse>(response), replacedString, replacementString); } void WebPageProxy::handleAlternativeTextUIResult(const String& result) { if (!isClosed()) - m_process->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID, 0); + m_process->send(Messages::WebPage::HandleAlternativeTextUIResult(result), m_pageID); } #if USE(DICTATION_ALTERNATIVES) @@ -4363,19 +6157,17 @@ void WebPageProxy::dictationAlternatives(uint64_t dictationContext, Vector<Strin } #endif -#endif // !PLATFORM(IOS) && PLATFORM(MAC) - -#if PLATFORM(MAC) -RetainPtr<CGImageRef> WebPageProxy::takeViewSnapshot() +void WebPageProxy::setEditableElementIsFocused(bool editableElementIsFocused) { - return m_pageClient.takeViewSnapshot(); + m_pageClient.setEditableElementIsFocused(editableElementIsFocused); } -#endif -#if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS) -void WebPageProxy::didReceiveURIRequest(String uriString, uint64_t requestID) +#endif // PLATFORM(MAC) + +#if PLATFORM(COCOA) +PassRefPtr<ViewSnapshot> WebPageProxy::takeViewSnapshot() { - m_process->context().supplement<WebSoupRequestManagerProxy>()->didReceiveURIRequest(uriString, this, requestID); + return m_pageClient.takeViewSnapshot(); } #endif @@ -4406,17 +6198,6 @@ void WebPageProxy::cancelComposition() } #endif // PLATFORM(GTK) -void WebPageProxy::setMainFrameInViewSourceMode(bool mainFrameInViewSourceMode) -{ - if (m_mainFrameInViewSourceMode == mainFrameInViewSourceMode) - return; - - m_mainFrameInViewSourceMode = mainFrameInViewSourceMode; - - if (isValid()) - m_process->send(Messages::WebPage::SetMainFrameInViewSourceMode(mainFrameInViewSourceMode), m_pageID); -} - void WebPageProxy::didSaveToPageCache() { m_process->didSaveToPageCache(); @@ -4433,4 +6214,636 @@ void WebPageProxy::setScrollPinningBehavior(ScrollPinningBehavior pinning) m_process->send(Messages::WebPage::SetScrollPinningBehavior(pinning), m_pageID); } +void WebPageProxy::setOverlayScrollbarStyle(std::optional<WebCore::ScrollbarOverlayStyle> scrollbarStyle) +{ + if (!m_scrollbarOverlayStyle && !scrollbarStyle) + return; + + if ((m_scrollbarOverlayStyle && scrollbarStyle) && m_scrollbarOverlayStyle.value() == scrollbarStyle.value()) + return; + + m_scrollbarOverlayStyle = scrollbarStyle; + + std::optional<uint32_t> scrollbarStyleForMessage; + if (scrollbarStyle) + scrollbarStyleForMessage = static_cast<ScrollbarOverlayStyle>(scrollbarStyle.value()); + + if (isValid()) + m_process->send(Messages::WebPage::SetScrollbarOverlayStyle(scrollbarStyleForMessage), m_pageID); +} + +#if ENABLE(SUBTLE_CRYPTO) +void WebPageProxy::wrapCryptoKey(const Vector<uint8_t>& key, bool& succeeded, Vector<uint8_t>& wrappedKey) +{ + PageClientProtector protector(m_pageClient); + + Vector<uint8_t> masterKey; + + if (m_navigationClient) { + if (RefPtr<API::Data> keyData = m_navigationClient->webCryptoMasterKey(*this)) + masterKey = keyData->dataReference().vector(); + } else if (!getDefaultWebCryptoMasterKey(masterKey)) { + succeeded = false; + return; + } + + succeeded = wrapSerializedCryptoKey(masterKey, key, wrappedKey); +} + +void WebPageProxy::unwrapCryptoKey(const Vector<uint8_t>& wrappedKey, bool& succeeded, Vector<uint8_t>& key) +{ + PageClientProtector protector(m_pageClient); + + Vector<uint8_t> masterKey; + + if (m_navigationClient) { + if (RefPtr<API::Data> keyData = m_navigationClient->webCryptoMasterKey(*this)) + masterKey = keyData->dataReference().vector(); + } else if (!getDefaultWebCryptoMasterKey(masterKey)) { + succeeded = false; + return; + } + + succeeded = unwrapSerializedCryptoKey(masterKey, wrappedKey, key); +} +#endif + +void WebPageProxy::addMIMETypeWithCustomContentProvider(const String& mimeType) +{ + m_process->send(Messages::WebPage::AddMIMETypeWithCustomContentProvider(mimeType), m_pageID); +} + +#if PLATFORM(COCOA) + +void WebPageProxy::insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup, EditingRangeIsRelativeTo editingRangeIsRelativeTo, bool suppressSelectionUpdate) +{ + if (!isValid()) + return; + + process().send(Messages::WebPage::InsertTextAsync(text, replacementRange, registerUndoGroup, static_cast<uint32_t>(editingRangeIsRelativeTo), suppressSelectionUpdate), m_pageID); +} + +void WebPageProxy::getMarkedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(EditingRange(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + process().send(Messages::WebPage::GetMarkedRangeAsync(callbackID), m_pageID); +} + +void WebPageProxy::getSelectedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(EditingRange(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + process().send(Messages::WebPage::GetSelectedRangeAsync(callbackID), m_pageID); +} + +void WebPageProxy::characterIndexForPointAsync(const WebCore::IntPoint& point, std::function<void (uint64_t, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(0, CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + process().send(Messages::WebPage::CharacterIndexForPointAsync(point, callbackID), m_pageID); +} + +void WebPageProxy::firstRectForCharacterRangeAsync(const EditingRange& range, std::function<void (const WebCore::IntRect&, const EditingRange&, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(WebCore::IntRect(), EditingRange(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + process().send(Messages::WebPage::FirstRectForCharacterRangeAsync(range, callbackID), m_pageID); +} + +void WebPageProxy::setCompositionAsync(const String& text, Vector<CompositionUnderline> underlines, const EditingRange& selectionRange, const EditingRange& replacementRange) +{ + if (!isValid()) { + // If this fails, we should call -discardMarkedText on input context to notify the input method. + // This will happen naturally later, as part of reloading the page. + return; + } + + process().send(Messages::WebPage::SetCompositionAsync(text, underlines, selectionRange, replacementRange), m_pageID); +} + +void WebPageProxy::confirmCompositionAsync() +{ + if (!isValid()) + return; + + process().send(Messages::WebPage::ConfirmCompositionAsync(), m_pageID); +} + +void WebPageProxy::setScrollPerformanceDataCollectionEnabled(bool enabled) +{ + if (enabled == m_scrollPerformanceDataCollectionEnabled) + return; + + m_scrollPerformanceDataCollectionEnabled = enabled; + + if (m_scrollPerformanceDataCollectionEnabled && !m_scrollingPerformanceData) + m_scrollingPerformanceData = std::make_unique<RemoteLayerTreeScrollingPerformanceData>(downcast<RemoteLayerTreeDrawingAreaProxy>(*m_drawingArea)); + else if (!m_scrollPerformanceDataCollectionEnabled) + m_scrollingPerformanceData = nullptr; +} +#endif + +void WebPageProxy::takeSnapshot(IntRect rect, IntSize bitmapSize, SnapshotOptions options, std::function<void (const ShareableBitmap::Handle&, CallbackBase::Error)> callbackFunction) +{ + if (!isValid()) { + callbackFunction(ShareableBitmap::Handle(), CallbackBase::Error::Unknown); + return; + } + + uint64_t callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()); + m_process->send(Messages::WebPage::TakeSnapshot(rect, bitmapSize, options, callbackID), m_pageID); +} + +void WebPageProxy::navigationGestureDidBegin() +{ + PageClientProtector protector(m_pageClient); + + m_isShowingNavigationGestureSnapshot = true; + m_pageClient.navigationGestureDidBegin(); + + if (m_navigationClient) + m_navigationClient->didBeginNavigationGesture(*this); + else + m_loaderClient->navigationGestureDidBegin(*this); +} + +void WebPageProxy::navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem& item) +{ + PageClientProtector protector(m_pageClient); + + m_pageClient.navigationGestureWillEnd(willNavigate, item); + + if (m_navigationClient) + m_navigationClient->willEndNavigationGesture(*this, willNavigate, item); + else + m_loaderClient->navigationGestureWillEnd(*this, willNavigate, item); +} + +void WebPageProxy::navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem& item) +{ + PageClientProtector protector(m_pageClient); + + m_pageClient.navigationGestureDidEnd(willNavigate, item); + + if (m_navigationClient) + m_navigationClient->didEndNavigationGesture(*this, willNavigate, item); + else + m_loaderClient->navigationGestureDidEnd(*this, willNavigate, item); +} + +void WebPageProxy::navigationGestureDidEnd() +{ + PageClientProtector protector(m_pageClient); + + m_pageClient.navigationGestureDidEnd(); +} + +void WebPageProxy::willRecordNavigationSnapshot(WebBackForwardListItem& item) +{ + PageClientProtector protector(m_pageClient); + + m_pageClient.willRecordNavigationSnapshot(item); +} + +void WebPageProxy::navigationGestureSnapshotWasRemoved() +{ + m_isShowingNavigationGestureSnapshot = false; + + m_pageClient.didRemoveNavigationGestureSnapshot(); + + if (m_navigationClient) + m_navigationClient->didRemoveNavigationGestureSnapshot(*this); +} + +void WebPageProxy::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID) +{ +#if ENABLE(MEDIA_SESSION) + WebMediaSessionFocusManager* focusManager = process().processPool().supplement<WebMediaSessionFocusManager>(); + ASSERT(focusManager); + focusManager->updatePlaybackAttributesFromMediaState(this, sourceElementID, state); +#endif + + if (state == m_mediaState) + return; + +#if ENABLE(MEDIA_STREAM) + WebCore::MediaProducer::MediaStateFlags oldMediaStateHasActiveCapture = m_mediaState & (WebCore::MediaProducer::HasActiveAudioCaptureDevice | WebCore::MediaProducer::HasActiveVideoCaptureDevice); + WebCore::MediaProducer::MediaStateFlags newMediaStateHasActiveCapture = state & (WebCore::MediaProducer::HasActiveAudioCaptureDevice | WebCore::MediaProducer::HasActiveVideoCaptureDevice); +#endif + + MediaProducer::MediaStateFlags playingMediaMask = MediaProducer::IsPlayingAudio | MediaProducer::IsPlayingVideo; + MediaProducer::MediaStateFlags oldState = m_mediaState; + m_mediaState = state; + +#if ENABLE(MEDIA_STREAM) + if (!oldMediaStateHasActiveCapture && newMediaStateHasActiveCapture) { + m_uiClient->didBeginCaptureSession(); + userMediaPermissionRequestManager().startedCaptureSession(); + } else if (oldMediaStateHasActiveCapture && !newMediaStateHasActiveCapture) { + m_uiClient->didEndCaptureSession(); + userMediaPermissionRequestManager().endedCaptureSession(); + } +#endif + + activityStateDidChange(ActivityState::IsAudible); + + playingMediaMask |= MediaProducer::HasActiveAudioCaptureDevice | MediaProducer::HasActiveVideoCaptureDevice; + if ((oldState & playingMediaMask) != (m_mediaState & playingMediaMask)) + m_uiClient->isPlayingAudioDidChange(*this); +#if PLATFORM(MAC) + if ((oldState & MediaProducer::HasAudioOrVideo) != (m_mediaState & MediaProducer::HasAudioOrVideo)) + videoControlsManagerDidChange(); +#endif +} + +#if PLATFORM(MAC) +void WebPageProxy::videoControlsManagerDidChange() +{ + m_pageClient.videoControlsManagerDidChange(); +} + +bool WebPageProxy::hasActiveVideoForControlsManager() const +{ +#if ENABLE(VIDEO_PRESENTATION_MODE) + return m_playbackSessionManager && m_playbackSessionManager->controlsManagerInterface(); +#else + return false; +#endif +} + +void WebPageProxy::requestControlledElementID() const +{ +#if ENABLE(VIDEO_PRESENTATION_MODE) + if (m_playbackSessionManager) + m_playbackSessionManager->requestControlledElementID(); +#endif +} + +void WebPageProxy::handleControlledElementIDResponse(const String& identifier) const +{ + m_pageClient.handleControlledElementIDResponse(identifier); +} + +bool WebPageProxy::isPlayingVideoInEnhancedFullscreen() const +{ +#if ENABLE(VIDEO_PRESENTATION_MODE) + return m_videoFullscreenManager && m_videoFullscreenManager->isPlayingVideoInEnhancedFullscreen(); +#else + return false; +#endif +} +#endif + +#if PLATFORM(COCOA) +void WebPageProxy::requestActiveNowPlayingSessionInfo() +{ + m_process->send(Messages::WebPage::RequestActiveNowPlayingSessionInfo(), m_pageID); +} + +void WebPageProxy::handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) const +{ + m_pageClient.handleActiveNowPlayingSessionInfoResponse(hasActiveSession, title, duration, elapsedTime); +} +#endif + +#if ENABLE(MEDIA_SESSION) +void WebPageProxy::hasMediaSessionWithActiveMediaElementsDidChange(bool state) +{ + m_hasMediaSessionWithActiveMediaElements = state; +} + +void WebPageProxy::mediaSessionMetadataDidChange(const WebCore::MediaSessionMetadata& metadata) +{ + Ref<WebMediaSessionMetadata> webMetadata = WebMediaSessionMetadata::create(metadata); + m_uiClient->mediaSessionMetadataDidChange(*this, webMetadata.ptr()); +} + +void WebPageProxy::focusedContentMediaElementDidChange(uint64_t elementID) +{ + WebMediaSessionFocusManager* focusManager = process().processPool().supplement<WebMediaSessionFocusManager>(); + ASSERT(focusManager); + focusManager->setFocusedMediaElement(*this, elementID); +} +#endif + +void WebPageProxy::didPlayMediaPreventedFromPlayingWithoutUserGesture() +{ + m_uiClient->didPlayMediaPreventedFromPlayingWithoutUserGesture(*this); +} + +#if PLATFORM(MAC) +void WebPageProxy::removeNavigationGestureSnapshot() +{ + m_pageClient.removeNavigationGestureSnapshot(); +} + +void WebPageProxy::performImmediateActionHitTestAtLocation(FloatPoint point) +{ + m_process->send(Messages::WebPage::PerformImmediateActionHitTestAtLocation(point), m_pageID); +} + +void WebPageProxy::immediateActionDidUpdate() +{ + m_process->send(Messages::WebPage::ImmediateActionDidUpdate(), m_pageID); +} + +void WebPageProxy::immediateActionDidCancel() +{ + m_process->send(Messages::WebPage::ImmediateActionDidCancel(), m_pageID); +} + +void WebPageProxy::immediateActionDidComplete() +{ + m_process->send(Messages::WebPage::ImmediateActionDidComplete(), m_pageID); +} + +void WebPageProxy::didPerformImmediateActionHitTest(const WebHitTestResultData& result, bool contentPreventsDefault, const UserData& userData) +{ + m_pageClient.didPerformImmediateActionHitTest(result, contentPreventsDefault, m_process->transformHandlesToObjects(userData.object()).get()); +} + +void* WebPageProxy::immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult> hitTestResult, uint64_t type, RefPtr<API::Object> userData) +{ + return m_pageClient.immediateActionAnimationControllerForHitTestResult(hitTestResult, type, userData); +} + +void WebPageProxy::installActivityStateChangeCompletionHandler(void (^completionHandler)()) +{ + if (!isValid()) { + completionHandler(); + return; + } + + auto copiedCompletionHandler = Block_copy(completionHandler); + auto voidCallback = VoidCallback::create([copiedCompletionHandler] (CallbackBase::Error) { + copiedCompletionHandler(); + Block_release(copiedCompletionHandler); + }, m_process->throttler().backgroundActivityToken()); + uint64_t callbackID = m_callbacks.put(WTFMove(voidCallback)); + m_nextActivityStateChangeCallbacks.append(callbackID); +} + +void WebPageProxy::handleAcceptedCandidate(WebCore::TextCheckingResult acceptedCandidate) +{ + m_process->send(Messages::WebPage::HandleAcceptedCandidate(acceptedCandidate), m_pageID); +} + +void WebPageProxy::didHandleAcceptedCandidate() +{ + m_pageClient.didHandleAcceptedCandidate(); +} + +void WebPageProxy::setHeaderBannerHeightForTesting(int height) +{ + m_process->send(Messages::WebPage::SetHeaderBannerHeightForTesting(height), m_pageID); +} + +void WebPageProxy::setFooterBannerHeightForTesting(int height) +{ + m_process->send(Messages::WebPage::SetFooterBannerHeightForTesting(height), m_pageID); +} + +#endif + +void WebPageProxy::imageOrMediaDocumentSizeChanged(const WebCore::IntSize& newSize) +{ + m_uiClient->imageOrMediaDocumentSizeChanged(newSize); +} + +void WebPageProxy::setShouldDispatchFakeMouseMoveEvents(bool shouldDispatchFakeMouseMoveEvents) +{ + m_process->send(Messages::WebPage::SetShouldDispatchFakeMouseMoveEvents(shouldDispatchFakeMouseMoveEvents), m_pageID); +} + +void WebPageProxy::handleAutoFillButtonClick(const UserData& userData) +{ + m_uiClient->didClickAutoFillButton(*this, m_process->transformHandlesToObjects(userData.object()).get()); +} + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) +void WebPageProxy::addPlaybackTargetPickerClient(uint64_t contextId) +{ + m_pageClient.mediaSessionManager().addPlaybackTargetPickerClient(*this, contextId); +} + +void WebPageProxy::removePlaybackTargetPickerClient(uint64_t contextId) +{ + m_pageClient.mediaSessionManager().removePlaybackTargetPickerClient(*this, contextId); +} + +void WebPageProxy::showPlaybackTargetPicker(uint64_t contextId, const WebCore::FloatRect& rect, bool hasVideo) +{ + m_pageClient.mediaSessionManager().showPlaybackTargetPicker(*this, contextId, m_pageClient.rootViewToScreen(IntRect(rect)), hasVideo); +} + +void WebPageProxy::playbackTargetPickerClientStateDidChange(uint64_t contextId, WebCore::MediaProducer::MediaStateFlags state) +{ + m_pageClient.mediaSessionManager().clientStateDidChange(*this, contextId, state); +} + +void WebPageProxy::setMockMediaPlaybackTargetPickerEnabled(bool enabled) +{ + m_pageClient.mediaSessionManager().setMockMediaPlaybackTargetPickerEnabled(enabled); +} + +void WebPageProxy::setMockMediaPlaybackTargetPickerState(const String& name, WebCore::MediaPlaybackTargetContext::State state) +{ + m_pageClient.mediaSessionManager().setMockMediaPlaybackTargetPickerState(name, state); +} + +void WebPageProxy::setPlaybackTarget(uint64_t contextId, Ref<MediaPlaybackTarget>&& target) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::PlaybackTargetSelected(contextId, target->targetContext()), m_pageID); +} + +void WebPageProxy::externalOutputDeviceAvailableDidChange(uint64_t contextId, bool available) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::PlaybackTargetAvailabilityDidChange(contextId, available), m_pageID); +} + +void WebPageProxy::setShouldPlayToPlaybackTarget(uint64_t contextId, bool shouldPlay) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetShouldPlayToPlaybackTarget(contextId, shouldPlay), m_pageID); +} +#endif + +void WebPageProxy::didChangeBackgroundColor() +{ + m_pageClient.didChangeBackgroundColor(); +} + +void WebPageProxy::clearWheelEventTestTrigger() +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::ClearWheelEventTestTrigger(), m_pageID); +} + +void WebPageProxy::callAfterNextPresentationUpdate(std::function<void (CallbackBase::Error)> callback) +{ + if (!isValid() || !m_drawingArea) { + callback(CallbackBase::Error::OwnerWasInvalidated); + return; + } + + m_drawingArea->dispatchAfterEnsuringDrawing(callback); +} + +void WebPageProxy::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument) +{ + if (m_shouldScaleViewToFitDocument == shouldScaleViewToFitDocument) + return; + + m_shouldScaleViewToFitDocument = shouldScaleViewToFitDocument; + + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetShouldScaleViewToFitDocument(shouldScaleViewToFitDocument), m_pageID); +} + +void WebPageProxy::didRestoreScrollPosition() +{ + m_pageClient.didRestoreScrollPosition(); +} + +void WebPageProxy::getLoadDecisionForIcon(const WebCore::LinkIcon& icon, uint64_t loadIdentifier) +{ + if (!m_iconLoadingClient) + return; + + m_iconLoadingClient->getLoadDecisionForIcon(icon, [this, protectedThis = RefPtr<WebPageProxy>(this), loadIdentifier](std::function<void (API::Data*, CallbackBase::Error)> callbackFunction) { + if (!isValid()) { + if (callbackFunction) + callbackFunction(nullptr, CallbackBase::Error::Unknown); + return; + } + + bool decision = (bool)callbackFunction; + uint64_t newCallbackIdentifier = decision ? m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken()) : 0; + + m_process->send(Messages::WebPage::DidGetLoadDecisionForIcon(decision, loadIdentifier, newCallbackIdentifier), m_pageID); + }); +} + +void WebPageProxy::finishedLoadingIcon(uint64_t callbackIdentifier, const IPC::DataReference& data) +{ + dataCallback(data, callbackIdentifier); +} + +void WebPageProxy::setResourceCachingDisabled(bool disabled) +{ + if (m_isResourceCachingDisabled == disabled) + return; + + m_isResourceCachingDisabled = disabled; + + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetResourceCachingDisabled(disabled), m_pageID); +} + +WebCore::UserInterfaceLayoutDirection WebPageProxy::userInterfaceLayoutDirection() +{ + return m_pageClient.userInterfaceLayoutDirection(); +} + +void WebPageProxy::setUserInterfaceLayoutDirection(WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection) +{ + if (!isValid()) + return; + + m_process->send(Messages::WebPage::SetUserInterfaceLayoutDirection(static_cast<uint32_t>(userInterfaceLayoutDirection)), m_pageID); +} + +void WebPageProxy::hideValidationMessage() +{ +#if PLATFORM(COCOA) + m_validationBubble = nullptr; +#endif +} + +#if ENABLE(POINTER_LOCK) +void WebPageProxy::requestPointerLock() +{ + ASSERT(!m_isPointerLockPending); + ASSERT(!m_isPointerLocked); + m_isPointerLockPending = true; + + if (!isViewVisible() || !(m_activityState & ActivityState::IsFocused)) { + didDenyPointerLock(); + return; + } + m_uiClient->requestPointerLock(this); +} + +void WebPageProxy::didAllowPointerLock() +{ + ASSERT(m_isPointerLockPending && !m_isPointerLocked); + m_isPointerLocked = true; + m_isPointerLockPending = false; +#if PLATFORM(MAC) + CGDisplayHideCursor(CGMainDisplayID()); + CGAssociateMouseAndMouseCursorPosition(false); +#endif + m_process->send(Messages::WebPage::DidAcquirePointerLock(), m_pageID); +} + +void WebPageProxy::didDenyPointerLock() +{ + ASSERT(m_isPointerLockPending && !m_isPointerLocked); + m_isPointerLockPending = false; + m_process->send(Messages::WebPage::DidNotAcquirePointerLock(), m_pageID); +} + +void WebPageProxy::requestPointerUnlock() +{ + if (m_isPointerLocked) { +#if PLATFORM(MAC) + CGAssociateMouseAndMouseCursorPosition(true); + CGDisplayShowCursor(CGMainDisplayID()); +#endif + m_uiClient->didLosePointerLock(this); + m_process->send(Messages::WebPage::DidLosePointerLock(), m_pageID); + } + + if (m_isPointerLockPending) { + m_uiClient->didLosePointerLock(this); + m_process->send(Messages::WebPage::DidNotAcquirePointerLock(), m_pageID); + } + + m_isPointerLocked = false; + m_isPointerLockPending = false; +} +#endif + + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index ae0a5a543..8436c2485 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,88 +23,124 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebPageProxy_h -#define WebPageProxy_h +#pragma once #include "APIObject.h" -#include "APISession.h" +#include "AssistedNodeInformation.h" #include "AutoCorrectionCallback.h" #include "Connection.h" +#include "ContextMenuContextData.h" +#include "DownloadID.h" #include "DragControllerAction.h" #include "DrawingAreaProxy.h" +#include "EditingRange.h" #include "EditorState.h" #include "GeolocationPermissionRequestManagerProxy.h" -#include "InteractionInformationAtPosition.h" #include "LayerTreeContext.h" #include "MessageSender.h" #include "NotificationPermissionRequestManagerProxy.h" #include "PageLoadState.h" -#include "PlatformProcessIdentifier.h" +#include "ProcessThrottler.h" #include "SandboxExtension.h" #include "ShareableBitmap.h" +#include "UserMediaPermissionRequestManagerProxy.h" +#include "VisibleContentRectUpdateInfo.h" #include "WKBase.h" #include "WKPagePrivate.h" #include "WebColorPicker.h" #include "WebContextMenuItemData.h" #include "WebCoreArgumentCoders.h" -#include "WebFindClient.h" -#include "WebFormClient.h" #include "WebFrameProxy.h" -#include "WebHistoryClient.h" -#include "WebHitTestResult.h" -#include "WebPageContextMenuClient.h" #include "WebPageCreationParameters.h" +#include "WebPageDiagnosticLoggingClient.h" +#include "WebPageInjectedBundleClient.h" +#include "WebPaymentCoordinatorProxy.h" +#include "WebPreferences.h" #include <WebCore/AlternativeTextClient.h> // FIXME: Needed by WebPageProxyMessages.h for DICTATION_ALTERNATIVES. #include "WebPageProxyMessages.h" #include "WebPopupMenuProxy.h" -#include "WebUIClient.h" +#include "WebProcessLifetimeTracker.h" +#include "WebsitePolicies.h" +#include <WebCore/ActivityState.h> #include <WebCore/Color.h> #include <WebCore/DragActions.h> -#include <WebCore/DragSession.h> +#include <WebCore/EventTrackingRegions.h> +#include <WebCore/FrameLoaderTypes.h> #include <WebCore/HitTestResult.h> +#include <WebCore/MediaProducer.h> #include <WebCore/Page.h> #include <WebCore/PlatformScreen.h> #include <WebCore/ScrollTypes.h> +#include <WebCore/SearchPopupMenu.h> #include <WebCore/TextChecking.h> #include <WebCore/TextGranularity.h> -#include <WebCore/ViewState.h> +#include <WebCore/UserInterfaceLayoutDirection.h> +#include <WebCore/VisibleSelection.h> +#include <memory> #include <wtf/HashMap.h> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/Ref.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> #include <wtf/text/WTFString.h> +OBJC_CLASS NSView; +OBJC_CLASS _WKRemoteObjectRegistry; + #if ENABLE(DRAG_SUPPORT) #include <WebCore/DragActions.h> -#include <WebCore/DragSession.h> #endif #if ENABLE(TOUCH_EVENTS) #include "NativeWebTouchEvent.h" #endif -#if PLATFORM(EFL) -#include "WKPageEfl.h" -#include "WebUIPopupMenuClient.h" -#include <Evas.h> +#if PLATFORM(COCOA) +#include "LayerRepresentation.h" #endif #if PLATFORM(MAC) -#include <WebCore/PlatformLayer.h> +#include "AttributedString.h" +#endif + +#if PLATFORM(IOS) +#include "ProcessThrottler.h" +#endif + +#if PLATFORM(GTK) +#include "ArgumentCodersGtk.h" +#endif + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) +#include <WebCore/MediaPlaybackTargetPicker.h> +#include <WebCore/WebMediaSessionManagerClient.h> +#endif + +#if ENABLE(MEDIA_SESSION) +namespace WebCore { +class MediaSessionMetadata; +} #endif namespace API { +class ContextMenuClient; +class FindClient; +class FindMatchesClient; +class FormClient; +class FullscreenClient; +class HistoryClient; +class IconLoadingClient; class LoaderClient; +class Navigation; +class NavigationClient; class PolicyClient; +class UIClient; class URLRequest; } namespace IPC { -class ArgumentDecoder; +class Decoder; class Connection; } @@ -116,17 +152,24 @@ class FloatRect; class GraphicsLayer; class IntSize; class ProtectionSpace; +class RunLoopObserver; class SharedBuffer; +class TextIndicator; +class ValidationBubble; + +struct DictionaryPopupInfo; +struct ExceptionDetails; struct FileChooserSettings; +struct MediaConstraintsData; +struct SecurityOriginData; struct TextAlternativeWithRange; struct TextCheckingResult; struct ViewportAttributes; struct WindowFeatures; -} -#if USE(APPKIT) -OBJC_CLASS WKView; -#endif +enum class HasInsecureContent; +enum class ShouldSample; +} #if PLATFORM(GTK) typedef GtkWidget* PlatformWidget; @@ -134,29 +177,45 @@ typedef GtkWidget* PlatformWidget; namespace WebKit { +enum HiddenPageThrottlingAutoIncreasesCounterType { }; +typedef RefCounter<HiddenPageThrottlingAutoIncreasesCounterType> HiddenPageThrottlingAutoIncreasesCounter; + class CertificateInfo; +class NativeWebGestureEvent; class NativeWebKeyboardEvent; class NativeWebMouseEvent; class NativeWebWheelEvent; class PageClient; +class RemoteLayerTreeScrollingPerformanceData; +class RemoteLayerTreeTransaction; class RemoteScrollingCoordinatorProxy; -class StringPairVector; +class UserData; +class ViewSnapshot; +class VisitedLinkStore; class WebBackForwardList; class WebBackForwardListItem; -class WebColorPickerResultListenerProxy; class WebContextMenuProxy; class WebEditCommandProxy; class WebFullScreenManagerProxy; +class WebPlaybackSessionManagerProxy; +class WebNavigationState; +class WebVideoFullscreenManagerProxy; class WebKeyboardEvent; class WebMouseEvent; class WebOpenPanelResultListenerProxy; class WebPageGroup; class WebProcessProxy; +class WebUserContentControllerProxy; class WebWheelEvent; +class WebsiteDataStore; +class GamepadData; + struct AttributedString; struct ColorSpaceData; -struct DictionaryPopupInfo; +struct EditingRange; struct EditorState; +struct InteractionInformationRequest; +struct LoadParameters; struct PlatformPopupMenuData; struct PrintInfo; struct WebPopupItem; @@ -165,11 +224,21 @@ struct WebPopupItem; class WebVibrationProxy; #endif -typedef GenericCallback<WKStringRef, StringImpl*> StringCallback; -typedef GenericCallback<WKSerializedScriptValueRef, WebSerializedScriptValue*> ScriptValueCallback; +#if USE(QUICK_LOOK) +class QuickLookDocumentData; +#endif + +typedef GenericCallback<uint64_t> UnsignedCallback; +typedef GenericCallback<EditingRange> EditingRangeCallback; +typedef GenericCallback<const String&> StringCallback; +typedef GenericCallback<API::SerializedScriptValue*, bool, const WebCore::ExceptionDetails&> ScriptValueCallback; + +enum VisibleWebPageCounterType { }; +using VisibleWebPageCounter = RefCounter<VisibleWebPageCounterType>; +using VisibleWebPageToken = VisibleWebPageCounter::Token; #if PLATFORM(GTK) -typedef GenericCallback<WKErrorRef> PrintFinishedCallback; +typedef GenericCallback<API::Error*> PrintFinishedCallback; #endif #if ENABLE(TOUCH_EVENTS) @@ -183,179 +252,88 @@ struct QueuedTouchEvents { }; #endif -// FIXME: Make a version of CallbackBase with three arguments, and define ValidateCommandCallback as a specialization. -class ValidateCommandCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(WKStringRef, bool, int32_t, WKErrorRef, void*); +typedef GenericCallback<const String&, bool, int32_t> ValidateCommandCallback; +typedef GenericCallback<const WebCore::IntRect&, const EditingRange&> RectForCharacterRangeCallback; - static PassRefPtr<ValidateCommandCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new ValidateCommandCallback(context, callback)); - } - - virtual ~ValidateCommandCallback() - { - ASSERT(!m_callback); - } - - void performCallbackWithReturnValue(StringImpl* returnValue1, bool returnValue2, int returnValue3) - { - ASSERT(m_callback); - - m_callback(toAPI(returnValue1), returnValue2, returnValue3, 0, context()); - - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - m_callback(0, 0, 0, toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - - ValidateCommandCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - } - - CallbackFunction m_callback; -}; +#if PLATFORM(MAC) +typedef GenericCallback<const AttributedString&, const EditingRange&> AttributedStringForCharacterRangeCallback; +typedef GenericCallback<const String&, double, bool> FontAtSelectionCallback; +#endif #if PLATFORM(IOS) -class GestureCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, WKErrorRef, void*); - - static PassRefPtr<GestureCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new GestureCallback(context, callback)); - } - - virtual ~GestureCallback() - { - ASSERT(!m_callback); - } - - void performCallbackWithReturnValue(const WebCore::IntPoint& returnValue1, uint32_t returnValue2, uint32_t returnValue3, uint32_t returnValue4) - { - ASSERT(m_callback); - - m_callback(returnValue1, returnValue2, returnValue3, returnValue4, 0, context()); - - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - m_callback(WebCore::IntPoint(), 0, 0, 0, toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - - GestureCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - ASSERT(m_callback); - } - - CallbackFunction m_callback; +typedef GenericCallback<const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t> GestureCallback; +typedef GenericCallback<const WebCore::IntPoint&, uint32_t, uint32_t> TouchesCallback; +typedef GenericCallback<const Vector<WebCore::SelectionRect>&> SelectionRectsCallback; +struct NodeAssistanceArguments { + AssistedNodeInformation m_nodeInformation; + bool m_userIsInteracting; + bool m_blurPreviousNode; + RefPtr<API::Object> m_userData; }; -class TouchesCallback : public CallbackBase { -public: - typedef void (*CallbackFunction)(const WebCore::IntPoint&, uint32_t, WKErrorRef, void*); - - static PassRefPtr<TouchesCallback> create(void* context, CallbackFunction callback) - { - return adoptRef(new TouchesCallback(context, callback)); - } - - virtual ~TouchesCallback() - { - ASSERT(!m_callback); - } - - void performCallbackWithReturnValue(const WebCore::IntPoint& returnValue1, uint32_t returnValue2) - { - ASSERT(m_callback); - - m_callback(returnValue1, returnValue2, 0, context()); - - m_callback = 0; - } - - void invalidate() - { - ASSERT(m_callback); - - RefPtr<API::Error> error = API::Error::create(); - m_callback(WebCore::IntPoint(), 0, toAPI(error.get()), context()); - - m_callback = 0; - } - -private: - - TouchesCallback(void* context, CallbackFunction callback) - : CallbackBase(context) - , m_callback(callback) - { - ASSERT(m_callback); - } - - CallbackFunction m_callback; -}; +using DrawToPDFCallback = GenericCallback<const IPC::DataReference&>; #endif -struct WebPageConfiguration { - WebPageGroup* pageGroup = nullptr; - API::Session* session = nullptr; - WebPageProxy* relatedPage = nullptr; -}; +#if PLATFORM(COCOA) +typedef GenericCallback<const WebCore::MachSendRight&> MachSendRightCallback; +#endif class WebPageProxy : public API::ObjectImpl<API::Object::Type::Page> #if ENABLE(INPUT_TYPE_COLOR) , public WebColorPicker::Client #endif +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + , public WebCore::WebMediaSessionManagerClient +#endif , public WebPopupMenuProxy::Client , public IPC::MessageReceiver , public IPC::MessageSender { public: - static PassRefPtr<WebPageProxy> create(PageClient&, WebProcessProxy&, uint64_t pageID, const WebPageConfiguration&); + static Ref<WebPageProxy> create(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&); virtual ~WebPageProxy(); - void setSession(API::Session&); + const API::PageConfiguration& configuration() const; uint64_t pageID() const { return m_pageID; } - uint64_t sessionID() const { return m_session->getID(); } + WebCore::SessionID sessionID() const { return m_sessionID; } WebFrameProxy* mainFrame() const { return m_mainFrame.get(); } WebFrameProxy* focusedFrame() const { return m_focusedFrame.get(); } WebFrameProxy* frameSetLargestFrame() const { return m_frameSetLargestFrame.get(); } DrawingAreaProxy* drawingArea() const { return m_drawingArea.get(); } - + + WebNavigationState& navigationState() { return *m_navigationState.get(); } + + WebsiteDataStore& websiteDataStore() { return m_websiteDataStore; } + +#if ENABLE(DATA_DETECTION) + NSArray *dataDetectionResults() { return m_dataDetectionResults.get(); } +#endif + #if ENABLE(ASYNC_SCROLLING) RemoteScrollingCoordinatorProxy* scrollingCoordinatorProxy() const { return m_scrollingCoordinatorProxy.get(); } #endif - WebBackForwardList& backForwardList() { return m_backForwardList.get(); } + WebBackForwardList& backForwardList() { return m_backForwardList; } + + bool addsVisitedLinks() const { return m_addsVisitedLinks; } + void setAddsVisitedLinks(bool addsVisitedLinks) { m_addsVisitedLinks = addsVisitedLinks; } + + void fullscreenMayReturnToInline(); + void didEnterFullscreen(); + void didExitFullscreen(); -#if ENABLE(INSPECTOR) - WebInspectorProxy* inspector(); + WebInspectorProxy* inspector() const; + + bool isControlledByAutomation() const { return m_controlledByAutomation; } + void setControlledByAutomation(bool); + +#if ENABLE(REMOTE_INSPECTOR) + bool allowsRemoteInspection() const { return m_allowsRemoteInspection; } + void setAllowsRemoteInspection(bool); + String remoteInspectionNameOverride() const { return m_remoteInspectionNameOverride; } + void setRemoteInspectionNameOverride(const String&); #endif #if ENABLE(VIBRATION) @@ -364,20 +342,43 @@ public: #if ENABLE(FULLSCREEN_API) WebFullScreenManagerProxy* fullScreenManager(); + + API::FullscreenClient& fullscreenClient() const { return *m_fullscreenClient; } + void setFullscreenClient(std::unique_ptr<API::FullscreenClient>); +#endif +#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + WebPlaybackSessionManagerProxy* playbackSessionManager(); + WebVideoFullscreenManagerProxy* videoFullscreenManager(); #endif -#if ENABLE(CONTEXT_MENUS) - void initializeContextMenuClient(const WKPageContextMenuClientBase*); +#if PLATFORM(IOS) + bool allowsMediaDocumentInlinePlayback() const; + void setAllowsMediaDocumentInlinePlayback(bool); #endif - void initializeFindClient(const WKPageFindClientBase*); - void initializeFindMatchesClient(const WKPageFindMatchesClientBase*); - void initializeFormClient(const WKPageFormClientBase*); + +#if ENABLE(CONTEXT_MENUS) + API::ContextMenuClient& contextMenuClient() { return *m_contextMenuClient; } + void setContextMenuClient(std::unique_ptr<API::ContextMenuClient>); +#endif + API::FindClient& findClient() { return *m_findClient; } + void setFindClient(std::unique_ptr<API::FindClient>); + API::FindMatchesClient& findMatchesClient() { return *m_findMatchesClient; } + void setFindMatchesClient(std::unique_ptr<API::FindMatchesClient>); + API::DiagnosticLoggingClient& diagnosticLoggingClient() { return *m_diagnosticLoggingClient; } + void setDiagnosticLoggingClient(std::unique_ptr<API::DiagnosticLoggingClient>); + void setFormClient(std::unique_ptr<API::FormClient>); + void setNavigationClient(std::unique_ptr<API::NavigationClient>); + void setHistoryClient(std::unique_ptr<API::HistoryClient>); void setLoaderClient(std::unique_ptr<API::LoaderClient>); void setPolicyClient(std::unique_ptr<API::PolicyClient>); - void initializeUIClient(const WKPageUIClientBase*); -#if PLATFORM(EFL) - void initializeUIPopupMenuClient(const WKPageUIPopupMenuClientBase*); -#endif + void setInjectedBundleClient(const WKPageInjectedBundleClientBase*); + WebPageInjectedBundleClient* injectedBundleClient() { return m_injectedBundleClient.get(); } + + API::UIClient& uiClient() { return *m_uiClient; } + void setUIClient(std::unique_ptr<API::UIClient>); + + API::IconLoadingClient& iconLoadingClient() { return *m_iconLoadingClient; } + void setIconLoadingClient(std::unique_ptr<API::IconLoadingClient>); void initializeWebPage(); @@ -385,76 +386,84 @@ public: bool tryClose(); bool isClosed() const { return m_isClosed; } - void loadRequest(const WebCore::ResourceRequest&, API::Object* userData = nullptr); - void loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr); - void loadData(API::Data*, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr); - void loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData = nullptr); + void setIsUsingHighPerformanceWebGL(bool value) { m_isUsingHighPerformanceWebGL = value; } + bool isUsingHighPerformanceWebGL() const { return m_isUsingHighPerformanceWebGL; } + + void closePage(bool stopResponsivenessTimer); + + void addPlatformLoadParameters(LoadParameters&); + RefPtr<API::Navigation> loadRequest(const WebCore::ResourceRequest&, WebCore::ShouldOpenExternalURLsPolicy = WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes, API::Object* userData = nullptr); + RefPtr<API::Navigation> loadFile(const String& fileURL, const String& resourceDirectoryURL, API::Object* userData = nullptr); + RefPtr<API::Navigation> loadData(API::Data*, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr); + RefPtr<API::Navigation> loadHTMLString(const String& htmlString, const String& baseURL, API::Object* userData = nullptr); void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL, API::Object* userData = nullptr); void loadPlainTextString(const String&, API::Object* userData = nullptr); void loadWebArchiveData(API::Data*, API::Object* userData = nullptr); + void navigateToPDFLinkWithSimulatedClick(const String& url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint); void stopLoading(); - void reload(bool reloadFromOrigin); + RefPtr<API::Navigation> reload(bool reloadFromOrigin, bool contentBlockersEnabled); - void goForward(); - void goBack(); + RefPtr<API::Navigation> goForward(); + RefPtr<API::Navigation> goBack(); - void goToBackForwardItem(WebBackForwardListItem*); + RefPtr<API::Navigation> goToBackForwardItem(WebBackForwardListItem*); void tryRestoreScrollPosition(); - void didChangeBackForwardList(WebBackForwardListItem* addedItem, Vector<RefPtr<API::Object>>* removedItems); - void willGoToBackForwardListItem(uint64_t itemID, IPC::MessageDecoder&); + void didChangeBackForwardList(WebBackForwardListItem* addedItem, Vector<RefPtr<WebBackForwardListItem>> removed); + void willGoToBackForwardListItem(uint64_t itemID, const UserData&); + + bool shouldKeepCurrentBackForwardListItemInList(WebBackForwardListItem*); bool willHandleHorizontalScrollEvents() const; + void updateWebsitePolicies(const WebsitePolicies&); + bool canShowMIMEType(const String& mimeType); bool drawsBackground() const { return m_drawsBackground; } void setDrawsBackground(bool); - bool drawsTransparentBackground() const { return m_drawsTransparentBackground; } - void setDrawsTransparentBackground(bool); + float topContentInset() const { return m_topContentInset; } + void setTopContentInset(float); WebCore::Color underlayColor() const { return m_underlayColor; } void setUnderlayColor(const WebCore::Color&); + // At this time, m_pageExtendedBackgroundColor can be set via pageExtendedBackgroundColorDidChange() which is a message + // from the UIProcess, or by didCommitLayerTree(). When PLATFORM(MAC) adopts UI side compositing, we should get rid of + // the message entirely. + WebCore::Color pageExtendedBackgroundColor() const { return m_pageExtendedBackgroundColor; } + void viewWillStartLiveResize(); void viewWillEndLiveResize(); - void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&); - void setWindowResizerSize(const WebCore::IntSize&); + void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&, std::function<void (CallbackBase::Error)>); void clearSelection(); + void restoreSelectionInFocusedEditableElement(); + + void setViewNeedsDisplay(const WebCore::Region&); + void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, bool isProgrammaticScroll); + + void setDelegatesScrolling(bool delegatesScrolling) { m_delegatesScrolling = delegatesScrolling; } + bool delegatesScrolling() const { return m_delegatesScrolling; } - void setViewNeedsDisplay(const WebCore::IntRect&); - void displayView(); - bool canScrollView(); - void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); + enum class ActivityStateChangeDispatchMode { Deferrable, Immediate }; + void activityStateDidChange(WebCore::ActivityState::Flags mayHaveChanged, bool wantsSynchronousReply = false, ActivityStateChangeDispatchMode = ActivityStateChangeDispatchMode::Deferrable); + bool isInWindow() const { return m_activityState & WebCore::ActivityState::IsInWindow; } + void waitForDidUpdateActivityState(); + void didUpdateActivityState() { m_waitingForDidUpdateActivityState = false; } - enum class WantsReplyOrNot { DoesNotWantReply, DoesWantReply }; - void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, WantsReplyOrNot = WantsReplyOrNot::DoesNotWantReply); - bool isInWindow() const { return m_viewState & WebCore::ViewState::IsInWindow; } - void waitForDidUpdateViewState(); + void layerHostingModeDidChange(); WebCore::IntSize viewSize() const; - bool isViewVisible() const { return m_viewState & WebCore::ViewState::IsVisible; } + bool isViewVisible() const { return m_activityState & WebCore::ActivityState::IsVisible; } bool isViewWindowActive() const; - bool isProcessSuppressible() const; - void executeEditCommand(const String& commandName); - void validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback>); -#if PLATFORM(IOS) - void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback>); - void updateSelectionWithTouches(const WebCore::IntPoint, uint32_t touches, bool baseIsStart, PassRefPtr<TouchesCallback>); - void selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback>); - void extendSelection(WebCore::TextGranularity); - void requestAutocorrectionData(const String& textForAutocorrection, PassRefPtr<AutocorrectionDataCallback>); - void applyAutocorrection(const String& correction, const String& originalText, PassRefPtr<StringCallback>); - void requestAutocorrectionContext(PassRefPtr<AutocorrectionContextCallback>); - void getAutocorrectionContext(String& contextBefore, String& markedText, String& selectedText, String& contextAfter, uint64_t& location, uint64_t& length); - void didReceivePositionInformation(const InteractionInformationAtPosition&); - void getPositionInformation(const WebCore::IntPoint&, InteractionInformationAtPosition&); - void requestPositionInformation(const WebCore::IntPoint&); -#endif + void addMIMETypeWithCustomContentProvider(const String& mimeType); + + void executeEditCommand(const String& commandName, const String& argument = String()); + void validateCommand(const String& commandName, std::function<void (const String&, bool, int32_t, CallbackBase::Error)>); const EditorState& editorState() const { return m_editorState; } bool canDelete() const { return hasSelectedRange() && isContentEditable(); } @@ -463,11 +472,106 @@ public: bool maintainsInactiveSelection() const { return m_maintainsInactiveSelection; } void setMaintainsInactiveSelection(bool); -#if USE(TILED_BACKING_STORE) + void setEditable(bool); + bool isEditable() const { return m_isEditable; } + +#if PLATFORM(IOS) + void executeEditCommand(const String& commandName, std::function<void (CallbackBase::Error)>); + double displayedContentScale() const { return m_lastVisibleContentRectUpdate.scale(); } + const WebCore::FloatRect& exposedContentRect() const { return m_lastVisibleContentRectUpdate.exposedContentRect(); } + const WebCore::FloatRect& unobscuredContentRect() const { return m_lastVisibleContentRectUpdate.unobscuredContentRect(); } + bool inStableState() const { return m_lastVisibleContentRectUpdate.inStableState(); } + const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds() const { return m_lastVisibleContentRectUpdate.unobscuredContentRectRespectingInputViewBounds(); } + // When visual viewports are enabled, this is the layout viewport rect. + const WebCore::FloatRect& customFixedPositionRect() const { return m_lastVisibleContentRectUpdate.customFixedPositionRect(); } + + void updateVisibleContentRects(const VisibleContentRectUpdateInfo&); + void resendLastVisibleContentRects(); + + enum class UnobscuredRectConstraint { ConstrainedToDocumentRect, Unconstrained }; + WebCore::FloatRect computeCustomFixedPositionRect(const WebCore::FloatRect& unobscuredContentRect, const WebCore::FloatRect& unobscuredContentRectRespectingInputViewBounds, const WebCore::FloatRect& currentCustomFixedPositionRect, double displayedContentScale, UnobscuredRectConstraint = UnobscuredRectConstraint::Unconstrained, bool visualViewportEnabled = false) const; + + void overflowScrollViewWillStartPanGesture(); + void overflowScrollViewDidScroll(); + void overflowScrollWillStartScroll(); + void overflowScrollDidEndScroll(); + + void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, double targetScale, int32_t deviceOrientation); + void synchronizeDynamicViewportUpdate(); + + void setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize&); + void setMaximumUnobscuredSize(const WebCore::FloatSize&); + void setDeviceOrientation(int32_t); + int32_t deviceOrientation() const { return m_deviceOrientation; } + void willCommitLayerTree(uint64_t transactionID); + + void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithAssistedNode, std::function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>); + void updateSelectionWithTouches(const WebCore::IntPoint, uint32_t touches, bool baseIsStart, std::function<void (const WebCore::IntPoint&, uint32_t, uint32_t, CallbackBase::Error)>); + void selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, std::function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>); + void updateBlockSelectionWithTouch(const WebCore::IntPoint, uint32_t touch, uint32_t handlePosition); + void extendSelection(WebCore::TextGranularity); + void selectWordBackward(); + void moveSelectionByOffset(int32_t offset, std::function<void (CallbackBase::Error)>); + void selectTextWithGranularityAtPoint(const WebCore::IntPoint, WebCore::TextGranularity, bool isInteractingWithAssistedNode, std::function<void (CallbackBase::Error)>); + void selectPositionAtPoint(const WebCore::IntPoint, bool isInteractingWithAssistedNode, std::function<void (CallbackBase::Error)>); + void selectPositionAtBoundaryWithDirection(const WebCore::IntPoint, WebCore::TextGranularity, WebCore::SelectionDirection, bool isInteractingWithAssistedNode, std::function<void (CallbackBase::Error)>); + void moveSelectionAtBoundaryWithDirection(WebCore::TextGranularity, WebCore::SelectionDirection, std::function<void(CallbackBase::Error)>); + void beginSelectionInDirection(WebCore::SelectionDirection, std::function<void (uint64_t, CallbackBase::Error)>); + void updateSelectionWithExtentPoint(const WebCore::IntPoint, bool isInteractingWithAssistedNode, std::function<void (uint64_t, CallbackBase::Error)>); + void updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint, WebCore::TextGranularity, bool isInteractingWithAssistedNode, std::function<void(uint64_t, CallbackBase::Error)>); + void requestAutocorrectionData(const String& textForAutocorrection, std::function<void (const Vector<WebCore::FloatRect>&, const String&, double, uint64_t, CallbackBase::Error)>); + void applyAutocorrection(const String& correction, const String& originalText, std::function<void (const String&, CallbackBase::Error)>); + bool applyAutocorrection(const String& correction, const String& originalText); + void requestAutocorrectionContext(std::function<void (const String&, const String&, const String&, const String&, uint64_t, uint64_t, CallbackBase::Error)>); + void getAutocorrectionContext(String& contextBefore, String& markedText, String& selectedText, String& contextAfter, uint64_t& location, uint64_t& length); + void requestDictationContext(std::function<void (const String&, const String&, const String&, CallbackBase::Error)>); + void replaceDictatedText(const String& oldText, const String& newText); + void replaceSelectedText(const String& oldText, const String& newText); + void didReceivePositionInformation(const InteractionInformationAtPosition&); + void getPositionInformation(const InteractionInformationRequest&, InteractionInformationAtPosition&); + void requestPositionInformation(const InteractionInformationRequest&); + void startInteractionWithElementAtPosition(const WebCore::IntPoint&); + void stopInteraction(); + void performActionOnElement(uint32_t action); + void saveImageToLibrary(const SharedMemory::Handle& imageHandle, uint64_t imageSize); + void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold); + void focusNextAssistedNode(bool isForward, std::function<void (CallbackBase::Error)>); + void setAssistedNodeValue(const String&); + void setAssistedNodeValueAsNumber(double); + void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection = false); + void applicationDidEnterBackground(); + void applicationDidFinishSnapshottingAfterEnteringBackground(); + void applicationWillEnterForeground(); + void applicationWillResignActive(); + void applicationDidBecomeActive(); + void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale); + void commitPotentialTapFailed(); + void didNotHandleTapAsClick(const WebCore::IntPoint&); + void disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID); + void contentSizeCategoryDidChange(const String& contentSizeCategory); + void getSelectionContext(std::function<void(const String&, const String&, const String&, CallbackBase::Error)>); + void handleTwoFingerTapAtPoint(const WebCore::IntPoint&, uint64_t requestID); + void setForceAlwaysUserScalable(bool); + void setIsScrollingOrZooming(bool); + void requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity, uint32_t offset, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>); + void requestRectsAtSelectionOffsetWithText(int32_t offset, const String&, std::function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>); +#if ENABLE(DATA_INTERACTION) + void didPerformDataInteractionControllerOperation(); + void didHandleStartDataInteractionRequest(bool started); + void requestStartDataInteraction(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition); +#endif +#endif +#if ENABLE(DATA_DETECTION) + void setDataDetectionResult(const DataDetectionResult&); +#endif + void didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction&); + void layerTreeCommitComplete(); + + bool updateLayoutViewportParameters(const WebKit::RemoteLayerTreeTransaction&); + +#if USE(COORDINATED_GRAPHICS_MULTIPROCESS) void didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect); -#endif -#if PLATFORM(EFL) - void setThemePath(const String&); + void commitPageTransitionViewport(); #endif #if PLATFORM(GTK) @@ -480,51 +584,72 @@ public: void setInputMethodState(bool enabled); #endif -#if PLATFORM(MAC) +#if PLATFORM (GTK) && HAVE(GTK_GESTURES) + void getCenterForZoomGesture(const WebCore::IntPoint& centerInViewCoordinates, WebCore::IntPoint& center); +#endif + +#if PLATFORM(COCOA) void windowAndViewFramesChanged(const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates); void setMainFrameIsScrollable(bool); - void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); - void confirmComposition(); - void cancelComposition(); - bool insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd); - bool insertDictatedText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives); - void getMarkedRange(uint64_t& location, uint64_t& length); - void getSelectedRange(uint64_t& location, uint64_t& length); - void getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString&); - uint64_t characterIndexForPoint(const WebCore::IntPoint); - WebCore::IntRect firstRectForCharacterRange(uint64_t, uint64_t); - bool executeKeypressCommands(const Vector<WebCore::KeypressCommand>&); - void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput); bool shouldDelayWindowOrderingForEvent(const WebMouseEvent&); bool acceptsFirstMouse(int eventNumber, const WebMouseEvent&); - void setAcceleratedCompositingRootLayer(PlatformLayer* rootLayer); - PlatformLayer* acceleratedCompositingRootLayer() const; + void setAcceleratedCompositingRootLayer(LayerOrView*); + LayerOrView* acceleratedCompositingRootLayer() const; -#if USE(APPKIT) - WKView* wkView() const; - void intrinsicContentSizeDidChange(const WebCore::IntSize& intrinsicContentSize); + void insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup = false, EditingRangeIsRelativeTo = EditingRangeIsRelativeTo::EditableRoot, bool suppressSelectionUpdate = false); + void getMarkedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)>); + void getSelectedRangeAsync(std::function<void (EditingRange, CallbackBase::Error)>); + void characterIndexForPointAsync(const WebCore::IntPoint&, std::function<void (uint64_t, CallbackBase::Error)>); + void firstRectForCharacterRangeAsync(const EditingRange&, std::function<void (const WebCore::IntRect&, const EditingRange&, CallbackBase::Error)>); + void setCompositionAsync(const String& text, Vector<WebCore::CompositionUnderline> underlines, const EditingRange& selectionRange, const EditingRange& replacementRange); + void confirmCompositionAsync(); + + void setScrollPerformanceDataCollectionEnabled(bool); + bool scrollPerformanceDataCollectionEnabled() const { return m_scrollPerformanceDataCollectionEnabled; } + RemoteLayerTreeScrollingPerformanceData* scrollingPerformanceData() { return m_scrollingPerformanceData.get(); } +#endif // PLATFORM(COCOA) + +#if PLATFORM(MAC) + void insertDictatedTextAsync(const String& text, const EditingRange& replacementRange, const Vector<WebCore::TextAlternativeWithRange>& dictationAlternatives, bool registerUndoGroup); + void attributedSubstringForCharacterRangeAsync(const EditingRange&, std::function<void (const AttributedString&, const EditingRange&, CallbackBase::Error)>); + void setFont(const String& fontFamily, double fontSize, uint64_t fontTraits); + void fontAtSelection(std::function<void (const String&, double, bool, CallbackBase::Error)>); + + void startWindowDrag(); + NSWindow *platformWindow(); + void rootViewToWindow(const WebCore::IntRect& viewRect, WebCore::IntRect& windowRect); + +#if WK_API_ENABLED + NSView *inspectorAttachmentView(); + _WKRemoteObjectRegistry *remoteObjectRegistry(); #endif + + void intrinsicContentSizeDidChange(const WebCore::IntSize& intrinsicContentSize); + CGRect boundsOfLayerInLayerBackedWindowCoordinates(CALayer *) const; #endif // PLATFORM(MAC) -#if PLATFORM(EFL) - void handleInputMethodKeydown(bool& handled); - void confirmComposition(const String&); - void setComposition(const String&, Vector<WebCore::CompositionUnderline>&, int); - void cancelComposition(); -#endif + #if PLATFORM(GTK) PlatformWidget viewWidget(); -#endif -#if USE(TILED_BACKING_STORE) - void commitPageTransitionViewport(); + const WebCore::Color& backgroundColor() const { return m_backgroundColor; } + void setBackgroundColor(const WebCore::Color& color) { m_backgroundColor = color; } #endif void handleMouseEvent(const NativeWebMouseEvent&); void handleWheelEvent(const NativeWebWheelEvent&); void handleKeyboardEvent(const NativeWebKeyboardEvent&); -#if ENABLE(TOUCH_EVENTS) + +#if ENABLE(MAC_GESTURE_EVENTS) + void handleGestureEvent(const NativeWebGestureEvent&); +#endif + +#if ENABLE(IOS_TOUCH_EVENTS) + void handleTouchEventSynchronously(NativeWebTouchEvent&); + void handleTouchEventAsynchronously(const NativeWebTouchEvent&); + +#elif ENABLE(TOUCH_EVENTS) void handleTouchEvent(const NativeWebTouchEvent&); #endif @@ -550,26 +675,31 @@ public: double estimatedProgress() const; - void terminateProcess(); + enum class TerminationReason { UnresponsiveWhileInBackground, Other }; + void terminateProcess(TerminationReason = TerminationReason::Other); - typedef bool (*WebPageProxySessionStateFilterCallback)(WKPageRef, WKStringRef type, WKTypeRef object, void* context); - PassRefPtr<API::Data> sessionStateData(WebPageProxySessionStateFilterCallback, void* context) const; - void restoreFromSessionStateData(API::Data*); + SessionState sessionState(const std::function<bool (WebBackForwardListItem&)>& = nullptr) const; + RefPtr<API::Navigation> restoreFromSessionState(SessionState, bool navigate); bool supportsTextZoom() const; double textZoomFactor() const { return m_textZoomFactor; } void setTextZoomFactor(double); - double pageZoomFactor() const { return m_pageZoomFactor; } + double pageZoomFactor() const; void setPageZoomFactor(double); void setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor); void scalePage(double scale, const WebCore::IntPoint& origin); - double pageScaleFactor() const { return m_pageScaleFactor; } - + void scalePageInViewCoordinates(double scale, const WebCore::IntPoint& centerInViewCoordinates); + double pageScaleFactor() const; + double viewScaleFactor() const { return m_viewScaleFactor; } + void scaleView(double scale); + void setShouldScaleViewToFitDocument(bool); + float deviceScaleFactor() const; void setIntrinsicDeviceScaleFactor(float); void setCustomDeviceScaleFactor(float); - void windowScreenDidChange(PlatformDisplayID); + void windowScreenDidChange(WebCore::PlatformDisplayID); + void accessibilitySettingsDidChange(); void setUseFixedLayout(bool); void setFixedLayoutSize(const WebCore::IntSize&); @@ -578,9 +708,6 @@ public: void listenForLayoutMilestones(WebCore::LayoutMilestones); - void setVisibilityStatePrerender(); - void didUpdateViewState() { m_waitingForDidUpdateViewState = false; } - bool hasHorizontalScrollbar() const { return m_mainFrameHasHorizontalScrollbar; } bool hasVerticalScrollbar() const { return m_mainFrameHasVerticalScrollbar; } @@ -601,6 +728,14 @@ public: bool rubberBandsAtBottom() const; void setRubberBandsAtBottom(bool); + void setShouldUseImplicitRubberBandControl(bool shouldUseImplicitRubberBandControl) { m_shouldUseImplicitRubberBandControl = shouldUseImplicitRubberBandControl; } + bool shouldUseImplicitRubberBandControl() const { return m_shouldUseImplicitRubberBandControl; } + + void setEnableVerticalRubberBanding(bool); + bool verticalRubberBandingIsEnabled() const; + void setEnableHorizontalRubberBanding(bool); + bool horizontalRubberBandingIsEnabled() const; + void setBackgroundExtendsBeyondPage(bool); bool backgroundExtendsBeyondPage() const; @@ -612,25 +747,30 @@ public: double pageLength() const { return m_pageLength; } void setGapBetweenPages(double); double gapBetweenPages() const { return m_gapBetweenPages; } + void setPaginationLineGridEnabled(bool); + bool paginationLineGridEnabled() const { return m_paginationLineGridEnabled; } unsigned pageCount() const { return m_pageCount; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Called by the web process through a message. void registerWebProcessAccessibilityToken(const IPC::DataReference&); // Called by the UI process when it is ready to send its tokens to the web process. void registerUIProcessAccessibilityTokens(const IPC::DataReference& elemenToken, const IPC::DataReference& windowToken); bool readSelectionFromPasteboard(const String& pasteboardName); String stringSelectionForPasteboard(); - PassRefPtr<WebCore::SharedBuffer> dataSelectionForPasteboard(const String& pasteboardType); + RefPtr<WebCore::SharedBuffer> dataSelectionForPasteboard(const String& pasteboardType); void makeFirstResponder(); ColorSpaceData colorSpace(); #endif - void pageScaleFactorDidChange(double); - void pageZoomFactorDidChange(double); +#if ENABLE(SERVICE_CONTROLS) + void replaceSelectionWithPasteboardData(const Vector<String>& types, const IPC::DataReference&); +#endif - void setMemoryCacheClientCallsEnabled(bool); + void pageScaleFactorDidChange(double); + void pluginScaleFactorDidChange(double); + void pluginZoomFactorDidChange(double); // Find. void findString(const String&, FindOptions, unsigned maxMatchCount); @@ -641,23 +781,29 @@ public: void hideFindUI(); void countStringMatches(const String&, FindOptions, unsigned maxMatchCount); void didCountStringMatches(const String&, uint32_t matchCount); - void setFindIndicator(const WebCore::FloatRect& selectionRectInWindowCoordinates, const Vector<WebCore::FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate); - void didFindString(const String&, uint32_t matchCount); + void setTextIndicator(const WebCore::TextIndicatorData&, uint64_t /* WebCore::TextIndicatorWindowLifetime */ lifetime = 0 /* Permanent */); + void setTextIndicatorAnimationProgress(float); + void clearTextIndicator(); + void didFindString(const String&, const Vector<WebCore::IntRect>&, uint32_t matchCount, int32_t matchIndex); void didFailToFindString(const String&); - void didFindStringMatches(const String&, Vector<Vector<WebCore::IntRect>> matchRects, int32_t firstIndexAfterSelection); + void didFindStringMatches(const String&, const Vector<Vector<WebCore::IntRect>>& matchRects, int32_t firstIndexAfterSelection); + + void getContentsAsString(std::function<void (const String&, CallbackBase::Error)>); + void getBytecodeProfile(std::function<void (const String&, CallbackBase::Error)>); + void getSamplingProfilerOutput(std::function<void (const String&, CallbackBase::Error)>); + void isWebProcessResponsive(std::function<void (bool isWebProcessResponsive)>); - void getContentsAsString(PassRefPtr<StringCallback>); #if ENABLE(MHTML) - void getContentsAsMHTMLData(PassRefPtr<DataCallback>, bool useBinaryEncoding); -#endif - void getMainResourceDataOfFrame(WebFrameProxy*, PassRefPtr<DataCallback>); - void getResourceDataFromFrame(WebFrameProxy*, API::URL*, PassRefPtr<DataCallback>); - void getRenderTreeExternalRepresentation(PassRefPtr<StringCallback>); - void getSelectionOrContentsAsString(PassRefPtr<StringCallback>); - void getSelectionAsWebArchiveData(PassRefPtr<DataCallback>); - void getSourceForFrame(WebFrameProxy*, PassRefPtr<StringCallback>); - void getWebArchiveOfFrame(WebFrameProxy*, PassRefPtr<DataCallback>); - void runJavaScriptInMainFrame(const String&, PassRefPtr<ScriptValueCallback>); + void getContentsAsMHTMLData(std::function<void (API::Data*, CallbackBase::Error)>); +#endif + void getMainResourceDataOfFrame(WebFrameProxy*, std::function<void (API::Data*, CallbackBase::Error)>); + void getResourceDataFromFrame(WebFrameProxy*, API::URL*, std::function<void (API::Data*, CallbackBase::Error)>); + void getRenderTreeExternalRepresentation(std::function<void (const String&, CallbackBase::Error)>); + void getSelectionOrContentsAsString(std::function<void (const String&, CallbackBase::Error)>); + void getSelectionAsWebArchiveData(std::function<void (API::Data*, CallbackBase::Error)>); + void getSourceForFrame(WebFrameProxy*, std::function<void (const String&, CallbackBase::Error)>); + void getWebArchiveOfFrame(WebFrameProxy*, std::function<void (API::Data*, CallbackBase::Error)>); + void runJavaScriptInMainFrame(const String&, std::function<void (API::SerializedScriptValue*, bool hadException, const WebCore::ExceptionDetails&, CallbackBase::Error)> callbackFunction); void forceRepaint(PassRefPtr<VoidCallback>); float headerHeight(WebFrameProxy*); @@ -665,12 +811,13 @@ public: void drawHeader(WebFrameProxy*, const WebCore::FloatRect&); void drawFooter(WebFrameProxy*, const WebCore::FloatRect&); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Dictionary. void performDictionaryLookupAtLocation(const WebCore::FloatPoint&); + void performDictionaryLookupOfCurrentSelection(); #endif - void receivedPolicyDecision(WebCore::PolicyAction, WebFrameProxy*, uint64_t listenerID); + void receivedPolicyDecision(WebCore::PolicyAction, WebFrameProxy&, uint64_t listenerID, API::Navigation* navigationID, const WebsitePolicies&); void backForwardRemovedItem(uint64_t itemID); @@ -679,32 +826,38 @@ public: void dragEntered(WebCore::DragData&, const String& dragStorageName = String()); void dragUpdated(WebCore::DragData&, const String& dragStorageName = String()); void dragExited(WebCore::DragData&, const String& dragStorageName = String()); - void performDrag(WebCore::DragData&, const String& dragStorageName, const SandboxExtension::Handle&, const SandboxExtension::HandleArray&); + void performDragOperation(WebCore::DragData&, const String& dragStorageName, const SandboxExtension::Handle&, const SandboxExtension::HandleArray&); - void didPerformDragControllerAction(WebCore::DragSession); + void didPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted); void dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation); -#if PLATFORM(MAC) - void setDragImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& dragImageHandle, bool isLinkDrag); - void setPromisedData(const String& pasteboardName, const SharedMemory::Handle& imageHandle, uint64_t imageSize, const String& filename, const String& extension, + void dragCancelled(); +#if PLATFORM(COCOA) + void setDragImage(const WebCore::IntPoint& clientPosition, const ShareableBitmap::Handle& dragImageHandle, const WebCore::FloatPoint& dragImageAnchor, bool isLinkDrag); + void setPromisedDataForImage(const String& pasteboardName, const SharedMemory::Handle& imageHandle, uint64_t imageSize, const String& filename, const String& extension, const String& title, const String& url, const String& visibleURL, const SharedMemory::Handle& archiveHandle, uint64_t archiveSize); +#if ENABLE(ATTACHMENT_ELEMENT) + void setPromisedDataForAttachment(const String& pasteboardName, const String& filename, const String& extension, const String& title, const String& url, const String& visibleURL); +#endif #endif #if PLATFORM(GTK) - void startDrag(const WebCore::DragData&, const ShareableBitmap::Handle& dragImage); + void startDrag(WebSelectionData&&, uint64_t dragOperation, const ShareableBitmap::Handle& dragImage); #endif #endif void processDidBecomeUnresponsive(); - void interactionOccurredWhileProcessUnresponsive(); void processDidBecomeResponsive(); void processDidCrash(); + void willChangeProcessIsResponsive(); + void didChangeProcessIsResponsive(); + +#if PLATFORM(IOS) + void processWillBecomeSuspended(); + void processWillBecomeForeground(); +#endif -#if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); -#endif - - void didDraw(); enum UndoOrRedo { Undo, Redo }; void addEditCommand(WebEditCommandProxy*); @@ -712,26 +865,31 @@ public: bool isValidEditCommand(WebEditCommandProxy*); void registerEditCommand(PassRefPtr<WebEditCommandProxy>, UndoOrRedo); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void registerKeypressCommandName(const String& name) { m_knownKeypressCommandNames.add(name); } bool isValidKeypressCommandName(const String& name) const { return m_knownKeypressCommandNames.contains(name); } #endif - WebProcessProxy& process() { return m_process.get(); } - PlatformProcessIdentifier processIdentifier() const; + WebProcessProxy& process() { return m_process; } + pid_t processIdentifier() const; - WebPageGroup& pageGroup() { return m_pageGroup.get(); } + WebPreferences& preferences() { return m_preferences; } + void setPreferences(WebPreferences&); - bool isValid() const; - - PassRefPtr<API::Array> relatedPages() const; + WebPageGroup& pageGroup() { return m_pageGroup; } - const String& urlAtProcessExit() const { return m_urlAtProcessExit; } - FrameLoadState::State loadStateAtProcessExit() const { return m_loadStateAtProcessExit; } + bool isValid() const; #if ENABLE(DRAG_SUPPORT) - WebCore::DragSession dragSession() const { return m_currentDragSession; } - void resetDragOperation() { m_currentDragSession = WebCore::DragSession(); } + WebCore::DragOperation currentDragOperation() const { return m_currentDragOperation; } + bool currentDragIsOverFileInput() const { return m_currentDragIsOverFileInput; } + unsigned currentDragNumberOfFilesToBeAccepted() const { return m_currentDragNumberOfFilesToBeAccepted; } + void resetCurrentDragInformation() + { + m_currentDragOperation = WebCore::DragOperationNone; + m_currentDragIsOverFileInput = false; + m_currentDragNumberOfFilesToBeAccepted = 0; + } #endif void preferencesDidChange(); @@ -739,21 +897,19 @@ public: #if ENABLE(CONTEXT_MENUS) // Called by the WebContextMenuProxy. void contextMenuItemSelected(const WebContextMenuItemData&); + void handleContextMenuKeyEvent(); #endif // Called by the WebOpenPanelResultListenerProxy. +#if PLATFORM(IOS) + void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, const API::Data* iconData); +#endif void didChooseFilesForOpenPanel(const Vector<String>&); void didCancelForOpenPanel(); WebPageCreationParameters creationParameters(); -#if USE(COORDINATED_GRAPHICS) - void findZoomableAreaForPoint(const WebCore::IntPoint&, const WebCore::IntSize&); -#endif - -#if PLATFORM(EFL) || PLATFORM(GTK) void handleDownloadRequest(DownloadProxy*); -#endif void advanceToNextMisspelling(bool startBeforeSelection); void changeSpellingToWord(const String& word); @@ -763,7 +919,7 @@ public: void capitalizeWord(); #endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) bool isSmartInsertDeleteEnabled() const { return m_isSmartInsertDeleteEnabled; } void setSmartInsertDeleteEnabled(bool); #endif @@ -778,22 +934,26 @@ public: void beginPrinting(WebFrameProxy*, const PrintInfo&); void endPrinting(); void computePagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<ComputedPagesCallback>); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void drawRectToImage(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, const WebCore::IntSize&, PassRefPtr<ImageCallback>); void drawPagesToPDF(WebFrameProxy*, const PrintInfo&, uint32_t first, uint32_t count, PassRefPtr<DataCallback>); +#if PLATFORM(IOS) + uint32_t computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo&, DrawToPDFCallback::CallbackFunction&&); + void drawToPDFCallback(const IPC::DataReference& pdfData, uint64_t callbackID); +#endif #elif PLATFORM(GTK) void drawPagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<PrintFinishedCallback>); #endif PageLoadState& pageLoadState() { return m_pageLoadState; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void handleAlternativeTextUIResult(const String& result); #endif void saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data*); void savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const IPC::DataReference&); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void savePDFToTemporaryFolderAndOpenWithNativeApplicationRaw(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID); void savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const IPC::DataReference&, const String& pdfUUID); void openPDFFromTemporaryFolderWithNativeApplication(const String& pdfUUID); @@ -803,28 +963,41 @@ public: uint64_t renderTreeSize() const { return m_renderTreeSize; } - void setShouldSendEventsSynchronously(bool sync) { m_shouldSendEventsSynchronously = sync; }; - void printMainFrame(); void setMediaVolume(float); + void setMuted(WebCore::MediaProducer::MutedStateFlags); void setMayStartMediaWhenInWindow(bool); + bool mayStartMediaWhenInWindow() const { return m_mayStartMediaWhenInWindow; } + +#if ENABLE(MEDIA_SESSION) + bool hasMediaSessionWithActiveMediaElements() const { return m_hasMediaSessionWithActiveMediaElements; } + void handleMediaEvent(WebCore::MediaEventType); + void setVolumeOfMediaElement(double, uint64_t); +#endif + +#if ENABLE(POINTER_LOCK) + void didAllowPointerLock(); + void didDenyPointerLock(); +#endif // WebPopupMenuProxy::Client - virtual NativeWebMouseEvent* currentlyProcessedMouseDownEvent(); + NativeWebMouseEvent* currentlyProcessedMouseDownEvent() override; -#if PLATFORM(GTK) && USE(TEXTURE_MAPPER_GL) - void setAcceleratedCompositingWindowId(uint64_t nativeWindowId); -#endif - - void setSuppressVisibilityUpdates(bool flag) { m_suppressVisibilityUpdates = flag; } + void setSuppressVisibilityUpdates(bool flag); bool suppressVisibilityUpdates() { return m_suppressVisibilityUpdates; } #if PLATFORM(IOS) - void didFinishScrolling(const WebCore::FloatPoint& contentOffset); - void didFinishZooming(float newScale); + void willStartUserTriggeredZooming(); + void potentialTapAtPosition(const WebCore::FloatPoint&, uint64_t& requestID); + void commitPotentialTap(); + void cancelPotentialTap(); void tapHighlightAtPosition(const WebCore::FloatPoint&, uint64_t& requestID); + void handleTap(const WebCore::FloatPoint&); + + void inspectorNodeSearchMovedToPosition(const WebCore::FloatPoint&); + void inspectorNodeSearchEndedAtPosition(const WebCore::FloatPoint&); void blurAssistedNode(); #endif @@ -842,109 +1015,277 @@ public: bool autoSizingShouldExpandToViewHeight() const { return m_autoSizingShouldExpandToViewHeight; } void setAutoSizingShouldExpandToViewHeight(bool); - bool mainFrameInViewSourceMode() const { return m_mainFrameInViewSourceMode; } - void setMainFrameInViewSourceMode(bool); - void didReceiveAuthenticationChallengeProxy(uint64_t frameID, PassRefPtr<AuthenticationChallengeProxy>); int64_t spellDocumentTag(); void didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>&); void didCancelCheckingText(uint64_t requestID); - void connectionWillOpen(IPC::Connection*); - void connectionWillClose(IPC::Connection*); + void connectionWillOpen(IPC::Connection&); + void webProcessWillShutDown(); + + void processDidFinishLaunching(); void didSaveToPageCache(); void setScrollPinningBehavior(WebCore::ScrollPinningBehavior); - WebCore::ScrollPinningBehavior scrollPinningBehavior() { return m_scrollPinningBehavior; } + WebCore::ScrollPinningBehavior scrollPinningBehavior() const { return m_scrollPinningBehavior; } + + void setOverlayScrollbarStyle(std::optional<WebCore::ScrollbarOverlayStyle>); + std::optional<WebCore::ScrollbarOverlayStyle> overlayScrollbarStyle() const { return m_scrollbarOverlayStyle; } bool shouldRecordNavigationSnapshots() const { return m_shouldRecordNavigationSnapshots; } void setShouldRecordNavigationSnapshots(bool shouldRecordSnapshots) { m_shouldRecordNavigationSnapshots = shouldRecordSnapshots; } - void recordNavigationSnapshot(); + void recordAutomaticNavigationSnapshot(); + void recordNavigationSnapshot(WebBackForwardListItem&); + +#if PLATFORM(COCOA) + PassRefPtr<ViewSnapshot> takeViewSnapshot(); +#endif + +#if ENABLE(SUBTLE_CRYPTO) + void wrapCryptoKey(const Vector<uint8_t>&, bool& succeeded, Vector<uint8_t>&); + void unwrapCryptoKey(const Vector<uint8_t>&, bool& succeeded, Vector<uint8_t>&); +#endif + + void takeSnapshot(WebCore::IntRect, WebCore::IntSize bitmapSize, SnapshotOptions, std::function<void (const ShareableBitmap::Handle&, CallbackBase::Error)>); + + void navigationGestureDidBegin(); + void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&); + void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&); + void navigationGestureDidEnd(); + void navigationGestureSnapshotWasRemoved(); + void willRecordNavigationSnapshot(WebBackForwardListItem&); + + bool isShowingNavigationGestureSnapshot() const { return m_isShowingNavigationGestureSnapshot; } + + bool isPlayingAudio() const { return !!(m_mediaState & WebCore::MediaProducer::IsPlayingAudio); } + void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags, uint64_t); + bool hasActiveAudioStream() const { return m_mediaState & WebCore::MediaProducer::HasActiveAudioCaptureDevice; } + bool hasActiveVideoStream() const { return m_mediaState & WebCore::MediaProducer::HasActiveVideoCaptureDevice; } + WebCore::MediaProducer::MediaStateFlags mediaStateFlags() const { return m_mediaState; } + void didPlayMediaPreventedFromPlayingWithoutUserGesture(); #if PLATFORM(MAC) - RetainPtr<CGImageRef> takeViewSnapshot(); + void videoControlsManagerDidChange(); + bool hasActiveVideoForControlsManager() const; + void requestControlledElementID() const; + void handleControlledElementIDResponse(const String&) const; + bool isPlayingVideoInEnhancedFullscreen() const; #endif +#if PLATFORM(COCOA) + void requestActiveNowPlayingSessionInfo(); + void handleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, const String& title, double duration, double elapsedTime) const; +#endif + +#if ENABLE(MEDIA_SESSION) + void hasMediaSessionWithActiveMediaElementsDidChange(bool); + void mediaSessionMetadataDidChange(const WebCore::MediaSessionMetadata&); + void focusedContentMediaElementDidChange(uint64_t); +#endif + +#if PLATFORM(MAC) + void removeNavigationGestureSnapshot(); + + API::HitTestResult* lastMouseMoveHitTestResult() const { return m_lastMouseMoveHitTestResult.get(); } + void performImmediateActionHitTestAtLocation(WebCore::FloatPoint); + + void immediateActionDidUpdate(); + void immediateActionDidCancel(); + void immediateActionDidComplete(); + + void* immediateActionAnimationControllerForHitTestResult(RefPtr<API::HitTestResult>, uint64_t, RefPtr<API::Object>); + + void installActivityStateChangeCompletionHandler(void(^completionHandler)()); + + void handleAcceptedCandidate(WebCore::TextCheckingResult); + void didHandleAcceptedCandidate(); + + void setHeaderBannerHeightForTesting(int); + void setFooterBannerHeightForTesting(int); +#endif + +#if USE(UNIFIED_TEXT_CHECKING) + void checkTextOfParagraph(const String& text, uint64_t checkingTypes, int32_t insertionPoint, Vector<WebCore::TextCheckingResult>& results); +#endif + void getGuessesForWord(const String& word, const String& context, int32_t insertionPoint, Vector<String>& guesses); + + void setShouldDispatchFakeMouseMoveEvents(bool); + + // Diagnostic messages logging. + void logDiagnosticMessage(const String& message, const String& description, WebCore::ShouldSample); + void logDiagnosticMessageWithResult(const String& message, const String& description, uint32_t result, WebCore::ShouldSample); + void logDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample); + void logDiagnosticMessageWithEnhancedPrivacy(const String& message, const String& description, WebCore::ShouldSample); + + // Form validation messages. + void showValidationMessage(const WebCore::IntRect& anchorClientRect, const String& message); + void hideValidationMessage(); +#if PLATFORM(COCOA) + WebCore::ValidationBubble* validationBubble() const { return m_validationBubble.get(); } // For testing. +#endif + +#if PLATFORM(IOS) + void setIsKeyboardAnimatingIn(bool isKeyboardAnimatingIn) { m_isKeyboardAnimatingIn = isKeyboardAnimatingIn; } +#endif + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + void addPlaybackTargetPickerClient(uint64_t); + void removePlaybackTargetPickerClient(uint64_t); + void showPlaybackTargetPicker(uint64_t, const WebCore::FloatRect&, bool hasVideo); + void playbackTargetPickerClientStateDidChange(uint64_t, WebCore::MediaProducer::MediaStateFlags); + void setMockMediaPlaybackTargetPickerEnabled(bool); + void setMockMediaPlaybackTargetPickerState(const String&, WebCore::MediaPlaybackTargetContext::State); + + // WebMediaSessionManagerClient + void setPlaybackTarget(uint64_t, Ref<WebCore::MediaPlaybackTarget>&&) override; + void externalOutputDeviceAvailableDidChange(uint64_t, bool) override; + void setShouldPlayToPlaybackTarget(uint64_t, bool) override; +#endif + + void didChangeBackgroundColor(); + void didLayoutForCustomContentProvider(); + + // For testing + void clearWheelEventTestTrigger(); + void callAfterNextPresentationUpdate(std::function<void (CallbackBase::Error)>); + + void didReachLayoutMilestone(uint32_t layoutMilestones); + + void didRestoreScrollPosition(); + + void getLoadDecisionForIcon(const WebCore::LinkIcon&, uint64_t callbackID); + void finishedLoadingIcon(uint64_t callbackIdentifier, const IPC::DataReference&); + + void setFocus(bool focused); + void setWindowFrame(const WebCore::FloatRect&); + void getWindowFrame(WebCore::FloatRect&); + + bool isResourceCachingDisabled() const { return m_isResourceCachingDisabled; } + void setResourceCachingDisabled(bool); + + WebCore::UserInterfaceLayoutDirection userInterfaceLayoutDirection(); + void setUserInterfaceLayoutDirection(WebCore::UserInterfaceLayoutDirection); + + bool hasHadSelectionChangesFromUserInteraction() const { return m_hasHadSelectionChangesFromUserInteraction; } + bool needsHiddenContentEditableQuirk() const { return m_needsHiddenContentEditableQuirk; } + bool needsPlainTextQuirk() const { return m_needsPlainTextQuirk; } + + bool isAlwaysOnLoggingAllowed() const; + + void canAuthenticateAgainstProtectionSpace(uint64_t loaderID, uint64_t frameID, const WebCore::ProtectionSpace&); + +#if ENABLE(GAMEPAD) + void gamepadActivity(const Vector<GamepadData>&, bool shouldMakeGamepadsVisible); +#endif + + WeakPtr<WebPageProxy> createWeakPtr() const { return m_weakPtrFactory.createWeakPtr(); } + + void isLoadingChanged() { activityStateDidChange(WebCore::ActivityState::IsLoading); } + + void clearUserMediaState(); + + void setShouldSkipWaitingForPaintAfterNextViewDidMoveToWindow(bool shouldSkip) { m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow = shouldSkip; } + private: - WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, const WebPageConfiguration&); + WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&); void platformInitialize(); - void updateViewState(WebCore::ViewState::Flags flagsToUpdate = WebCore::ViewState::AllFlags); + void updateActivityState(WebCore::ActivityState::Flags flagsToUpdate = WebCore::ActivityState::AllFlags); + void updateThrottleState(); + void updateHiddenPageThrottlingAutoIncreases(); - void resetState(); + enum class ResetStateReason { + PageInvalidated, + WebProcessExited, + }; + void resetState(ResetStateReason); void resetStateAfterProcessExited(); void setUserAgent(const String&); // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + // Implemented in generated WebPageProxyMessageReceiver.cpp + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + // IPC::MessageSender - virtual bool sendMessage(std::unique_ptr<IPC::MessageEncoder>, unsigned messageSendFlags) override; - virtual IPC::Connection* messageSenderConnection() override; - virtual uint64_t messageSenderDestinationID() override; + bool sendMessage(std::unique_ptr<IPC::Encoder>, OptionSet<IPC::SendOption>) override; + IPC::Connection* messageSenderConnection() override; + uint64_t messageSenderDestinationID() override; // WebPopupMenuProxy::Client - virtual void valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex); - virtual void setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index); + void valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex) override; + void setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index) override; #if PLATFORM(GTK) - virtual void failedToShowPopupMenu(); + void failedToShowPopupMenu() override; #endif - // Implemented in generated WebPageProxyMessageReceiver.cpp - void didReceiveWebPageProxyMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncWebPageProxyMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); +#if ENABLE(POINTER_LOCK) + void requestPointerLock(); + void requestPointerUnlock(); +#endif void didCreateMainFrame(uint64_t frameID); void didCreateSubframe(uint64_t frameID); - void didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, IPC::MessageDecoder&); - void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String&, IPC::MessageDecoder&); - void didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::ResourceError&, IPC::MessageDecoder&); - void didCommitLoadForFrame(uint64_t frameID, const String& mimeType, uint32_t frameLoadType, const WebCore::CertificateInfo&, IPC::MessageDecoder&); - void didFinishDocumentLoadForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didFinishLoadForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didFailLoadForFrame(uint64_t frameID, const WebCore::ResourceError&, IPC::MessageDecoder&); - void didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t sameDocumentNavigationType, const String&, IPC::MessageDecoder&); - void didReceiveTitleForFrame(uint64_t frameID, const String&, IPC::MessageDecoder&); - void didFirstLayoutForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didLayout(uint32_t layoutMilestones, IPC::MessageDecoder&); - void didRemoveFrameFromHierarchy(uint64_t frameID, IPC::MessageDecoder&); - void didDisplayInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didRunInsecureContentForFrame(uint64_t frameID, IPC::MessageDecoder&); - void didDetectXSSForFrame(uint64_t frameID, IPC::MessageDecoder&); + void didStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& url, const String& unreachableURL, const UserData&); + void didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, const String&, const UserData&); + void didChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, const String& url); + void didFailProvisionalLoadForFrame(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const String& provisionalURL, const WebCore::ResourceError&, const UserData&); + void didCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, const String& mimeType, bool frameHasCustomContentProvider, uint32_t frameLoadType, const WebCore::CertificateInfo&, bool containsPluginDocument, std::optional<WebCore::HasInsecureContent> forcedHasInsecureContent, const UserData&); + void didFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&); + void didFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, const UserData&); + void didFailLoadForFrame(uint64_t frameID, uint64_t navigationID, const WebCore::ResourceError&, const UserData&); + void didSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t sameDocumentNavigationType, const String&, const UserData&); + void didReceiveTitleForFrame(uint64_t frameID, const String&, const UserData&); + void didFirstLayoutForFrame(uint64_t frameID, const UserData&); + void didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, const UserData&); + void didDisplayInsecureContentForFrame(uint64_t frameID, const UserData&); + void didRunInsecureContentForFrame(uint64_t frameID, const UserData&); + void didDetectXSSForFrame(uint64_t frameID, const UserData&); + void mainFramePluginHandlesPageScaleGestureDidChange(bool); void frameDidBecomeFrameSet(uint64_t frameID, bool); void didStartProgress(); void didChangeProgress(double); void didFinishProgress(); + void setNetworkRequestsInProgress(bool); + + void hasInsecureContent(WebCore::HasInsecureContent&); + + void didDestroyNavigation(uint64_t navigationID); + + void decidePolicyForNavigationAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, uint64_t navigationID, const NavigationActionData&, uint64_t originatingFrameID, const WebCore::SecurityOriginData& originatingFrameSecurityOrigin, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, uint64_t& newNavigationID, uint64_t& policyAction, DownloadID&, WebsitePolicies&); + void decidePolicyForNewWindowAction(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, uint64_t listenerID, const UserData&); + void decidePolicyForResponse(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&); + void decidePolicyForResponseSync(uint64_t frameID, const WebCore::SecurityOriginData& frameSecurityOrigin, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, const UserData&, bool& receivedPolicyAction, uint64_t& policyAction, DownloadID&); + void unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError&, const UserData&); - void decidePolicyForNavigationAction(uint64_t frameID, const NavigationActionData&, uint64_t originatingFrameID, const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceRequest&, uint64_t listenerID, IPC::MessageDecoder&, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID); - void decidePolicyForNewWindowAction(uint64_t frameID, const NavigationActionData&, const WebCore::ResourceRequest&, const String& frameName, uint64_t listenerID, IPC::MessageDecoder&); - void decidePolicyForResponse(uint64_t frameID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder&); - void decidePolicyForResponseSync(uint64_t frameID, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&, bool canShowMIMEType, uint64_t listenerID, IPC::MessageDecoder&, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID); - void unableToImplementPolicy(uint64_t frameID, const WebCore::ResourceError&, IPC::MessageDecoder&); + void willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, const UserData&); - void willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String>>& textFieldValues, uint64_t listenerID, IPC::MessageDecoder&); + // History client + void didNavigateWithNavigationData(const WebNavigationDataStore&, uint64_t frameID); + void didPerformClientRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID); + void didPerformServerRedirect(const String& sourceURLString, const String& destinationURLString, uint64_t frameID); + void didUpdateHistoryTitle(const String& title, const String& url, uint64_t frameID); // UI client - void createNewPage(const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, uint32_t modifiers, int32_t mouseButton, uint64_t& newPageID, WebPageCreationParameters&); + void createNewPage(uint64_t frameID, const WebCore::SecurityOriginData&, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, const NavigationActionData&, uint64_t& newPageID, WebPageCreationParameters&); void showPage(); - void closePage(bool stopResponsivenessTimer); - void runJavaScriptAlert(uint64_t frameID, const String&); - void runJavaScriptConfirm(uint64_t frameID, const String&, bool& result); - void runJavaScriptPrompt(uint64_t frameID, const String&, const String&, String& result); - void shouldInterruptJavaScript(bool& result); + void runJavaScriptAlert(uint64_t frameID, const WebCore::SecurityOriginData&, const String&, Ref<Messages::WebPageProxy::RunJavaScriptAlert::DelayedReply>&&); + void runJavaScriptConfirm(uint64_t frameID, const WebCore::SecurityOriginData&, const String&, Ref<Messages::WebPageProxy::RunJavaScriptConfirm::DelayedReply>&&); + void runJavaScriptPrompt(uint64_t frameID, const WebCore::SecurityOriginData&, const String&, const String&, RefPtr<Messages::WebPageProxy::RunJavaScriptPrompt::DelayedReply>); void setStatusText(const String&); - void mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t modifiers, IPC::MessageDecoder&); + void mouseDidMoveOverElement(const WebHitTestResultData&, uint32_t modifiers, const UserData&); + #if ENABLE(NETSCAPE_PLUGIN_API) void unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginsPageURLString, const String& frameURLString, const String& pageURLString); #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(WEBGL) void webGLPolicyForURL(const String& url, uint32_t& loadPolicy); + void resolveWebGLPolicyForURL(const String& url, uint32_t& loadPolicy); #endif // ENABLE(WEBGL) void setToolbarsAreVisible(bool toolbarsAreVisible); void getToolbarsAreVisible(bool& toolbarsAreVisible); @@ -954,23 +1295,34 @@ private: void getStatusBarIsVisible(bool& statusBarIsVisible); void setIsResizable(bool isResizable); void getIsResizable(bool& isResizable); - void setWindowFrame(const WebCore::FloatRect&); - void getWindowFrame(WebCore::FloatRect&); - void screenToWindow(const WebCore::IntPoint& screenPoint, WebCore::IntPoint& windowPoint); - void windowToScreen(const WebCore::IntRect& viewRect, WebCore::IntRect& result); - void runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose); + void screenToRootView(const WebCore::IntPoint& screenPoint, WebCore::IntPoint& windowPoint); + void rootViewToScreen(const WebCore::IntRect& viewRect, WebCore::IntRect& result); +#if PLATFORM(IOS) + void accessibilityScreenToRootView(const WebCore::IntPoint& screenPoint, WebCore::IntPoint& windowPoint); + void rootViewToAccessibilityScreen(const WebCore::IntRect& viewRect, WebCore::IntRect& result); +#endif + void runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, RefPtr<Messages::WebPageProxy::RunBeforeUnloadConfirmPanel::DelayedReply>); void didChangeViewportProperties(const WebCore::ViewportAttributes&); void pageDidScroll(); - void runOpenPanel(uint64_t frameID, const WebCore::FileChooserSettings&); + void runOpenPanel(uint64_t frameID, const WebCore::SecurityOriginData&, const WebCore::FileChooserSettings&); void printFrame(uint64_t frameID); void exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>); + void reachedApplicationCacheOriginQuota(const String& originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded, PassRefPtr<Messages::WebPageProxy::ReachedApplicationCacheOriginQuota::DelayedReply>); void requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier); + +#if ENABLE(MEDIA_STREAM) + UserMediaPermissionRequestManagerProxy& userMediaPermissionRequestManager(); +#endif + void requestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, const WebCore::MediaConstraintsData& audioConstraints, const WebCore::MediaConstraintsData& videoConstraints); + void enumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier); + void runModal(); void notifyScrollerThumbIsVisibleInRect(const WebCore::IntRect&); void recommendedScrollbarStyleDidChange(int32_t newStyle); void didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar); void didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide); void didChangePageCount(unsigned); + void pageExtendedBackgroundColorDidChange(const WebCore::Color&); #if ENABLE(NETSCAPE_PLUGIN_API) void didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString); void didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString, bool replacementObscured); @@ -978,7 +1330,8 @@ private: void setCanShortCircuitHorizontalWheelEvents(bool canShortCircuitHorizontalWheelEvents) { m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; } void reattachToWebProcess(); - void reattachToWebProcessWithItem(WebBackForwardListItem*); + RefPtr<API::Navigation> reattachToWebProcessForReload(); + RefPtr<API::Navigation> reattachToWebProcessWithItem(WebBackForwardListItem*); void requestNotificationPermission(uint64_t notificationID, const String& originString); void showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID); @@ -986,28 +1339,19 @@ private: void clearNotifications(const Vector<uint64_t>& notificationIDs); void didDestroyNotification(uint64_t notificationID); -#if USE(TILED_BACKING_STORE) - void pageDidRequestScroll(const WebCore::IntPoint&); - void pageTransitionViewportReady(); -#endif -#if USE(COORDINATED_GRAPHICS) - void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&); -#endif -#if PLATFORM(EFL) || PLATFORM(IOS) void didChangeContentSize(const WebCore::IntSize&); -#endif - -#if ENABLE(TOUCH_EVENTS) - void needTouchEvents(bool); -#endif #if ENABLE(INPUT_TYPE_COLOR) void showColorPicker(const WebCore::Color& initialColor, const WebCore::IntRect&); - void didChooseColor(const WebCore::Color&); - void didEndColorPicker(); + void didChooseColor(const WebCore::Color&) override; + void didEndColorPicker() override; #endif void editorStateChanged(const EditorState&); + void compositionWasCanceled(); + void setHasHadSelectionChangesFromUserInteraction(bool); + void setNeedsHiddenContentEditableQuirk(bool); + void setNeedsPlainTextQuirk(bool); // Back/Forward list management void backForwardAddItem(uint64_t itemID); @@ -1019,13 +1363,13 @@ private: // Undo management void registerEditCommandForUndo(uint64_t commandID, uint32_t editAction); + void registerInsertionUndoGrouping(); void clearAllEditCommands(); void canUndoRedo(uint32_t action, bool& result); void executeUndoRedo(uint32_t action, bool& result); // Keyboard handling -#if PLATFORM(MAC) - void interpretQueuedKeyEvent(const EditorState&, bool& handled, Vector<WebCore::KeypressCommand>&); +#if PLATFORM(COCOA) void executeSavedCommandBySelector(const String& selector, bool& handled); #endif @@ -1033,25 +1377,27 @@ private: void getEditorCommandsForKeyEvent(const AtomicString&, Vector<String>&); void bindAccessibilityTree(const String&); #endif -#if PLATFORM(EFL) - void getEditorCommandsForKeyEvent(Vector<String>&); -#endif // Popup Menu. void showPopupMenu(const WebCore::IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData&); void hidePopupMenu(); #if ENABLE(CONTEXT_MENUS) - // Context Menu. - void showContextMenu(const WebCore::IntPoint& menuLocation, const WebHitTestResult::Data&, const Vector<WebContextMenuItemData>&, IPC::MessageDecoder&); - void internalShowContextMenu(const WebCore::IntPoint& menuLocation, const WebHitTestResult::Data&, const Vector<WebContextMenuItemData>&, IPC::MessageDecoder&); + void showContextMenu(const ContextMenuContextData&, const UserData&); + void internalShowContextMenu(const ContextMenuContextData&, const UserData&); +#endif + +#if ENABLE(TELEPHONE_NUMBER_DETECTION) +#if PLATFORM(MAC) + void showTelephoneNumberMenu(const String& telephoneNumber, const WebCore::IntPoint&); +#endif #endif // Search popup results - void saveRecentSearches(const String&, const Vector<String>&); - void loadRecentSearches(const String&, Vector<String>&); + void saveRecentSearches(const String&, const Vector<WebCore::RecentSearch>&); + void loadRecentSearches(const String&, Vector<WebCore::RecentSearch>&); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Speech. void getIsSpeaking(bool&); void speak(const String&); @@ -1063,24 +1409,23 @@ private: void searchTheWeb(const String&); // Dictionary. - void didPerformDictionaryLookup(const AttributedString&, const DictionaryPopupInfo&); + void didPerformDictionaryLookup(const WebCore::DictionaryPopupInfo&); #endif - // Spelling and grammar. -#if USE(UNIFIED_TEXT_CHECKING) - void checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<WebCore::TextCheckingResult>& results); +#if PLATFORM(MAC) + bool appleMailPaginationQuirkEnabled(); #endif + + // Spelling and grammar. void checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength); void checkGrammarOfString(const String& text, Vector<WebCore::GrammarDetail>&, int32_t& badGrammarLocation, int32_t& badGrammarLength); void spellingUIIsShowing(bool&); void updateSpellingUIWithMisspelledWord(const String& misspelledWord); void updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const WebCore::GrammarDetail&); - void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses); void learnWord(const String& word); void ignoreWord(const String& word); - void requestCheckingOfString(uint64_t requestID, const WebCore::TextCheckingRequestData&); + void requestCheckingOfString(uint64_t requestID, const WebCore::TextCheckingRequestData&, int32_t insertionPoint); - void setFocus(bool focused); void takeFocus(uint32_t direction); void setToolTip(const String&); void setCursor(const WebCore::Cursor&); @@ -1093,15 +1438,29 @@ private: void dataCallback(const IPC::DataReference&, uint64_t); void imageCallback(const ShareableBitmap::Handle&, uint64_t); void stringCallback(const String&, uint64_t); - void scriptValueCallback(const IPC::DataReference&, uint64_t); + void invalidateStringCallback(uint64_t); + void scriptValueCallback(const IPC::DataReference&, bool hadException, const WebCore::ExceptionDetails&, uint64_t); void computedPagesCallback(const Vector<WebCore::IntRect>&, double totalScaleFactorForPrinting, uint64_t); void validateCommandCallback(const String&, bool, int, uint64_t); + void unsignedCallback(uint64_t, uint64_t); + void editingRangeCallback(const EditingRange&, uint64_t); +#if PLATFORM(COCOA) + void machSendRightCallback(const WebCore::MachSendRight&, uint64_t); +#endif + void rectForCharacterRangeCallback(const WebCore::IntRect&, const EditingRange&, uint64_t); +#if PLATFORM(MAC) + void attributedStringForCharacterRangeCallback(const AttributedString&, const EditingRange&, uint64_t); + void fontAtSelectionCallback(const String&, double, bool, uint64_t); +#endif #if PLATFORM(IOS) void gestureCallback(const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, uint64_t); - void touchesCallback(const WebCore::IntPoint&, uint32_t, uint64_t); + void touchesCallback(const WebCore::IntPoint&, uint32_t, uint32_t, uint64_t); void autocorrectionDataCallback(const Vector<WebCore::FloatRect>&, const String&, float, uint64_t, uint64_t); void autocorrectionContextCallback(const String&, const String&, const String&, const String&, uint64_t, uint64_t, uint64_t); + void selectionContextCallback(const String&, const String&, const String&, uint64_t); void interpretKeyEvent(const EditorState&, bool isCharEvent, bool& handled); + void showPlaybackTargetPicker(bool hasVideo, const WebCore::IntRect& elementRect); + void selectionRectsCallback(const Vector<WebCore::SelectionRect>&, uint64_t); #endif #if PLATFORM(GTK) void printFinishedCallback(const WebCore::ResourceError&, uint64_t); @@ -1110,17 +1469,26 @@ private: void focusedFrameChanged(uint64_t frameID); void frameSetLargestFrameChanged(uint64_t frameID); - void canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const WebCore::ProtectionSpace&, bool& canAuthenticate); void didReceiveAuthenticationChallenge(uint64_t frameID, const WebCore::AuthenticationChallenge&, uint64_t challengeID); -#if PLATFORM(MAC) + void didFinishLoadingDataForCustomContentProvider(const String& suggestedFilename, const IPC::DataReference&); + +#if PLATFORM(COCOA) void pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus); void setPluginComplexTextInputState(uint64_t pluginComplexTextInputIdentifier, uint64_t complexTextInputState); #endif bool maybeInitializeSandboxExtensionHandle(const WebCore::URL&, SandboxExtension::Handle&); -#if PLATFORM(MAC) && !PLATFORM(IOS) +#if USE(AUTOMATIC_TEXT_REPLACEMENT) + void toggleSmartInsertDelete(); + void toggleAutomaticQuoteSubstitution(); + void toggleAutomaticLinkDetection(); + void toggleAutomaticDashSubstitution(); + void toggleAutomaticTextReplacement(); +#endif + +#if PLATFORM(MAC) void substitutionsPanelIsShowing(bool&); void showCorrectionPanel(int32_t panelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings); void dismissCorrectionPanel(int32_t reason); @@ -1132,22 +1500,37 @@ private: void removeDictationAlternatives(uint64_t dictationContext); void dictationAlternatives(uint64_t dictationContext, Vector<String>& result); #endif -#endif // PLATFORM(MAC) && !PLATFORM(IOS) + + void setEditableElementIsFocused(bool); +#endif // PLATFORM(MAC) #if PLATFORM(IOS) - void mainDocumentDidReceiveMobileDocType(); + WebCore::FloatSize screenSize(); + WebCore::FloatSize availableScreenSize(); + float textAutosizingWidth(); - void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& geometries, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius); + void dynamicViewportUpdateChangedTarget(double newTargetScale, const WebCore::FloatPoint& newScrollPosition, uint64_t dynamicViewportSizeUpdateID); + void couldNotRestorePageState(); + void restorePageState(const WebCore::FloatPoint& scrollPosition, const WebCore::FloatPoint& scrollOrigin, const WebCore::FloatSize& obscuredInsetOnSave, double scale); + void restorePageCenterAndScale(const WebCore::FloatPoint&, double scale); - void didChangeViewportArguments(const WebCore::ViewportArguments& viewportArguments); + void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& geometries, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius); - void startAssistingNode(const WebCore::IntRect&, bool hasNextFocusable, bool hasPreviousFocusable); + void startAssistingNode(const AssistedNodeInformation&, bool userIsInteracting, bool blurPreviousNode, const UserData&); void stopAssistingNode(); - void notifyRevealedSelection(); + + void showInspectorHighlight(const WebCore::Highlight&); + void hideInspectorHighlight(); + + void showInspectorIndication(); + void hideInspectorIndication(); + + void enableInspectorNodeSearch(); + void disableInspectorNodeSearch(); #endif // PLATFORM(IOS) -#if USE(SOUP) && !ENABLE(CUSTOM_PROTOCOLS) - void didReceiveURIRequest(String uriString, uint64_t requestID); +#if ENABLE(DATA_DETECTION) + RetainPtr<NSArray> m_dataDetectionResults; #endif void clearLoadDependentCallbacks(); @@ -1167,23 +1550,76 @@ private: void processNextQueuedWheelEvent(); void sendWheelEvent(const WebWheelEvent&); +#if ENABLE(TOUCH_EVENTS) + void updateTouchEventTracking(const WebTouchEvent&); + WebCore::TrackingType touchEventTrackingType(const WebTouchEvent&) const; +#endif + #if ENABLE(NETSCAPE_PLUGIN_API) void findPlugin(const String& mimeType, uint32_t processType, const String& urlString, const String& frameURLString, const String& pageURLString, bool allowOnlyApplicationPlugins, uint64_t& pluginProcessToken, String& newMIMEType, uint32_t& pluginLoadPolicy, String& unavailabilityDescription); #endif +#if USE(QUICK_LOOK) + void didStartLoadForQuickLookDocumentInMainFrame(const String& fileName, const String& uti); + void didFinishLoadForQuickLookDocumentInMainFrame(const QuickLookDocumentData&); + void didRequestPasswordForQuickLookDocumentInMainFrame(const String& fileName); +#endif + +#if ENABLE(CONTENT_FILTERING) + void contentFilterDidBlockLoadForFrame(const WebCore::ContentFilterUnblockHandler&, uint64_t frameID); +#endif + + uint64_t generateNavigationID(); + + WebPreferencesStore preferencesStore() const; + + void dispatchActivityStateChange(); + void viewDidLeaveWindow(); + void viewDidEnterWindow(); + void reloadAfterBeingKilledInBackground(); + +#if PLATFORM(MAC) + void didPerformImmediateActionHitTest(const WebHitTestResultData&, bool contentPreventsDefault, const UserData&); +#endif + + void useFixedLayoutDidChange(bool useFixedLayout) { m_useFixedLayout = useFixedLayout; } + void fixedLayoutSizeDidChange(WebCore::IntSize fixedLayoutSize) { m_fixedLayoutSize = fixedLayoutSize; } + + void imageOrMediaDocumentSizeChanged(const WebCore::IntSize&); +#if ENABLE(VIDEO) +#if USE(GSTREAMER) + void requestInstallMissingMediaPlugins(const String& details, const String& description); +#endif +#endif + + void handleAutoFillButtonClick(const UserData&); + + void finishInitializingWebPageAfterProcessLaunch(); + + void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody); + void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, UserData& returnUserData); + PageClient& m_pageClient; + Ref<API::PageConfiguration> m_configuration; + std::unique_ptr<API::LoaderClient> m_loaderClient; std::unique_ptr<API::PolicyClient> m_policyClient; - WebFormClient m_formClient; - WebUIClient m_uiClient; -#if PLATFORM(EFL) - WebUIPopupMenuClient m_uiPopupMenuClient; -#endif - WebFindClient m_findClient; - WebFindMatchesClient m_findMatchesClient; + std::unique_ptr<API::NavigationClient> m_navigationClient; + std::unique_ptr<API::HistoryClient> m_historyClient; + std::unique_ptr<API::IconLoadingClient> m_iconLoadingClient; + std::unique_ptr<API::FormClient> m_formClient; + std::unique_ptr<API::UIClient> m_uiClient; + std::unique_ptr<API::FindClient> m_findClient; + std::unique_ptr<API::FindMatchesClient> m_findMatchesClient; + std::unique_ptr<API::DiagnosticLoggingClient> m_diagnosticLoggingClient; #if ENABLE(CONTEXT_MENUS) - WebPageContextMenuClient m_contextMenuClient; + std::unique_ptr<API::ContextMenuClient> m_contextMenuClient; #endif + std::unique_ptr<WebPageInjectedBundleClient> m_injectedBundleClient; + + std::unique_ptr<WebNavigationState> m_navigationState; + String m_failingProvisionalLoadURL; + bool m_isLoadingAlternateHTMLStringForFailingProvisionalLoad { false }; std::unique_ptr<DrawingAreaProxy> m_drawingArea; #if ENABLE(ASYNC_SCROLLING) @@ -1192,6 +1628,14 @@ private: Ref<WebProcessProxy> m_process; Ref<WebPageGroup> m_pageGroup; + Ref<WebPreferences> m_preferences; + + WebProcessLifetimeTracker m_webProcessLifetimeTracker { *this }; + + Ref<WebUserContentControllerProxy> m_userContentController; + Ref<VisitedLinkStore> m_visitedLinkStore; + Ref<WebsiteDataStore> m_websiteDataStore; + RefPtr<WebFrameProxy> m_mainFrame; RefPtr<WebFrameProxy> m_focusedFrame; RefPtr<WebFrameProxy> m_frameSetLargestFrame; @@ -1200,91 +1644,117 @@ private: String m_applicationNameForUserAgent; String m_customUserAgent; String m_customTextEncodingName; + String m_overrideContentSecurityPolicy; + + bool m_treatsSHA1CertificatesAsInsecure; -#if ENABLE(INSPECTOR) RefPtr<WebInspectorProxy> m_inspector; -#endif #if ENABLE(FULLSCREEN_API) RefPtr<WebFullScreenManagerProxy> m_fullScreenManager; + std::unique_ptr<API::FullscreenClient> m_fullscreenClient; +#endif +#if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)) + RefPtr<WebPlaybackSessionManagerProxy> m_playbackSessionManager; + RefPtr<WebVideoFullscreenManagerProxy> m_videoFullscreenManager; +#endif +#if PLATFORM(IOS) + VisibleContentRectUpdateInfo m_lastVisibleContentRectUpdate; + bool m_hasReceivedLayerTreeTransactionAfterDidCommitLoad { true }; + uint64_t m_firstLayerTreeTransactionIdAfterDidCommitLoad { 0 }; + int32_t m_deviceOrientation { 0 }; + bool m_dynamicViewportSizeUpdateWaitingForTarget { false }; + bool m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit { false }; + uint64_t m_dynamicViewportSizeUpdateLayerTreeTransactionID { 0 }; + uint64_t m_layerTreeTransactionIdAtLastTouchStart { 0 }; + uint64_t m_currentDynamicViewportSizeUpdateID { 0 }; + bool m_hasNetworkRequestsOnSuspended { false }; + bool m_isKeyboardAnimatingIn { false }; + bool m_isScrollingOrZooming { false }; #endif #if ENABLE(VIBRATION) RefPtr<WebVibrationProxy> m_vibration; #endif - HashMap<uint64_t, RefPtr<VoidCallback>> m_voidCallbacks; - HashMap<uint64_t, RefPtr<DataCallback>> m_dataCallbacks; - HashMap<uint64_t, RefPtr<ImageCallback>> m_imageCallbacks; - HashMap<uint64_t, RefPtr<StringCallback>> m_stringCallbacks; - HashSet<uint64_t> m_loadDependentStringCallbackIDs; - HashMap<uint64_t, RefPtr<ScriptValueCallback>> m_scriptValueCallbacks; - HashMap<uint64_t, RefPtr<ComputedPagesCallback>> m_computedPagesCallbacks; - HashMap<uint64_t, RefPtr<ValidateCommandCallback>> m_validateCommandCallbacks; -#if PLATFORM(IOS) - HashMap<uint64_t, RefPtr<GestureCallback>> m_gestureCallbacks; - HashMap<uint64_t, RefPtr<TouchesCallback>> m_touchesCallbacks; - HashMap<uint64_t, RefPtr<AutocorrectionDataCallback>> m_autocorrectionCallbacks; - HashMap<uint64_t, RefPtr<AutocorrectionContextCallback>> m_autocorrectionContextCallbacks; -#endif -#if PLATFORM(GTK) - HashMap<uint64_t, RefPtr<PrintFinishedCallback>> m_printFinishedCallbacks; +#if ENABLE(APPLE_PAY) + std::unique_ptr<WebPaymentCoordinatorProxy> m_paymentCoordinator; #endif + CallbackMap m_callbacks; + HashSet<uint64_t> m_loadDependentStringCallbackIDs; + HashSet<WebEditCommandProxy*> m_editCommandSet; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) HashSet<String> m_knownKeypressCommandNames; #endif RefPtr<WebPopupMenuProxy> m_activePopupMenu; - RefPtr<WebContextMenuProxy> m_activeContextMenu; - WebHitTestResult::Data m_activeContextMenuHitTestResultData; +#if ENABLE(CONTEXT_MENUS) + std::unique_ptr<WebContextMenuProxy> m_activeContextMenu; + ContextMenuContextData m_activeContextMenuContextData; +#endif + RefPtr<API::HitTestResult> m_lastMouseMoveHitTestResult; + RefPtr<WebOpenPanelResultListenerProxy> m_openPanelResultListener; GeolocationPermissionRequestManagerProxy m_geolocationPermissionRequestManager; NotificationPermissionRequestManagerProxy m_notificationPermissionRequestManager; - WebCore::ViewState::Flags m_viewState; +#if ENABLE(MEDIA_STREAM) + std::unique_ptr<UserMediaPermissionRequestManagerProxy> m_userMediaPermissionRequestManager; +#endif - bool m_canGoBack; - bool m_canGoForward; + WebCore::ActivityState::Flags m_activityState; + bool m_viewWasEverInWindow; +#if PLATFORM(IOS) + bool m_allowsMediaDocumentInlinePlayback { false }; + bool m_alwaysRunsAtForegroundPriority; + ProcessThrottler::ForegroundActivityToken m_activityToken; +#endif + bool m_initialCapitalizationEnabled; Ref<WebBackForwardList> m_backForwardList; - + bool m_maintainsInactiveSelection; - String m_toolTip; + bool m_waitsForPaintAfterViewDidMoveToWindow; + bool m_shouldSkipWaitingForPaintAfterNextViewDidMoveToWindow { false }; - String m_urlAtProcessExit; - FrameLoadState::State m_loadStateAtProcessExit; + String m_toolTip; EditorState m_editorState; - bool m_temporarilyClosedComposition; // Editor state changed from hasComposition to !hasComposition, but that was only with shouldIgnoreCompositionSelectionChange yet. + bool m_isEditable; double m_textZoomFactor; double m_pageZoomFactor; double m_pageScaleFactor; + double m_pluginZoomFactor; + double m_pluginScaleFactor; + double m_viewScaleFactor { 1 }; float m_intrinsicDeviceScaleFactor; float m_customDeviceScaleFactor; + float m_topContentInset; LayerHostingMode m_layerHostingMode; bool m_drawsBackground; - bool m_drawsTransparentBackground; WebCore::Color m_underlayColor; - - bool m_areMemoryCacheClientCallsEnabled; + WebCore::Color m_pageExtendedBackgroundColor; bool m_useFixedLayout; WebCore::IntSize m_fixedLayoutSize; + WebCore::LayoutMilestones m_observedLayoutMilestones { 0 }; + bool m_suppressScrollbarAnimations; WebCore::Pagination::Mode m_paginationMode; bool m_paginationBehavesLikeColumns; double m_pageLength; double m_gapBetweenPages; - + bool m_paginationLineGridEnabled; + // If the process backing the web page is alive and kicking. bool m_isValid; @@ -1294,6 +1764,8 @@ private: // Whether it can run modal child web pages. bool m_canRunModal; + bool m_needsToFinishInitializingWebPageAfterProcessLaunch { false }; + bool m_isInPrintingMode; bool m_isPerformingDOMPrintOperation; @@ -1301,52 +1773,101 @@ private: const WebCore::ResourceRequest* m_decidePolicyForResponseRequest; bool m_syncMimeTypePolicyActionIsValid; WebCore::PolicyAction m_syncMimeTypePolicyAction; - uint64_t m_syncMimeTypePolicyDownloadID; + DownloadID m_syncMimeTypePolicyDownloadID; bool m_inDecidePolicyForNavigationAction; bool m_syncNavigationActionPolicyActionIsValid; WebCore::PolicyAction m_syncNavigationActionPolicyAction; - uint64_t m_syncNavigationActionPolicyDownloadID; + DownloadID m_syncNavigationActionPolicyDownloadID; + WebsitePolicies m_syncNavigationActionPolicyWebsitePolicies; + bool m_shouldSuppressAppLinksInNextNavigationPolicyDecision { false }; Deque<NativeWebKeyboardEvent> m_keyEventQueue; Deque<NativeWebWheelEvent> m_wheelEventQueue; - Deque<OwnPtr<Vector<NativeWebWheelEvent>>> m_currentlyProcessedWheelEvents; + Deque<std::unique_ptr<Vector<NativeWebWheelEvent>>> m_currentlyProcessedWheelEvents; +#if ENABLE(MAC_GESTURE_EVENTS) + Deque<NativeWebGestureEvent> m_gestureEventQueue; +#endif bool m_processingMouseMoveEvent; - OwnPtr<NativeWebMouseEvent> m_nextMouseMoveEvent; - OwnPtr<NativeWebMouseEvent> m_currentlyProcessedMouseDownEvent; + std::unique_ptr<NativeWebMouseEvent> m_nextMouseMoveEvent; + std::unique_ptr<NativeWebMouseEvent> m_currentlyProcessedMouseDownEvent; #if ENABLE(TOUCH_EVENTS) - bool m_needTouchEvents; + struct TouchEventTracking { + WebCore::TrackingType touchForceChangedTracking { WebCore::TrackingType::NotTracking }; + WebCore::TrackingType touchStartTracking { WebCore::TrackingType::NotTracking }; + WebCore::TrackingType touchMoveTracking { WebCore::TrackingType::NotTracking }; + WebCore::TrackingType touchEndTracking { WebCore::TrackingType::NotTracking }; + + bool isTrackingAnything() const + { + return touchForceChangedTracking != WebCore::TrackingType::NotTracking + || touchStartTracking != WebCore::TrackingType::NotTracking + || touchMoveTracking != WebCore::TrackingType::NotTracking + || touchEndTracking != WebCore::TrackingType::NotTracking; + } + + void reset() + { + touchForceChangedTracking = WebCore::TrackingType::NotTracking; + touchStartTracking = WebCore::TrackingType::NotTracking; + touchMoveTracking = WebCore::TrackingType::NotTracking; + touchEndTracking = WebCore::TrackingType::NotTracking; + } + }; + TouchEventTracking m_touchEventTracking; +#endif +#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS) Deque<QueuedTouchEvents> m_touchEventQueue; #endif + #if ENABLE(INPUT_TYPE_COLOR) RefPtr<WebColorPicker> m_colorPicker; - RefPtr<WebColorPickerResultListenerProxy> m_colorPickerResultListener; +#endif +#if PLATFORM(COCOA) + RefPtr<WebCore::ValidationBubble> m_validationBubble; #endif - uint64_t m_pageID; - Ref<API::Session> m_session; + const uint64_t m_pageID; + const WebCore::SessionID m_sessionID; bool m_isPageSuspended; + bool m_addsVisitedLinks; -#if PLATFORM(MAC) + bool m_controlledByAutomation { false }; + +#if ENABLE(REMOTE_INSPECTOR) + bool m_allowsRemoteInspection; + String m_remoteInspectionNameOverride; +#endif + +#if PLATFORM(COCOA) bool m_isSmartInsertDeleteEnabled; #endif #if PLATFORM(GTK) String m_accessibilityPlugID; + WebCore::Color m_backgroundColor; #endif int64_t m_spellDocumentTag; bool m_hasSpellDocumentTag; unsigned m_pendingLearnOrIgnoreWordMessageCount; + bool m_mainFrameHasCustomContentProvider; + #if ENABLE(DRAG_SUPPORT) - WebCore::DragSession m_currentDragSession; + // Current drag destination details are delivered as an asynchronous response, + // so we preserve them to be used when the next dragging delegate call is made. + WebCore::DragOperation m_currentDragOperation; + bool m_currentDragIsOverFileInput; + unsigned m_currentDragNumberOfFilesToBeAccepted; #endif PageLoadState m_pageLoadState; + + bool m_delegatesScrolling; bool m_mainFrameHasHorizontalScrollbar; bool m_mainFrameHasVerticalScrollbar; @@ -1359,42 +1880,106 @@ private: bool m_mainFrameIsPinnedToTopSide; bool m_mainFrameIsPinnedToBottomSide; - bool m_useLegacyImplicitRubberBandControl; + bool m_shouldUseImplicitRubberBandControl; bool m_rubberBandsAtLeft; bool m_rubberBandsAtRight; bool m_rubberBandsAtTop; bool m_rubberBandsAtBottom; + + bool m_enableVerticalRubberBanding; + bool m_enableHorizontalRubberBanding; bool m_backgroundExtendsBeyondPage; - bool m_mainFrameInViewSourceMode; - bool m_shouldRecordNavigationSnapshots; + bool m_isShowingNavigationGestureSnapshot; + + bool m_mainFramePluginHandlesPageScaleGesture { false }; unsigned m_pageCount; WebCore::IntRect m_visibleScrollerThumbRect; uint64_t m_renderTreeSize; - - bool m_shouldSendEventsSynchronously; + uint64_t m_sessionRestorationRenderTreeSize; + bool m_hitRenderTreeSizeThreshold; bool m_suppressVisibilityUpdates; bool m_autoSizingShouldExpandToViewHeight; WebCore::IntSize m_minimumLayoutSize; + // Visual viewports + WebCore::LayoutSize m_baseLayoutViewportSize; + WebCore::LayoutPoint m_minStableLayoutViewportOrigin; + WebCore::LayoutPoint m_maxStableLayoutViewportOrigin; + float m_mediaVolume; + WebCore::MediaProducer::MutedStateFlags m_mutedState { WebCore::MediaProducer::NoneMuted }; bool m_mayStartMediaWhenInWindow; - bool m_waitingForDidUpdateViewState; + bool m_waitingForDidUpdateActivityState; -#if PLATFORM(MAC) + bool m_shouldScaleViewToFitDocument { false }; + bool m_suppressAutomaticNavigationSnapshotting { false }; + +#if PLATFORM(COCOA) HashMap<String, String> m_temporaryPDFFiles; + std::unique_ptr<WebCore::RunLoopObserver> m_activityStateChangeDispatcher; + + std::unique_ptr<RemoteLayerTreeScrollingPerformanceData> m_scrollingPerformanceData; + bool m_scrollPerformanceDataCollectionEnabled; #endif + UserObservablePageCounter::Token m_pageIsUserObservableCount; + ProcessSuppressionDisabledToken m_preventProcessSuppressionCount; + HiddenPageThrottlingAutoIncreasesCounter::Token m_hiddenPageDOMTimerThrottlingAutoIncreasesCount; + VisibleWebPageToken m_visiblePageToken; WebCore::ScrollPinningBehavior m_scrollPinningBehavior; + std::optional<WebCore::ScrollbarOverlayStyle> m_scrollbarOverlayStyle; + + uint64_t m_navigationID; + + WebPreferencesStore::ValueMap m_configurationPreferenceValues; + WebCore::ActivityState::Flags m_potentiallyChangedActivityStateFlags; + bool m_activityStateChangeWantsSynchronousReply; + Vector<uint64_t> m_nextActivityStateChangeCallbacks; + + WebCore::MediaProducer::MediaStateFlags m_mediaState { WebCore::MediaProducer::IsNotPlaying }; + + bool m_isResourceCachingDisabled { false }; + + bool m_hasHadSelectionChangesFromUserInteraction { false }; + bool m_needsHiddenContentEditableQuirk { false }; + bool m_needsPlainTextQuirk { false }; + bool m_hasEverBeenVisible { false }; + +#if ENABLE(MEDIA_SESSION) + bool m_hasMediaSessionWithActiveMediaElements { false }; +#endif + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + bool m_requiresTargetMonitoring { false }; +#endif + +#if PLATFORM(IOS) + bool m_hasDeferredStartAssistingNode { false }; + std::unique_ptr<NodeAssistanceArguments> m_deferredNodeAssistanceArguments; + bool m_forceAlwaysUserScalable { false }; +#endif + +#if ENABLE(POINTER_LOCK) + bool m_isPointerLockPending { false }; + bool m_isPointerLocked { false }; +#endif + +#if ENABLE(DOWNLOAD_ATTRIBUTE) + bool m_syncNavigationActionHasDownloadAttribute { false }; +#endif + + bool m_isUsingHighPerformanceWebGL { false }; + bool m_wasKilledForBeingUnresponsiveWhileInBackground { false }; + + WeakPtrFactory<WebPageProxy> m_weakPtrFactory; }; } // namespace WebKit - -#endif // WebPageProxy_h diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in index 871760a03..ac46314b1 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2010, 2011 Apple Inc. All rights reserved. +# Copyright (C) 2010-2016 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -22,21 +22,22 @@ messages -> WebPageProxy { # UI messages - CreateNewPage(WebCore::ResourceRequest request, WebCore::WindowFeatures windowFeatures, uint32_t modifiers, int32_t mouseButton) -> (uint64_t newPageID, WebKit::WebPageCreationParameters newPageParameters) + CreateNewPage(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceRequest request, struct WebCore::WindowFeatures windowFeatures, struct WebKit::NavigationActionData navigationActionData) -> (uint64_t newPageID, struct WebKit::WebPageCreationParameters newPageParameters) ShowPage() ClosePage(bool stopResponsivenessTimer) - RunJavaScriptAlert(uint64_t frameID, String message) -> () - RunJavaScriptConfirm(uint64_t frameID, String message) -> (bool result) - RunJavaScriptPrompt(uint64_t frameID, String message, String defaultValue) -> (String result) - ShouldInterruptJavaScript() -> (bool shouldInterupt) - MouseDidMoveOverElement(WebKit::WebHitTestResult::Data hitTestResultData, uint32_t modifiers, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + RunJavaScriptAlert(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> () Delayed + RunJavaScriptConfirm(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message) -> (bool result) Delayed + RunJavaScriptPrompt(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, String message, String defaultValue) -> (String result) Delayed + MouseDidMoveOverElement(struct WebKit::WebHitTestResultData hitTestResultData, uint32_t modifiers, WebKit::UserData userData) + #if ENABLE(NETSCAPE_PLUGIN_API) UnavailablePluginButtonClicked(uint32_t pluginUnavailabilityReason, String mimeType, String pluginURLString, String pluginspageAttributeURLString, String frameURLString, String pageURLString) #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(WEBGL) WebGLPolicyForURL(String url) -> (uint32_t loadPolicy) + ResolveWebGLPolicyForURL(String url) -> (uint32_t loadPolicy) #endif // ENABLE(WEBGL) - DidChangeViewportProperties(WebCore::ViewportAttributes attributes) + DidChangeViewportProperties(struct WebCore::ViewportAttributes attributes) DidReceiveEvent(uint32_t type, bool handled) StopResponsivenessTimer() #if !PLATFORM(IOS) @@ -60,18 +61,30 @@ messages -> WebPageProxy { GetIsResizable() -> (bool isResizable) SetWindowFrame(WebCore::FloatRect windowFrame) GetWindowFrame() -> (WebCore::FloatRect windowFrame) - ScreenToWindow(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) - WindowToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) - RunBeforeUnloadConfirmPanel(String message, uint64_t frameID) -> (bool shouldClose) + ScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) + RootViewToScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) + +#if PLATFORM(COCOA) + ShowValidationMessage(WebCore::IntRect anchorRect, String message) + HideValidationMessage() +#endif + +#if PLATFORM(IOS) + AccessibilityScreenToRootView(WebCore::IntPoint screenPoint) -> (WebCore::IntPoint windowPoint) + RootViewToAccessibilityScreen(WebCore::IntRect rect) -> (WebCore::IntRect screenFrame) +#endif + + RunBeforeUnloadConfirmPanel(String message, uint64_t frameID) -> (bool shouldClose) Delayed PageDidScroll() - RunOpenPanel(uint64_t frameID, WebCore::FileChooserSettings parameters) + RunOpenPanel(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebCore::FileChooserSettings parameters) PrintFrame(uint64_t frameID) -> () RunModal() NotifyScrollerThumbIsVisibleInRect(WebCore::IntRect scrollerThumb) RecommendedScrollbarStyleDidChange(int32_t newStyle) DidChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar) DidChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide) - DidChangePageCount(unsigned pageCount); + DidChangePageCount(unsigned pageCount) + PageExtendedBackgroundColorDidChange(WebCore::Color backgroundColor) #if ENABLE(NETSCAPE_PLUGIN_API) DidFailToInitializePlugin(String mimeType, String frameURLString, String pageURLString) DidBlockInsecurePluginVersion(String mimeType, String pluginURLString, String frameURLString, String pageURLString, bool replacementObscured) @@ -82,21 +95,7 @@ messages -> WebPageProxy { HandleInputMethodKeydown() -> (bool handled) #endif -#if USE(TILED_BACKING_STORE) - PageDidRequestScroll(WebCore::IntPoint point) - PageTransitionViewportReady() -#endif -#if USE(COORDINATED_GRAPHICS) - DidFindZoomableArea(WebCore::IntPoint target, WebCore::IntRect area) -#endif - -#if PLATFORM(EFL) || PLATFORM(IOS) DidChangeContentSize(WebCore::IntSize newSize) -#endif - -#if ENABLE(TOUCH_EVENTS) - NeedTouchEvents(bool needTouchEvents) -#endif #if ENABLE(INPUT_TYPE_COLOR) ShowColorPicker(WebCore::Color initialColor, WebCore::IntRect elementRect); @@ -105,70 +104,108 @@ messages -> WebPageProxy { #endif # Policy messages - DecidePolicyForResponseSync(uint64_t frameID, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) -> (bool receivedPolicyAction, uint64_t policyAction, uint64_t downloadID) Variadic - DecidePolicyForNavigationAction(uint64_t frameID, WebKit::NavigationActionData navigationActionData, uint64_t originatingFrameID, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) -> (bool receivedPolicyAction, uint64_t policyAction, uint64_t downloadID) Variadic - DecidePolicyForNewWindowAction(uint64_t frameID, WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + DecidePolicyForResponseSync(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, WebCore::ResourceResponse response, WebCore::ResourceRequest request, bool canShowMIMEType, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction, uint64_t policyAction, WebKit::DownloadID downloadID) + DecidePolicyForNavigationAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, struct WebKit::NavigationActionData navigationActionData, uint64_t originatingFrameID, struct WebCore::SecurityOriginData originatingFrameSecurityOrigin, WebCore::ResourceRequest originalRequest, WebCore::ResourceRequest request, uint64_t listenerID, WebKit::UserData userData) -> (bool receivedPolicyAction, uint64_t newNavigationID, uint64_t policyAction, WebKit::DownloadID downloadID, struct WebKit::WebsitePolicies websitePolicies) + DecidePolicyForNewWindowAction(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, struct WebKit::NavigationActionData navigationActionData, WebCore::ResourceRequest request, String frameName, uint64_t listenerID, WebKit::UserData userData) + UnableToImplementPolicy(uint64_t frameID, WebCore::ResourceError error, WebKit::UserData userData) # Progress messages DidChangeProgress(double value) DidFinishProgress() DidStartProgress() + SetNetworkRequestsInProgress(bool networkRequestsInProgress) + # Frame lifetime messages DidCreateMainFrame(uint64_t frameID) DidCreateSubframe(uint64_t frameID) # Frame load messages - DidCommitLoadForFrame(uint64_t frameID, String mimeType, uint32_t loadType, WebCore::CertificateInfo certificateInfo, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFailLoadForFrame(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFailProvisionalLoadForFrame(uint64_t frameID, WebCore::ResourceError error, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFinishDocumentLoadForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFinishLoadForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFirstLayoutForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidLayout(uint32_t type, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, String url, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidRemoveFrameFromHierarchy(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidStartProvisionalLoadForFrame(uint64_t frameID, String url, String unreachableURL, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidReceiveTitleForFrame(uint64_t frameID, String title, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidDisplayInsecureContentForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidRunInsecureContentForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidDetectXSSForFrame(uint64_t frameID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic - DidSameDocumentNavigationForFrame(uint64_t frameID, uint32_t type, String url, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + DidStartProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, String url, String unreachableURL, WebKit::UserData userData) + DidReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, uint64_t navigationID, String url, WebKit::UserData userData) + DidChangeProvisionalURLForFrame(uint64_t frameID, uint64_t navigationID, String url) + DidFailProvisionalLoadForFrame(uint64_t frameID, struct WebCore::SecurityOriginData frameSecurityOrigin, uint64_t navigationID, String provisionalURL, WebCore::ResourceError error, WebKit::UserData userData) + DidCommitLoadForFrame(uint64_t frameID, uint64_t navigationID, String mimeType, bool hasCustomContentProvider, uint32_t loadType, WebCore::CertificateInfo certificateInfo, bool containsPluginDocument, std::optional<WebCore::HasInsecureContent> forcedHasInsecureContent, WebKit::UserData userData) + DidFailLoadForFrame(uint64_t frameID, uint64_t navigationID, WebCore::ResourceError error, WebKit::UserData userData) + DidFinishDocumentLoadForFrame(uint64_t frameID, uint64_t navigationID, WebKit::UserData userData) + DidFinishLoadForFrame(uint64_t frameID, uint64_t navigationID, WebKit::UserData userData) + DidFirstLayoutForFrame(uint64_t frameID, WebKit::UserData userData) + DidFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, WebKit::UserData userData) + DidReachLayoutMilestone(uint32_t type) + DidReceiveTitleForFrame(uint64_t frameID, String title, WebKit::UserData userData) + DidDisplayInsecureContentForFrame(uint64_t frameID, WebKit::UserData userData) + DidRunInsecureContentForFrame(uint64_t frameID, WebKit::UserData userData) + DidDetectXSSForFrame(uint64_t frameID, WebKit::UserData userData) + DidSameDocumentNavigationForFrame(uint64_t frameID, uint64_t navigationID, uint32_t type, String url, WebKit::UserData userData) + DidDestroyNavigation(uint64_t navigationID) + + HasInsecureContent() -> (enum WebCore::HasInsecureContent hasInsecureContent) + + MainFramePluginHandlesPageScaleGestureDidChange(bool mainFramePluginHandlesPageScaleGesture) FrameDidBecomeFrameSet(uint64_t frameID, bool value) + # History client messages. + DidNavigateWithNavigationData(struct WebKit::WebNavigationDataStore store, uint64_t frameID) + DidPerformClientRedirect(String sourceURLString, String destinationURLString, uint64_t frameID) + DidPerformServerRedirect(String sourceURLString, String destinationURLString, uint64_t frameID) + DidUpdateHistoryTitle(String title, String url, uint64_t frameID) + + # Custom representations + DidFinishLoadingDataForCustomContentProvider(String suggestedFilename, IPC::DataReference data) + # Forms messages - WillSubmitForm(uint64_t frameID, uint64_t sourceFrameID, Vector<std::pair<String, String>> textFieldValues, uint64_t listenerID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + WillSubmitForm(uint64_t frameID, uint64_t sourceFrameID, Vector<std::pair<String, String>> textFieldValues, uint64_t listenerID, WebKit::UserData userData) # Callback messages VoidCallback(uint64_t callbackID) DataCallback(IPC::DataReference resultData, uint64_t callbackID) ImageCallback(WebKit::ShareableBitmap::Handle bitmapHandle, uint64_t callbackID) StringCallback(String resultString, uint64_t callbackID) - ScriptValueCallback(IPC::DataReference resultData, uint64_t callbackID) + InvalidateStringCallback(uint64_t callbackID) + ScriptValueCallback(IPC::DataReference resultData, bool hadException, struct WebCore::ExceptionDetails details, uint64_t callbackID) ComputedPagesCallback(Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting, uint64_t callbackID) ValidateCommandCallback(String command, bool isEnabled, int32_t state, uint64_t callbackID) + EditingRangeCallback(struct WebKit::EditingRange range, uint64_t callbackID) + UnsignedCallback(uint64_t result, uint64_t callbackID) + RectForCharacterRangeCallback(WebCore::IntRect rect, struct WebKit::EditingRange actualRange, uint64_t callbackID) +#if PLATFORM(MAC) + AttributedStringForCharacterRangeCallback(struct WebKit::AttributedString string, struct WebKit::EditingRange actualRange, uint64_t callbackID) + FontAtSelectionCallback(String fontName, double fontSize, bool selectioHasMultipleFonts, uint64_t callbackID) +#endif #if PLATFORM(IOS) GestureCallback(WebCore::IntPoint point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, uint64_t callbackID) - TouchesCallback(WebCore::IntPoint point, uint32_t touches, uint64_t callbackID) + TouchesCallback(WebCore::IntPoint point, uint32_t touches, uint32_t flags, uint64_t callbackID) AutocorrectionDataCallback(Vector<WebCore::FloatRect> textRects, String fontName, double fontSize, uint64_t traits, uint64_t callbackID) AutocorrectionContextCallback(String beforeText, String markedText, String selectedText, String afterText, uint64_t location, uint64_t length, uint64_t callbackID) - InterpretKeyEvent(WebKit::EditorState state, bool isCharEvent) -> (bool handled) - DidReceivePositionInformation(WebKit::InteractionInformationAtPosition information) + SelectionContextCallback(String selectedText, String beforeText, String afterText, uint64_t callbackID) + InterpretKeyEvent(struct WebKit::EditorState state, bool isCharEvent) -> (bool handled) + DidReceivePositionInformation(struct WebKit::InteractionInformationAtPosition information) + SaveImageToLibrary(WebKit::SharedMemory::Handle handle, uint64_t size) + DidUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold) + ShowPlaybackTargetPicker(bool hasVideo, WebCore::IntRect elementRect) + ZoomToRect(WebCore::FloatRect rect, double minimumScale, double maximumScale) + CommitPotentialTapFailed() + DidNotHandleTapAsClick(WebCore::IntPoint point) + DisableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID) + DrawToPDFCallback(IPC::DataReference pdfData, uint64_t callbackID) + SelectionRectsCallback(Vector<WebCore::SelectionRect> selectionRects, uint64_t callbackID); +#endif +#if ENABLE(DATA_DETECTION) + SetDataDetectionResult(struct WebKit::DataDetectionResult dataDetectionResult) #endif #if PLATFORM(GTK) PrintFinishedCallback(WebCore::ResourceError error, uint64_t callbackID) #endif +#if PLATFORM(COCOA) + MachSendRightCallback(WebCore::MachSendRight sendRight, uint64_t callbackID) +#endif PageScaleFactorDidChange(double scaleFactor) - PageZoomFactorDidChange(double zoomFactor) + PluginScaleFactorDidChange(double zoomFactor) + PluginZoomFactorDidChange(double zoomFactor) #if PLATFORM(GTK) - # Support for GTK+ platform keybindings - GetEditorCommandsForKeyEvent(AtomicString eventType) -> (Vector<String> commandsList) - # Support for connecting the Accessibility worlds of the UI and the Web processes BindAccessibilityTree(String plugID) @@ -182,44 +219,63 @@ messages -> WebPageProxy { BackForwardBackListCount() -> (int32_t count) BackForwardForwardListCount() -> (int32_t count) BackForwardClear() - WillGoToBackForwardListItem(uint64_t itemID, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + WillGoToBackForwardListItem(uint64_t itemID, WebKit::UserData userData) # Undo/Redo messages RegisterEditCommandForUndo(uint64_t commandID, uint32_t editAction) ClearAllEditCommands() + RegisterInsertionUndoGrouping() CanUndoRedo(uint32_t action) -> (bool result) ExecuteUndoRedo(uint32_t action) -> (bool result) + # Diagnostic messages logging + LogDiagnosticMessage(String message, String description, enum WebCore::ShouldSample shouldSample) + LogDiagnosticMessageWithResult(String message, String description, uint32_t result, enum WebCore::ShouldSample shouldSample) + LogDiagnosticMessageWithValue(String message, String description, double value, unsigned significantFigures, enum WebCore::ShouldSample shouldSample) + LogDiagnosticMessageWithEnhancedPrivacy(String message, String description, enum WebCore::ShouldSample shouldSample) + # Editor notifications - EditorStateChanged(WebKit::EditorState editorState) + EditorStateChanged(struct WebKit::EditorState editorState) + CompositionWasCanceled() + SetHasHadSelectionChangesFromUserInteraction(bool hasHadUserSelectionChanges) + SetNeedsHiddenContentEditableQuirk(bool needsHiddenContentEditableQuirk) + SetNeedsPlainTextQuirk(bool needsPlainTextQuirk) # Find messages DidCountStringMatches(String string, uint32_t matchCount) - SetFindIndicator(WebCore::FloatRect selectionRect, Vector<WebCore::FloatRect> textRects, float contentImageScaleFactor, WebKit::ShareableBitmap::Handle contentImageHandle, bool fadeOut, bool animate) - DidFindString(String string, uint32_t matchCount) + SetTextIndicator(struct WebCore::TextIndicatorData indicator, uint64_t lifetime) + ClearTextIndicator() + DidFindString(String string, Vector<WebCore::IntRect> matchRect, uint32_t matchCount, int32_t matchIndex) DidFailToFindString(String string) DidFindStringMatches(String string, Vector<Vector<WebCore::IntRect>> matches, int32_t firstIndexAfterSelection) DidGetImageForFindMatch(WebKit::ShareableBitmap::Handle contentImageHandle, uint32_t matchIndex) # PopupMenu messages - ShowPopupMenu(WebCore::IntRect rect, uint64_t textDirection, Vector<WebKit::WebPopupItem> items, int32_t selectedIndex, WebKit::PlatformPopupMenuData data) + ShowPopupMenu(WebCore::IntRect rect, uint64_t textDirection, Vector<WebKit::WebPopupItem> items, int32_t selectedIndex, struct WebKit::PlatformPopupMenuData data) HidePopupMenu() #if ENABLE(CONTEXT_MENUS) - # ContextMenu messages - ShowContextMenu(WebCore::IntPoint menuLocation, WebKit::WebHitTestResult::Data hitTestResultData, Vector<WebKit::WebContextMenuItemData> items, WebKit::InjectedBundleUserMessageEncoder userData) Variadic + ShowContextMenu(WebKit::ContextMenuContextData contextMenuContextData, WebKit::UserData userData) #endif # Authentication messages - CanAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, WebCore::ProtectionSpace protectionSpace) -> (bool canAuthenticate) DidReceiveAuthenticationChallenge(uint64_t frameID, WebCore::AuthenticationChallenge challenge, uint64_t challengeID) # Database messages ExceededDatabaseQuota(uint64_t frameID, String originIdentifier, String databaseName, String databaseDisplayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage) -> (uint64_t newQuota) Delayed + # Application cache messages + ReachedApplicationCacheOriginQuota(String originIdentifier, uint64_t currentQuota, uint64_t totalBytesNeeded) -> (uint64_t newQuota) Delayed + # Geolocation messages RequestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier) +#if ENABLE(MEDIA_STREAM) + # MediaSteam messages + RequestUserMediaPermissionForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier, struct WebCore::MediaConstraintsData audioConstraintsData, struct WebCore::MediaConstraintsData videoConstraintsData) + EnumerateMediaDevicesForFrame(uint64_t userMediaID, uint64_t frameID, String userMediaDocumentOriginIdentifier, String topLevelDocumentOriginIdentifier) +#endif + # Notification messages RequestNotificationPermission(uint64_t requestID, String originIdentifier) ShowNotification(String title, String body, String iconURL, String tag, String lang, String dir, String originIdentifier, uint64_t notificationID) @@ -229,36 +285,43 @@ messages -> WebPageProxy { # Spelling and grammar messages #if USE(UNIFIED_TEXT_CHECKING) - CheckTextOfParagraph(String text, uint64_t checkingTypes) -> (Vector<WebCore::TextCheckingResult> results) + CheckTextOfParagraph(String text, uint64_t checkingTypes, int32_t insertionPoint) -> (Vector<WebCore::TextCheckingResult> results) #endif CheckSpellingOfString(String text) -> (int32_t misspellingLocation, int32_t misspellingLength) CheckGrammarOfString(String text) -> (Vector<WebCore::GrammarDetail> results, int32_t badGrammarLocation, int32_t badGrammarLength) SpellingUIIsShowing() -> (bool isShowing) UpdateSpellingUIWithMisspelledWord(String misspelledWord) - UpdateSpellingUIWithGrammarString(String badGrammarPhrase, WebCore::GrammarDetail grammarDetail) - GetGuessesForWord(String word, String context) -> (Vector<String> guesses) + UpdateSpellingUIWithGrammarString(String badGrammarPhrase, struct WebCore::GrammarDetail grammarDetail) + GetGuessesForWord(String word, String context, int32_t insertionPoint) -> (Vector<String> guesses) LearnWord(String word); IgnoreWord(String word); - RequestCheckingOfString(uint64_t requestID, WebCore::TextCheckingRequestData request) + RequestCheckingOfString(uint64_t requestID, WebCore::TextCheckingRequestData request, int32_t insertionPoint) # Drag and drop messages #if ENABLE(DRAG_SUPPORT) - DidPerformDragControllerAction(WebCore::DragSession dragSession) + DidPerformDragControllerAction(uint64_t dragOperation, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted) +#endif +#if PLATFORM(COCOA) && ENABLE(DRAG_SUPPORT) + SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, WebCore::FloatPoint dragImageAnchor, bool linkDrag) + SetPromisedDataForImage(String pasteboardName, WebKit::SharedMemory::Handle imageHandle, uint64_t imageSize, String filename, String extension, String title, String url, String visibleURL, WebKit::SharedMemory::Handle archiveHandle, uint64_t archiveSize) +#if ENABLE(ATTACHMENT_ELEMENT) + SetPromisedDataForAttachment(String pasteboardName, String filename, String extension, String title, String url, String visibleURL) #endif -#if PLATFORM(MAC) && ENABLE(DRAG_SUPPORT) - SetDragImage(WebCore::IntPoint clientPosition, WebKit::ShareableBitmap::Handle dragImage, bool linkDrag) - SetPromisedData(String pasteboardName, WebKit::SharedMemory::Handle imageHandle, uint64_t imageSize, String filename, String extension, String title, String url, String visibleURL, WebKit::SharedMemory::Handle archiveHandle, uint64_t archiveSize) #endif #if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT) - StartDrag(WebCore::DragData dragData, WebKit::ShareableBitmap::Handle dragImage) + StartDrag(struct WebKit::WebSelectionData selection, uint64_t dragOperation, WebKit::ShareableBitmap::Handle dragImage) #endif -#if PLATFORM(MAC) +#if ENABLE(DATA_INTERACTION) + DidPerformDataInteractionControllerOperation() + DidHandleStartDataInteractionRequest(bool started) +#endif + +#if PLATFORM(COCOA) # Dictionary support. - DidPerformDictionaryLookup(WebKit::AttributedString text, WebKit::DictionaryPopupInfo dictionaryPopupInfo) + DidPerformDictionaryLookup(struct WebCore::DictionaryPopupInfo dictionaryPopupInfo) # Keyboard input support messages - InterpretQueuedKeyEvent(WebKit::EditorState state) -> (bool handled, Vector<WebCore::KeypressCommand> savedCommands) ExecuteSavedCommandBySelector(String selector) -> (bool handled) # Remote accessibility messages @@ -284,12 +347,21 @@ messages -> WebPageProxy { #if USE(APPKIT) SubstitutionsPanelIsShowing() -> (bool isShowing) #endif -#if !PLATFORM(IOS) && PLATFORM(MAC) +#if USE(AUTOMATIC_TEXT_REPLACEMENT) + toggleSmartInsertDelete() + toggleAutomaticQuoteSubstitution() + toggleAutomaticLinkDetection() + toggleAutomaticDashSubstitution() + toggleAutomaticTextReplacement() +#endif +#if PLATFORM(MAC) # Autocorrection messages ShowCorrectionPanel(int32_t panelType, WebCore::FloatRect boundingBoxOfReplacedString, String replacedString, String replacementString, Vector<String> alternativeReplacementStrings) DismissCorrectionPanel(int32_t reason) DismissCorrectionPanelSoon(int32_t reason) -> (String result) - RecordAutocorrectionResponse(int32_t responseType, String replacedString, String replacementString); + RecordAutocorrectionResponse(int32_t response, String replacedString, String replacementString); + + SetEditableElementIsFocused(bool editableElementIsFocused) #endif #if USE(DICTATION_ALTERNATIVES) @@ -306,30 +378,33 @@ messages -> WebPageProxy { #endif #if PLATFORM(IOS) - MainDocumentDidReceiveMobileDocType(); - + DynamicViewportUpdateChangedTarget(double newTargetScale, WebCore::FloatPoint newScrollPosition, uint64_t dynamicViewportSizeUpdateID) + CouldNotRestorePageState() + RestorePageState(WebCore::FloatPoint scrollPosition, WebCore::FloatPoint scrollOrigin, WebCore::FloatSize obscuredInsetOnSave, double scale) + RestorePageCenterAndScale(WebCore::FloatPoint unobscuredCenter, double scale) DidGetTapHighlightGeometries(uint64_t requestID, WebCore::Color color, Vector<WebCore::FloatQuad> geometries, WebCore::IntSize topLeftRadius, WebCore::IntSize topRightRadius, WebCore::IntSize bottomLeftRadius, WebCore::IntSize bottomRightRadius) - DidChangeViewportArguments(WebCore::ViewportArguments viewportArguments) - StartAssistingNode(WebCore::IntRect scrollRect, bool hasNextFocusable, bool hasPreviousFocusable) + StartAssistingNode(struct WebKit::AssistedNodeInformation information, bool userIsInteracting, bool blurPreviousNode, WebKit::UserData userData) StopAssistingNode() - NotifyRevealedSelection() -#endif + OverflowScrollWillStartScroll() + OverflowScrollDidEndScroll() + ShowInspectorHighlight(struct WebCore::Highlight highlight) + HideInspectorHighlight() - # Search popup menus - SaveRecentSearches(String name, Vector<String> searchItems) - LoadRecentSearches(String name) -> (Vector<String> result) + ShowInspectorIndication() + HideInspectorIndication() -#if USE(SOUP) -#if !ENABLE(CUSTOM_PROTOCOLS) - # Soup custom URI request messages - DidReceiveURIRequest(String uriString, uint64_t requestID); -#endif + EnableInspectorNodeSearch() + DisableInspectorNodeSearch() #endif + # Search popup menus + SaveRecentSearches(String name, Vector<WebCore::RecentSearch> searchItems) + LoadRecentSearches(String name) -> (Vector<WebCore::RecentSearch> result) + SavePDFToFileInDownloadsFolder(String suggestedFilename, String originatingURLString, IPC::DataReference data) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) SavePDFToTemporaryFolderAndOpenWithNativeApplication(String suggestedFilename, String originatingURLString, IPC::DataReference data, String pdfUUID) OpenPDFFromTemporaryFolderWithNativeApplication(String pdfUUID) #endif @@ -338,7 +413,84 @@ messages -> WebPageProxy { FindPlugin(String mimeType, uint32_t processType, String urlString, String frameURLString, String pageURLString, bool allowOnlyApplicationPlugins) -> (uint64_t pluginProcessToken, String newMIMEType, uint32_t pluginLoadPolicy, String unavailabilityDescription) #endif - DidUpdateViewState() - + DidUpdateActivityState() + DidSaveToPageCache() + +#if ENABLE(SUBTLE_CRYPTO) + WrapCryptoKey(Vector<uint8_t> key) -> (bool succeeded, Vector<uint8_t> wrappedKey) + UnwrapCryptoKey(Vector<uint8_t> wrappedKey) -> (bool succeeded, Vector<uint8_t> key) +#endif + + +#if ENABLE(TELEPHONE_NUMBER_DETECTION) +#if PLATFORM(MAC) + ShowTelephoneNumberMenu(String telephoneNumber, WebCore::IntPoint point) +#endif +#endif + +#if USE(QUICK_LOOK) + DidStartLoadForQuickLookDocumentInMainFrame(String fileName, String uti) + DidFinishLoadForQuickLookDocumentInMainFrame(WebKit::QuickLookDocumentData data) + DidRequestPasswordForQuickLookDocumentInMainFrame(String fileName) +#endif + +#if ENABLE(CONTENT_FILTERING) + ContentFilterDidBlockLoadForFrame(WebCore::ContentFilterUnblockHandler unblockHandler, uint64_t frameID) +#endif + + IsPlayingMediaDidChange(unsigned state, uint64_t sourceElementID) + DidPlayMediaPreventedFromPlayingWithoutUserGesture() + +#if ENABLE(MEDIA_SESSION) + HasMediaSessionWithActiveMediaElementsDidChange(bool state) + MediaSessionMetadataDidChange(WebCore::MediaSessionMetadata metadata); + FocusedContentMediaElementDidChange(uint64_t elementID) +#endif + +#if PLATFORM(MAC) + DidPerformImmediateActionHitTest(struct WebKit::WebHitTestResultData result, bool contentPreventsDefault, WebKit::UserData userData) +#endif + HandleMessage(String messageName, WebKit::UserData messageBody) WantsConnection + HandleSynchronousMessage(String messageName, WebKit::UserData messageBody) -> (WebKit::UserData returnData) WantsConnection + + HandleAutoFillButtonClick(WebKit::UserData userData); + +#if ENABLE(WIRELESS_PLAYBACK_TARGET) && !PLATFORM(IOS) + AddPlaybackTargetPickerClient(uint64_t contextId) + RemovePlaybackTargetPickerClient(uint64_t contextId) + ShowPlaybackTargetPicker(uint64_t clientId, WebCore::FloatRect pickerLocation, bool hasVideo) + PlaybackTargetPickerClientStateDidChange(uint64_t contextId, unsigned mediaState) + SetMockMediaPlaybackTargetPickerEnabled(bool enabled) + SetMockMediaPlaybackTargetPickerState(String name, unsigned pickerState) +#endif + +#if ENABLE(POINTER_LOCK) + RequestPointerLock() + RequestPointerUnlock() +#endif + + ImageOrMediaDocumentSizeChanged(WebCore::IntSize newSize) + + UseFixedLayoutDidChange(bool useFixedLayout) + FixedLayoutSizeDidChange(WebCore::IntSize fixedLayoutSize) + +#if ENABLE(VIDEO) && USE(GSTREAMER) + RequestInstallMissingMediaPlugins(String details, String description) +#endif + + DidRestoreScrollPosition() + + GetLoadDecisionForIcon(struct WebCore::LinkIcon icon, uint64_t callbackID) + FinishedLoadingIcon(uint64_t callbackIdentifier, IPC::DataReference data); + +#if PLATFORM(MAC) + DidHandleAcceptedCandidate() +#endif + +#if PLATFORM(COCOA) + HandleActiveNowPlayingSessionInfoResponse(bool hasActiveSession, String title, double duration, double elapsedTime) +#endif + + SetIsUsingHighPerformanceWebGL(bool isUsingHighPerformanceWebGL) } diff --git a/Source/WebKit2/UIProcess/WebPasteboardProxy.cpp b/Source/WebKit2/UIProcess/WebPasteboardProxy.cpp new file mode 100644 index 000000000..0b7886eab --- /dev/null +++ b/Source/WebKit2/UIProcess/WebPasteboardProxy.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebPasteboardProxy.h" + +#include "WebPasteboardProxyMessages.h" +#include "WebProcessProxy.h" +#include <mutex> + +namespace WebKit { + +WebPasteboardProxy& WebPasteboardProxy::singleton() +{ + static std::once_flag onceFlag; + static LazyNeverDestroyed<WebPasteboardProxy> proxy; + + std::call_once(onceFlag, [] { + proxy.construct(); + }); + + return proxy; +} + +WebPasteboardProxy::WebPasteboardProxy() +{ +} + +void WebPasteboardProxy::addWebProcessProxy(WebProcessProxy& webProcessProxy) +{ + // FIXME: Can we handle all of these on a background queue? + webProcessProxy.addMessageReceiver(Messages::WebPasteboardProxy::messageReceiverName(), *this); + m_webProcessProxyList.add(&webProcessProxy); +} + +void WebPasteboardProxy::removeWebProcessProxy(WebProcessProxy& webProcessProxy) +{ + m_webProcessProxyList.remove(&webProcessProxy); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPasteboardProxy.h b/Source/WebKit2/UIProcess/WebPasteboardProxy.h new file mode 100644 index 000000000..f156e4b91 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebPasteboardProxy.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebPasteboardProxy_h +#define WebPasteboardProxy_h + +#include "MessageReceiver.h" +#include "SharedMemory.h" +#include <wtf/Forward.h> +#include <wtf/HashSet.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/Vector.h> + +namespace WebCore { +class Color; +struct PasteboardImage; +struct PasteboardWebContent; +} + +namespace WebKit { + +class WebFrameProxy; +class WebProcessProxy; +struct WebSelectionData; + +class WebPasteboardProxy : public IPC::MessageReceiver { + WTF_MAKE_NONCOPYABLE(WebPasteboardProxy); + friend class LazyNeverDestroyed<WebPasteboardProxy>; +public: + static WebPasteboardProxy& singleton(); + + void addWebProcessProxy(WebProcessProxy&); + void removeWebProcessProxy(WebProcessProxy&); + +#if PLATFORM(GTK) + void setPrimarySelectionOwner(WebFrameProxy*); + void didDestroyFrame(WebFrameProxy*); +#endif + +private: + WebPasteboardProxy(); + + typedef HashSet<WebProcessProxy*> WebProcessProxyList; + + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + +#if PLATFORM(IOS) + void writeWebContentToPasteboard(const WebCore::PasteboardWebContent&, const String& pasteboardName); + void writeImageToPasteboard(const WebCore::PasteboardImage&, const String& pasteboardName); + void writeStringToPasteboard(const String& pasteboardType, const String&, const String& pasteboardName); + void readStringFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, WTF::String&); + void readURLFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, String&); + void readBufferFromPasteboard(uint64_t index, const String& pasteboardType, const String& pasteboardName, SharedMemory::Handle&, uint64_t& size); + void getPasteboardItemsCount(const String& pasteboardName, uint64_t& itemsCount); +#endif +#if PLATFORM(COCOA) + void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes); + void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames); + void getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String&); + void getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size); + void pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, uint64_t& newChangeCount); + void getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount); + void getPasteboardUniqueName(String& pasteboardName); + void getPasteboardColor(const String& pasteboardName, WebCore::Color&); + void getPasteboardURL(const String& pasteboardName, WTF::String&); + void addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); + void setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); + void setPasteboardPathnamesForType(IPC::Connection&, const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames, uint64_t& newChangeCount); + void setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String&, uint64_t& newChangeCount); + void setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle&, uint64_t size, uint64_t& newChangeCount); +#endif +#if PLATFORM(GTK) + void writeToClipboard(const String& pasteboardName, const WebSelectionData&); + void readFromClipboard(const String& pasteboardName, WebSelectionData&); + + WebFrameProxy* m_primarySelectionOwner { nullptr }; + WebFrameProxy* m_frameWritingToClipboard { nullptr }; +#endif // PLATFORM(GTK) + + WebProcessProxyList m_webProcessProxyList; +}; + +} // namespace WebKit + +#endif // WebPasteboardProxy_h diff --git a/Source/WebKit2/UIProcess/WebContext.messages.in b/Source/WebKit2/UIProcess/WebPasteboardProxy.messages.in index 056088c4e..c267922f6 100644 --- a/Source/WebKit2/UIProcess/WebContext.messages.in +++ b/Source/WebKit2/UIProcess/WebPasteboardProxy.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2010 Apple Inc. All rights reserved. +# Copyright (C) 2014 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,24 +20,18 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -messages -> WebContext LegacyReceiver { - - # Visited link provider messages. - AddVisitedLinkHash(uint64_t linkHash) - - DidGetStatistics(WebKit::StatisticsData statisticsData, uint64_t callbackID) - +messages -> WebPasteboardProxy { #if PLATFORM(IOS) - WriteWebContentToPasteboard(WebCore::PasteboardWebContent content) - WriteImageToPasteboard(WebCore::PasteboardImage pasteboardImage) - WriteStringToPasteboard(String pasteboardType, String text) - ReadStringFromPasteboard(uint64_t index, String pasteboardType) -> (String string) - ReadURLFromPasteboard(uint64_t index, String pasteboardType) -> (String string) - ReadBufferFromPasteboard(uint64_t index, String pasteboardType) -> (WebKit::SharedMemory::Handle handle, uint64_t size) - GetPasteboardItemsCount() -> (uint64_t itemsCount) + WriteWebContentToPasteboard(struct WebCore::PasteboardWebContent content, String pasteboardName) + WriteImageToPasteboard(struct WebCore::PasteboardImage pasteboardImage, String pasteboardName) + WriteStringToPasteboard(String pasteboardType, String text, String pasteboardName) + ReadStringFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (String string) + ReadURLFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (String string) + ReadBufferFromPasteboard(uint64_t index, String pasteboardType, String pasteboardName) -> (WebKit::SharedMemory::Handle handle, uint64_t size) + GetPasteboardItemsCount(String pasteboardName) -> (uint64_t itemsCount) #endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) # Pasteboard messages. GetPasteboardTypes(String pasteboardName) -> (Vector<String> types) GetPasteboardPathnamesForType(String pasteboardName, String pasteboardType) -> (Vector<String> pathnames) @@ -50,18 +44,13 @@ messages -> WebContext LegacyReceiver { GetPasteboardURL(String pasteboardName) -> (String urlString) AddPasteboardTypes(String pasteboardName, Vector<String> pasteboardTypes) -> (uint64_t changeCount) SetPasteboardTypes(String pasteboardName, Vector<String> pasteboardTypes) -> (uint64_t changeCount) - SetPasteboardPathnamesForType(String pasteboardName, String pasteboardType, Vector<String> pathnames) -> (uint64_t changeCount) + SetPasteboardPathnamesForType(String pasteboardName, String pasteboardType, Vector<String> pathnames) -> (uint64_t changeCount) WantsConnection SetPasteboardStringForType(String pasteboardName, String pasteboardType, String string) -> (uint64_t changeCount) SetPasteboardBufferForType(String pasteboardName, String pasteboardType, WebKit::SharedMemory::Handle handle, uint64_t size) -> (uint64_t changeCount) #endif -#if !PLATFORM(MAC) - // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require - // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. - Dummy() -> (bool dummyReturn) +#if PLATFORM(GTK) + WriteToClipboard(String pasteboardName, struct WebKit::WebSelectionData pasteboardContent) + ReadFromClipboard(String pasteboardName) -> (struct WebKit::WebSelectionData pasteboardContent) #endif - - # Plug-in messages. - void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash) - void PlugInDidReceiveUserInteraction(uint32_t hash) } diff --git a/Source/WebKit2/UIProcess/WebPopupMenuProxy.h b/Source/WebKit2/UIProcess/WebPopupMenuProxy.h index 4c5c8e0c0..bc16a0f22 100644 --- a/Source/WebKit2/UIProcess/WebPopupMenuProxy.h +++ b/Source/WebKit2/UIProcess/WebPopupMenuProxy.h @@ -26,8 +26,7 @@ #ifndef WebPopupMenuProxy_h #define WebPopupMenuProxy_h -#include <WebCore/TextDirection.h> -#include <wtf/PassRefPtr.h> +#include <WebCore/WritingMode.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> @@ -62,16 +61,15 @@ public: { } -#if !PLATFORM(EFL) virtual void showPopupMenu(const WebCore::IntRect& rect, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex) = 0; virtual void hidePopupMenu() = 0; -#endif + virtual void cancelTracking() { } void invalidate() { m_client = 0; } protected: - explicit WebPopupMenuProxy(Client* client) - : m_client(client) + explicit WebPopupMenuProxy(Client& client) + : m_client(&client) { } diff --git a/Source/WebKit2/UIProcess/WebPreferences.cpp b/Source/WebKit2/UIProcess/WebPreferences.cpp index a4c4b796a..dc33bfeae 100644 --- a/Source/WebKit2/UIProcess/WebPreferences.cpp +++ b/Source/WebKit2/UIProcess/WebPreferences.cpp @@ -26,62 +26,90 @@ #include "config.h" #include "WebPreferences.h" -#include "WebContext.h" #include "WebPageGroup.h" +#include "WebPreferencesKeys.h" +#include "WebProcessPool.h" +#include <wtf/NeverDestroyed.h> #include <wtf/ThreadingPrimitives.h> namespace WebKit { // FIXME: Manipulating this variable is not thread safe. // Instead of tracking private browsing state as a boolean preference, we should let the client provide storage sessions explicitly. -static unsigned privateBrowsingPageGroupCount; +static unsigned privateBrowsingPageCount; -WebPreferences::WebPreferences() +Ref<WebPreferences> WebPreferences::create(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix) { - platformInitializeStore(); + return adoptRef(*new WebPreferences(identifier, keyPrefix, globalDebugKeyPrefix)); } -WebPreferences::WebPreferences(const String& identifier) +PassRefPtr<WebPreferences> WebPreferences::createWithLegacyDefaults(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix) +{ + auto preferences = WebPreferences::create(identifier, keyPrefix, globalDebugKeyPrefix); + // FIXME: The registerDefault...ValueForKey machinery is unnecessarily heavyweight and complicated. + // We can just compute different defaults for modern and legacy APIs in WebPreferencesDefinitions.h macros. + preferences->registerDefaultBoolValueForKey(WebPreferencesKey::javaEnabledKey(), true); + preferences->registerDefaultBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey(), true); + preferences->registerDefaultBoolValueForKey(WebPreferencesKey::pluginsEnabledKey(), true); + preferences->registerDefaultUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey(), WebCore::SecurityOrigin::AllowAllStorage); + return WTFMove(preferences); +} + +WebPreferences::WebPreferences(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix) : m_identifier(identifier) + , m_keyPrefix(keyPrefix) + , m_globalDebugKeyPrefix(globalDebugKeyPrefix) { platformInitializeStore(); } WebPreferences::WebPreferences(const WebPreferences& other) - : m_store(other.m_store) + : m_keyPrefix(other.m_keyPrefix) + , m_globalDebugKeyPrefix(other.m_globalDebugKeyPrefix) + , m_store(other.m_store) { platformInitializeStore(); } WebPreferences::~WebPreferences() { - ASSERT(m_pageGroups.isEmpty()); + ASSERT(m_pages.isEmpty()); } -void WebPreferences::addPageGroup(WebPageGroup* pageGroup) +PassRefPtr<WebPreferences> WebPreferences::copy() const { - bool didAddPageGroup = m_pageGroups.add(pageGroup).isNewEntry; - if (didAddPageGroup && privateBrowsingEnabled()) { - if (!privateBrowsingPageGroupCount) - WebContext::willStartUsingPrivateBrowsing(); - ++privateBrowsingPageGroupCount; + return adoptRef(*new WebPreferences(*this)); +} + +void WebPreferences::addPage(WebPageProxy& webPageProxy) +{ + ASSERT(!m_pages.contains(&webPageProxy)); + m_pages.add(&webPageProxy); + + if (privateBrowsingEnabled()) { + if (!privateBrowsingPageCount) + WebProcessPool::willStartUsingPrivateBrowsing(); + + ++privateBrowsingPageCount; } } -void WebPreferences::removePageGroup(WebPageGroup* pageGroup) +void WebPreferences::removePage(WebPageProxy& webPageProxy) { - bool didRemovePageGroup = m_pageGroups.remove(pageGroup); - if (didRemovePageGroup && privateBrowsingEnabled()) { - --privateBrowsingPageGroupCount; - if (!privateBrowsingPageGroupCount) - WebContext::willStopUsingPrivateBrowsing(); + ASSERT(m_pages.contains(&webPageProxy)); + m_pages.remove(&webPageProxy); + + if (privateBrowsingEnabled()) { + --privateBrowsingPageCount; + if (!privateBrowsingPageCount) + WebProcessPool::willStopUsingPrivateBrowsing(); } } void WebPreferences::update() { - for (HashSet<WebPageGroup*>::iterator it = m_pageGroups.begin(), end = m_pageGroups.end(); it != end; ++it) - (*it)->preferencesDidChange(); + for (auto& webPageProxy : m_pages) + webPageProxy->preferencesDidChange(); } void WebPreferences::updateStringValueForKey(const String& key, const String& value) @@ -101,6 +129,11 @@ void WebPreferences::updateBoolValueForKey(const String& key, bool value) update(); // FIXME: Only send over the changed key and value. } +void WebPreferences::updateBoolValueForExperimentalFeatureKey(const String& key, bool value) +{ + update(); // FIXME: Only send over the changed key and value. +} + void WebPreferences::updateUInt32ValueForKey(const String& key, uint32_t value) { platformUpdateUInt32ValueForKey(key, value); @@ -123,27 +156,27 @@ void WebPreferences::updatePrivateBrowsingValue(bool value) { platformUpdateBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey(), value); - unsigned pageGroupsChanged = m_pageGroups.size(); - if (!pageGroupsChanged) + unsigned pagesChanged = m_pages.size(); + if (!pagesChanged) return; if (value) { - if (!privateBrowsingPageGroupCount) - WebContext::willStartUsingPrivateBrowsing(); - privateBrowsingPageGroupCount += pageGroupsChanged; + if (!privateBrowsingPageCount) + WebProcessPool::willStartUsingPrivateBrowsing(); + privateBrowsingPageCount += pagesChanged; } update(); // FIXME: Only send over the changed key and value. if (!value) { - ASSERT(privateBrowsingPageGroupCount >= pageGroupsChanged); - privateBrowsingPageGroupCount -= pageGroupsChanged; - if (!privateBrowsingPageGroupCount) - WebContext::willStopUsingPrivateBrowsing(); + ASSERT(privateBrowsingPageCount >= pagesChanged); + privateBrowsingPageCount -= pagesChanged; + if (!privateBrowsingPageCount) + WebProcessPool::willStopUsingPrivateBrowsing(); } } -#define DEFINE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \ +#define DEFINE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ void WebPreferences::set##KeyUpper(const Type& value) \ { \ if (!m_store.set##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), value)) \ @@ -158,12 +191,138 @@ void WebPreferences::updatePrivateBrowsingValue(bool value) } \ FOR_EACH_WEBKIT_PREFERENCE(DEFINE_PREFERENCE_GETTER_AND_SETTERS) +FOR_EACH_WEBKIT_DEBUG_PREFERENCE(DEFINE_PREFERENCE_GETTER_AND_SETTERS) #undef DEFINE_PREFERENCE_GETTER_AND_SETTERS -bool WebPreferences::anyPageGroupsAreUsingPrivateBrowsing() +#define DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ + void WebPreferences::set##KeyUpper(const Type& value) \ + { \ + if (!m_store.set##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), value)) \ + return; \ + update##TypeName##ValueForExperimentalFeatureKey(WebPreferencesKey::KeyLower##Key(), value); \ + \ + } \ + \ + Type WebPreferences::KeyLower() const \ + { \ + return m_store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()); \ + } \ + +FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS) + +#undef DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS + +static Vector<RefPtr<API::Object>> createExperimentalFeaturesVector() +{ + Vector<RefPtr<API::Object>> features; + +#define ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ + features.append(API::ExperimentalFeature::create(HumanReadableName, #KeyUpper, HumanReadableDescription, DefaultValue)); \ + + FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION) + +#undef ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION + + return features; +} + +const Vector<RefPtr<API::Object>>& WebPreferences::experimentalFeatures() +{ + static NeverDestroyed<Vector<RefPtr<API::Object>>> features = createExperimentalFeaturesVector(); + return features; +} + +bool WebPreferences::isEnabledForFeature(const API::ExperimentalFeature& feature) const +{ + struct FeatureGetterMapping { + const char* name; + bool (WebPreferences::*function) () const; + }; + +#define MAKE_FEATURE_GETTER(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ + { #KeyUpper, &WebPreferences::KeyLower }, \ + + static FeatureGetterMapping getters[] = { + FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(MAKE_FEATURE_GETTER) + }; + +#undef MAKE_FEATURE_GETTER + + const String& key = feature.key(); + + for (auto& getter : getters) { + if (key == getter.name) + return (this->*getter.function)(); + } + + return false; +} + +void WebPreferences::setPeerConnectionAndMediaStreamEnabled(bool value) +{ + setPeerConnectionEnabled(value); + setMediaStreamEnabled(value); +} + +void WebPreferences::setEnabledForFeature(bool value, const API::ExperimentalFeature& feature) +{ + struct FeatureSetterMapping { + const char* name; + void (WebPreferences::*function) (const bool&); + }; + +#define MAKE_FEATURE_SETTER(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ + { #KeyUpper, &WebPreferences::set##KeyUpper }, \ + + static FeatureSetterMapping setters[] = { + FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(MAKE_FEATURE_SETTER) + }; + +#undef MAKE_FEATURE_SETTER + + const String& key = feature.key(); + + for (auto& setter : setters) { + if (key == setter.name) { + if (key == WebPreferencesKey::peerConnectionEnabledKey()) + setPeerConnectionAndMediaStreamEnabled(value); + else + (this->*setter.function)(value); + return; + } + } +} + +void WebPreferences::enableAllExperimentalFeatures() +{ +#define SET_FEATURE_ENABLED(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ + set##KeyUpper(true); \ + + FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(SET_FEATURE_ENABLED) + +#undef SET_FEATURE_ENABLED +} + +bool WebPreferences::anyPagesAreUsingPrivateBrowsing() +{ + return privateBrowsingPageCount; +} + +void WebPreferences::registerDefaultBoolValueForKey(const String& key, bool value) +{ + m_store.setOverrideDefaultsBoolValueForKey(key, value); + bool userValue; + if (platformGetBoolUserValueForKey(key, userValue)) + m_store.setBoolValueForKey(key, userValue); +} + +void WebPreferences::registerDefaultUInt32ValueForKey(const String& key, uint32_t value) { - return privateBrowsingPageGroupCount; + m_store.setOverrideDefaultsUInt32ValueForKey(key, value); + uint32_t userValue; + if (platformGetUInt32UserValueForKey(key, userValue)) + m_store.setUInt32ValueForKey(key, userValue); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebPreferences.h b/Source/WebKit2/UIProcess/WebPreferences.h index 725d6113d..54435b87a 100644 --- a/Source/WebKit2/UIProcess/WebPreferences.h +++ b/Source/WebKit2/UIProcess/WebPreferences.h @@ -26,68 +26,62 @@ #ifndef WebPreferences_h #define WebPreferences_h +#include "APIExperimentalFeature.h" #include "APIObject.h" #include "FontSmoothingLevel.h" +#include "WebPreferencesDefinitions.h" #include "WebPreferencesStore.h" #include <wtf/HashSet.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> -#define DECLARE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \ +#define DECLARE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \ void set##KeyUpper(const Type& value); \ Type KeyLower() const; namespace WebKit { -class WebPageGroup; +class WebPageProxy; class WebPreferences : public API::ObjectImpl<API::Object::Type::Preferences> { public: - static PassRefPtr<WebPreferences> create() - { - return adoptRef(new WebPreferences); - } - static PassRefPtr<WebPreferences> create(const String& identifier) - { - return adoptRef(new WebPreferences(identifier)); - } - - static PassRefPtr<WebPreferences> create(const WebPreferences& other) - { - return adoptRef(new WebPreferences(other)); - } + static Ref<WebPreferences> create(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix); + static PassRefPtr<WebPreferences> createWithLegacyDefaults(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix); + + explicit WebPreferences(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix); + WebPreferences(const WebPreferences&); virtual ~WebPreferences(); - void addPageGroup(WebPageGroup*); - void removePageGroup(WebPageGroup*); + PassRefPtr<WebPreferences> copy() const; - const WebPreferencesStore& store() const { return m_store; } + void addPage(WebPageProxy&); + void removePage(WebPageProxy&); -#define DECLARE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \ - void set##KeyUpper(const Type& value); \ - Type KeyLower() const; \ + const WebPreferencesStore& store() const { return m_store; } FOR_EACH_WEBKIT_PREFERENCE(DECLARE_PREFERENCE_GETTER_AND_SETTERS) + FOR_EACH_WEBKIT_DEBUG_PREFERENCE(DECLARE_PREFERENCE_GETTER_AND_SETTERS) + FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(DECLARE_PREFERENCE_GETTER_AND_SETTERS) -#undef DECLARE_PREFERENCE_GETTER_AND_SETTERS + static const Vector<RefPtr<API::Object>>& experimentalFeatures(); + bool isEnabledForFeature(const API::ExperimentalFeature&) const; + void setEnabledForFeature(bool, const API::ExperimentalFeature&); + void enableAllExperimentalFeatures(); // Exposed for WebKitTestRunner use only. void forceUpdate() { update(); } - static bool anyPageGroupsAreUsingPrivateBrowsing(); + static bool anyPagesAreUsingPrivateBrowsing(); private: - WebPreferences(); - explicit WebPreferences(const String&); - WebPreferences(const WebPreferences&); - void platformInitializeStore(); void update(); void updateStringValueForKey(const String& key, const String& value); void updateBoolValueForKey(const String& key, bool value); + void updateBoolValueForExperimentalFeatureKey(const String& key, bool value); void updateUInt32ValueForKey(const String& key, uint32_t value); void updateDoubleValueForKey(const String& key, double value); void updateFloatValueForKey(const String& key, float value); @@ -99,9 +93,22 @@ private: void updatePrivateBrowsingValue(bool value); - HashSet<WebPageGroup*> m_pageGroups; + void setPeerConnectionAndMediaStreamEnabled(bool value); + + void registerDefaultBoolValueForKey(const String&, bool); + void registerDefaultUInt32ValueForKey(const String&, uint32_t); + + bool platformGetStringUserValueForKey(const String& key, String& userValue); + bool platformGetBoolUserValueForKey(const String&, bool&); + bool platformGetUInt32UserValueForKey(const String&, uint32_t&); + bool platformGetDoubleUserValueForKey(const String&, double&); + + const String m_identifier; + const String m_keyPrefix; + const String m_globalDebugKeyPrefix; WebPreferencesStore m_store; - String m_identifier; + + HashSet<WebPageProxy*> m_pages; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.cpp b/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.cpp new file mode 100644 index 000000000..c36474f2b --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessLifetimeObserver.h" + +#include "WebPageProxy.h" +#include "WebProcessProxy.h" + +namespace WebKit { + +WebProcessLifetimeObserver::WebProcessLifetimeObserver() +{ +} + +WebProcessLifetimeObserver::~WebProcessLifetimeObserver() +{ +} + +void WebProcessLifetimeObserver::addWebPage(WebPageProxy& webPageProxy) +{ + auto& process = webPageProxy.process(); + + ASSERT(process.state() == WebProcessProxy::State::Running); + + if (m_processes.add(&process).isNewEntry) + webProcessWillOpenConnection(process, *process.connection()); + + webPageWillOpenConnection(webPageProxy, *process.connection()); +} + +void WebProcessLifetimeObserver::removeWebPage(WebPageProxy& webPageProxy) +{ + auto& process = webPageProxy.process(); + + // FIXME: This should assert that the page is either closed or that the process is no longer running, + // but we have to make sure that removeWebPage is called after the connection has been removed in that case. + ASSERT(m_processes.contains(&process)); + + webPageDidCloseConnection(webPageProxy, *process.connection()); + + if (m_processes.remove(&process)) + webProcessDidCloseConnection(process, *process.connection()); +} + +WTF::IteratorRange<HashCountedSet<WebProcessProxy*>::const_iterator::Keys> WebProcessLifetimeObserver::processes() const +{ + ASSERT(std::all_of(m_processes.begin().keys(), m_processes.end().keys(), [](WebProcessProxy* process) { + return process->state() == WebProcessProxy::State::Running; + })); + + return makeIteratorRange(m_processes.begin().keys(), m_processes.end().keys()); +} + +} diff --git a/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.h b/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.h new file mode 100644 index 000000000..5c5bfeae3 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessLifetimeObserver.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebProcessLifetimeObserver_h +#define WebProcessLifetimeObserver_h + +#include <wtf/HashCountedSet.h> +#include <wtf/IteratorRange.h> + +namespace IPC { +class Connection; +} + +namespace WebKit { + +class WebPageProxy; +class WebProcessProxy; + +class WebProcessLifetimeObserver { +public: + WebProcessLifetimeObserver(); + virtual ~WebProcessLifetimeObserver(); + + void addWebPage(WebPageProxy&); + void removeWebPage(WebPageProxy&); + + WTF::IteratorRange<HashCountedSet<WebProcessProxy*>::const_iterator::Keys> processes() const; + +private: + friend class WebProcessLifetimeTracker; + + virtual void webPageWasAdded(WebPageProxy&) { } + virtual void webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) { } + virtual void webPageWillOpenConnection(WebPageProxy&, IPC::Connection&) { } + virtual void webPageDidCloseConnection(WebPageProxy&, IPC::Connection&) { } + virtual void webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) { } + virtual void webPageWasRemoved(WebPageProxy&) { } + + HashCountedSet<WebProcessProxy*> m_processes; +}; + +} + +#endif // WebProcessLifetimeObserver_h diff --git a/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.cpp b/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.cpp new file mode 100644 index 000000000..b080cc81c --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessLifetimeTracker.h" + +#include "WebProcessLifetimeObserver.h" +#include "WebProcessProxy.h" + +namespace WebKit { + +WebProcessLifetimeTracker::WebProcessLifetimeTracker(WebPageProxy& webPageProxy) + : m_webPageProxy(webPageProxy) +{ +} + +WebProcessLifetimeTracker::~WebProcessLifetimeTracker() +{ +} + +void WebProcessLifetimeTracker::addObserver(WebProcessLifetimeObserver& observer) +{ + ASSERT(!m_observers.contains(&observer)); + + m_observers.add(&observer); + + observer.webPageWasAdded(m_webPageProxy); + + if (processIsRunning()) + observer.addWebPage(m_webPageProxy); +} + +void WebProcessLifetimeTracker::connectionWillOpen(IPC::Connection&) +{ + ASSERT(processIsRunning()); + + for (auto& observer : m_observers) + observer->addWebPage(m_webPageProxy); +} + +void WebProcessLifetimeTracker::webProcessWillShutDown() +{ + ASSERT(processIsRunning()); + + for (auto& observer : m_observers) + observer->removeWebPage(m_webPageProxy); +} + +void WebProcessLifetimeTracker::pageWasInvalidated() +{ + if (!processIsRunning()) + return; + + for (auto& observer : m_observers) { + observer->removeWebPage(m_webPageProxy); + + observer->webPageWasRemoved(m_webPageProxy); + } +} + +bool WebProcessLifetimeTracker::processIsRunning() +{ + return m_webPageProxy.process().state() == WebProcessProxy::State::Running; +} + +} diff --git a/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.h b/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.h new file mode 100644 index 000000000..7a73b7367 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessLifetimeTracker.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebProcessLifetimeTracker_h +#define WebProcessLifetimeTracker_h + +#include <wtf/HashSet.h> + +namespace IPC { +class Connection; +} + +namespace WebKit { + +class WebPageProxy; +class WebProcessLifetimeObserver; + +class WebProcessLifetimeTracker { +public: + explicit WebProcessLifetimeTracker(WebPageProxy&); + ~WebProcessLifetimeTracker(); + + void addObserver(WebProcessLifetimeObserver&); + + void connectionWillOpen(IPC::Connection&); + void webProcessWillShutDown(); + + void pageWasInvalidated(); + +private: + bool processIsRunning(); + + WebPageProxy& m_webPageProxy; + + HashSet<WebProcessLifetimeObserver*> m_observers; +}; + +} + +#endif // WebProcessLifetimeTracker_h diff --git a/Source/WebKit2/UIProcess/WebProcessPool.cpp b/Source/WebKit2/UIProcess/WebProcessPool.cpp new file mode 100644 index 000000000..33ccfadd1 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessPool.cpp @@ -0,0 +1,1447 @@ +/* + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessPool.h" + +#include "APIArray.h" +#include "APIAutomationClient.h" +#include "APICustomProtocolManagerClient.h" +#include "APIDownloadClient.h" +#include "APILegacyContextHistoryClient.h" +#include "APIPageConfiguration.h" +#include "APIProcessPoolConfiguration.h" +#include "CustomProtocolManagerMessages.h" +#include "DownloadProxy.h" +#include "DownloadProxyMessages.h" +#include "GamepadData.h" +#include "HighPerformanceGraphicsUsageSampler.h" +#include "LogInitialization.h" +#include "NetworkProcessCreationParameters.h" +#include "NetworkProcessMessages.h" +#include "NetworkProcessProxy.h" +#include "PerActivityStateCPUUsageSampler.h" +#include "SandboxExtension.h" +#include "StatisticsData.h" +#include "TextChecker.h" +#include "UIGamepad.h" +#include "UIGamepadProvider.h" +#include "WKContextPrivate.h" +#include "WebAutomationSession.h" +#include "WebCertificateInfo.h" +#include "WebContextSupplement.h" +#include "WebCookieManagerProxy.h" +#include "WebCoreArgumentCoders.h" +#include "WebGeolocationManagerProxy.h" +#include "WebIconDatabase.h" +#include "WebKit2Initialize.h" +#include "WebMemorySampler.h" +#include "WebNotificationManagerProxy.h" +#include "WebPageGroup.h" +#include "WebPreferences.h" +#include "WebPreferencesKeys.h" +#include "WebProcessCreationParameters.h" +#include "WebProcessMessages.h" +#include "WebProcessPoolMessages.h" +#include "WebProcessProxy.h" +#include "WebsiteDataStore.h" +#include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/Language.h> +#include <WebCore/LinkHash.h> +#include <WebCore/LogInitialization.h> +#include <WebCore/ResourceRequest.h> +#include <WebCore/SessionID.h> +#include <WebCore/URLParser.h> +#include <runtime/JSCInlines.h> +#include <wtf/CurrentTime.h> +#include <wtf/MainThread.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/RunLoop.h> +#include <wtf/text/StringBuilder.h> + +#if ENABLE(DATABASE_PROCESS) +#include "DatabaseProcessCreationParameters.h" +#include "DatabaseProcessMessages.h" +#endif + +#if ENABLE(SERVICE_CONTROLS) +#include "ServicesController.h" +#endif + +#if ENABLE(REMOTE_INSPECTOR) +#include <JavaScriptCore/RemoteInspector.h> +#endif + +#if OS(LINUX) +#include "MemoryPressureMonitor.h" +#endif + +#if PLATFORM(WAYLAND) +#include "WaylandCompositor.h" +#include <WebCore/PlatformDisplay.h> +#endif + +#ifndef NDEBUG +#include <wtf/RefCountedLeakCounter.h> +#endif + +using namespace WebCore; +using namespace WebKit; + +namespace WebKit { + +DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, processPoolCounter, ("WebProcessPool")); + +Ref<WebProcessPool> WebProcessPool::create(API::ProcessPoolConfiguration& configuration) +{ + InitializeWebKit2(); + return adoptRef(*new WebProcessPool(configuration)); +} + +static Vector<WebProcessPool*>& processPools() +{ + static NeverDestroyed<Vector<WebProcessPool*>> processPools; + return processPools; +} + +const Vector<WebProcessPool*>& WebProcessPool::allProcessPools() +{ + return processPools(); +} + +static WebsiteDataStore::Configuration legacyWebsiteDataStoreConfiguration(API::ProcessPoolConfiguration& processPoolConfiguration) +{ + WebsiteDataStore::Configuration configuration; + + configuration.localStorageDirectory = processPoolConfiguration.localStorageDirectory(); + configuration.webSQLDatabaseDirectory = processPoolConfiguration.webSQLDatabaseDirectory(); + configuration.applicationCacheDirectory = processPoolConfiguration.applicationCacheDirectory(); + configuration.applicationCacheFlatFileSubdirectoryName = processPoolConfiguration.applicationCacheFlatFileSubdirectoryName(); + configuration.mediaCacheDirectory = processPoolConfiguration.mediaCacheDirectory(); + configuration.mediaKeysStorageDirectory = processPoolConfiguration.mediaKeysStorageDirectory(); + configuration.networkCacheDirectory = processPoolConfiguration.diskCacheDirectory(); + + // This is needed to support legacy WK2 clients, which did not have resource load statistics. + configuration.resourceLoadStatisticsDirectory = API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory(); + + return configuration; +} + +static HashSet<String, ASCIICaseInsensitiveHash>& globalURLSchemesWithCustomProtocolHandlers() +{ + static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> set; + return set; +} + +WebProcessPool::WebProcessPool(API::ProcessPoolConfiguration& configuration) + : m_configuration(configuration.copy()) + , m_haveInitialEmptyProcess(false) + , m_processWithPageCache(0) + , m_defaultPageGroup(WebPageGroup::createNonNull()) + , m_automationClient(std::make_unique<API::AutomationClient>()) + , m_downloadClient(std::make_unique<API::DownloadClient>()) + , m_historyClient(std::make_unique<API::LegacyContextHistoryClient>()) + , m_customProtocolManagerClient(std::make_unique<API::CustomProtocolManagerClient>()) + , m_visitedLinkStore(VisitedLinkStore::create()) + , m_visitedLinksPopulated(false) + , m_plugInAutoStartProvider(this) + , m_alwaysUsesComplexTextCodePath(false) + , m_shouldUseFontSmoothing(true) + , m_memorySamplerEnabled(false) + , m_memorySamplerInterval(1400.0) + , m_websiteDataStore(m_configuration->shouldHaveLegacyDataStore() ? API::WebsiteDataStore::create(legacyWebsiteDataStoreConfiguration(m_configuration)).ptr() : nullptr) +#if PLATFORM(MAC) + , m_highPerformanceGraphicsUsageSampler(std::make_unique<HighPerformanceGraphicsUsageSampler>(*this)) + , m_perActivityStateCPUUsageSampler(std::make_unique<PerActivityStateCPUUsageSampler>(*this)) +#endif + , m_shouldUseTestingNetworkSession(false) + , m_processTerminationEnabled(true) + , m_canHandleHTTPSServerTrustEvaluation(true) + , m_didNetworkProcessCrash(false) + , m_memoryCacheDisabled(false) + , m_alwaysRunsAtBackgroundPriority(m_configuration->alwaysRunsAtBackgroundPriority()) + , m_userObservablePageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); }) + , m_processSuppressionDisabledForPageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); }) + , m_hiddenPageThrottlingAutoIncreasesCounter([this](RefCounterEvent) { m_hiddenPageThrottlingTimer.startOneShot(0); }) + , m_hiddenPageThrottlingTimer(RunLoop::main(), this, &WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit) +{ + for (auto& scheme : m_configuration->alwaysRevalidatedURLSchemes()) + m_schemesToRegisterAsAlwaysRevalidated.add(scheme); + + for (const auto& urlScheme : m_configuration->cachePartitionedURLSchemes()) + m_schemesToRegisterAsCachePartitioned.add(urlScheme); + + platformInitialize(); + + addMessageReceiver(Messages::WebProcessPool::messageReceiverName(), *this); + + // NOTE: These sub-objects must be initialized after m_messageReceiverMap.. + m_iconDatabase = WebIconDatabase::create(this); + + addSupplement<WebCookieManagerProxy>(); + addSupplement<WebGeolocationManagerProxy>(); + addSupplement<WebNotificationManagerProxy>(); +#if ENABLE(MEDIA_SESSION) + addSupplement<WebMediaSessionFocusManager>(); +#endif + + processPools().append(this); + + addLanguageChangeObserver(this, languageChanged); + + resolvePathsForSandboxExtensions(); + +#if !LOG_DISABLED || !RELEASE_LOG_DISABLED + WebCore::initializeLogChannelsIfNecessary(); + WebKit::initializeLogChannelsIfNecessary(); +#endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED + +#ifndef NDEBUG + processPoolCounter.increment(); +#endif +} + +#if !PLATFORM(COCOA) +void WebProcessPool::platformInitialize() +{ +} +#endif + +WebProcessPool::~WebProcessPool() +{ + bool removed = processPools().removeFirst(this); + ASSERT_UNUSED(removed, removed); + + removeLanguageChangeObserver(this); + + m_messageReceiverMap.invalidate(); + + for (auto& supplement : m_supplements.values()) { + supplement->processPoolDestroyed(); + supplement->clearProcessPool(); + } + + m_iconDatabase->invalidate(); + m_iconDatabase->clearProcessPool(); + WebIconDatabase* rawIconDatabase = m_iconDatabase.leakRef(); + rawIconDatabase->derefWhenAppropriate(); + + invalidateCallbackMap(m_dictionaryCallbacks, CallbackBase::Error::OwnerWasInvalidated); + + platformInvalidateContext(); + +#ifndef NDEBUG + processPoolCounter.decrement(); +#endif + + if (m_networkProcess) + m_networkProcess->shutDownProcess(); + +#if ENABLE(GAMEPAD) + if (!m_processesUsingGamepads.isEmpty()) + UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this); +#endif +} + +void WebProcessPool::initializeClient(const WKContextClientBase* client) +{ + m_client.initialize(client); +} + +void WebProcessPool::initializeInjectedBundleClient(const WKContextInjectedBundleClientBase* client) +{ + m_injectedBundleClient.initialize(client); +} + +void WebProcessPool::initializeConnectionClient(const WKContextConnectionClientBase* client) +{ + m_connectionClient.initialize(client); +} + +void WebProcessPool::setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient> historyClient) +{ + if (!historyClient) + m_historyClient = std::make_unique<API::LegacyContextHistoryClient>(); + else + m_historyClient = WTFMove(historyClient); +} + +void WebProcessPool::setDownloadClient(std::unique_ptr<API::DownloadClient> downloadClient) +{ + if (!downloadClient) + m_downloadClient = std::make_unique<API::DownloadClient>(); + else + m_downloadClient = WTFMove(downloadClient); +} + +void WebProcessPool::setAutomationClient(std::unique_ptr<API::AutomationClient> automationClient) +{ + if (!automationClient) + m_automationClient = std::make_unique<API::AutomationClient>(); + else + m_automationClient = WTFMove(automationClient); +} + +void WebProcessPool::setCustomProtocolManagerClient(std::unique_ptr<API::CustomProtocolManagerClient>&& customProtocolManagerClient) +{ + if (!customProtocolManagerClient) + m_customProtocolManagerClient = std::make_unique<API::CustomProtocolManagerClient>(); + else + m_customProtocolManagerClient = WTFMove(customProtocolManagerClient); +} + +void WebProcessPool::setMaximumNumberOfProcesses(unsigned maximumNumberOfProcesses) +{ + // Guard against API misuse. + if (!m_processes.isEmpty()) + CRASH(); + + m_configuration->setMaximumProcessCount(maximumNumberOfProcesses); +} + +IPC::Connection* WebProcessPool::networkingProcessConnection() +{ + return m_networkProcess->connection(); +} + +void WebProcessPool::languageChanged(void* context) +{ + static_cast<WebProcessPool*>(context)->languageChanged(); +} + +void WebProcessPool::languageChanged() +{ + sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(userPreferredLanguages())); +#if USE(SOUP) + if (m_networkProcess) + m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(userPreferredLanguages()), 0); +#endif +} + +void WebProcessPool::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) +{ + sendToAllProcesses(Messages::WebProcess::FullKeyboardAccessModeChanged(fullKeyboardAccessEnabled)); +} + +void WebProcessPool::textCheckerStateChanged() +{ + sendToAllProcesses(Messages::WebProcess::SetTextCheckerState(TextChecker::state())); +} + +NetworkProcessProxy& WebProcessPool::ensureNetworkProcess() +{ + if (m_networkProcess) + return *m_networkProcess; + + m_networkProcess = NetworkProcessProxy::create(*this); + + NetworkProcessCreationParameters parameters; + + parameters.privateBrowsingEnabled = WebPreferences::anyPagesAreUsingPrivateBrowsing(); + + parameters.cacheModel = cacheModel(); + parameters.diskCacheSizeOverride = m_configuration->diskCacheSizeOverride(); + parameters.canHandleHTTPSServerTrustEvaluation = m_canHandleHTTPSServerTrustEvaluation; + + for (auto& scheme : globalURLSchemesWithCustomProtocolHandlers()) + parameters.urlSchemesRegisteredForCustomProtocols.append(scheme); + + for (auto& scheme : m_urlSchemesRegisteredForCustomProtocols) + parameters.urlSchemesRegisteredForCustomProtocols.append(scheme); + + parameters.diskCacheDirectory = m_configuration->diskCacheDirectory(); + if (!parameters.diskCacheDirectory.isEmpty()) + SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle); +#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION) + parameters.shouldEnableNetworkCacheSpeculativeRevalidation = m_configuration->diskCacheSpeculativeValidationEnabled(); +#endif + +#if PLATFORM(IOS) + String cookieStorageDirectory = this->cookieStorageDirectory(); + if (!cookieStorageDirectory.isEmpty()) + SandboxExtension::createHandleForReadWriteDirectory(cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle); + + String containerCachesDirectory = this->networkingCachesDirectory(); + if (!containerCachesDirectory.isEmpty()) + SandboxExtension::createHandleForReadWriteDirectory(containerCachesDirectory, parameters.containerCachesDirectoryExtensionHandle); + + String parentBundleDirectory = this->parentBundleDirectory(); + if (!parentBundleDirectory.isEmpty()) + SandboxExtension::createHandle(parentBundleDirectory, SandboxExtension::ReadOnly, parameters.parentBundleDirectoryExtensionHandle); +#endif + +#if OS(LINUX) + if (MemoryPressureMonitor::isEnabled()) + parameters.memoryPressureMonitorHandle = MemoryPressureMonitor::singleton().createHandle(); +#endif + + parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession; + + // Add any platform specific parameters + platformInitializeNetworkProcess(parameters); + + // Initialize the network process. + m_networkProcess->send(Messages::NetworkProcess::InitializeNetworkProcess(parameters), 0); + +#if PLATFORM(COCOA) + m_networkProcess->send(Messages::NetworkProcess::SetQOS(networkProcessLatencyQOS(), networkProcessThroughputQOS()), 0); +#endif + + if (m_didNetworkProcessCrash) { + m_didNetworkProcessCrash = false; + for (auto& process : m_processes) + process->reinstateNetworkProcessAssertionState(*m_networkProcess); + } + + return *m_networkProcess; +} + +void WebProcessPool::networkProcessCrashed(NetworkProcessProxy* networkProcessProxy) +{ + ASSERT(m_networkProcess); + ASSERT(networkProcessProxy == m_networkProcess.get()); + m_didNetworkProcessCrash = true; + + for (auto& supplement : m_supplements.values()) + supplement->processDidClose(networkProcessProxy); + + m_client.networkProcessDidCrash(this); + + // Leave the process proxy around during client call, so that the client could query the process identifier. + m_networkProcess = nullptr; +} + +void WebProcessPool::getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&& reply) +{ + ensureNetworkProcess(); + ASSERT(m_networkProcess); + + m_networkProcess->getNetworkProcessConnection(WTFMove(reply)); +} + +#if ENABLE(DATABASE_PROCESS) +void WebProcessPool::ensureDatabaseProcess() +{ + if (m_databaseProcess) + return; + + m_databaseProcess = DatabaseProcessProxy::create(this); + + // ********* + // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>) + // ********* + DatabaseProcessCreationParameters parameters; +#if ENABLE(INDEXED_DATABASE) + ASSERT(!m_configuration->indexedDBDatabaseDirectory().isEmpty()); + parameters.indexedDatabaseDirectory = m_configuration->indexedDBDatabaseDirectory(); + + SandboxExtension::createHandleForReadWriteDirectory(parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle); +#endif + + m_databaseProcess->send(Messages::DatabaseProcess::InitializeDatabaseProcess(parameters), 0); +} + +void WebProcessPool::getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&& reply) +{ + ensureDatabaseProcess(); + + m_databaseProcess->getDatabaseProcessConnection(WTFMove(reply)); +} + +void WebProcessPool::databaseProcessCrashed(DatabaseProcessProxy* databaseProcessProxy) +{ + ASSERT(m_databaseProcess); + ASSERT(databaseProcessProxy == m_databaseProcess.get()); + + for (auto& supplement : m_supplements.values()) + supplement->processDidClose(databaseProcessProxy); + + m_client.databaseProcessDidCrash(this); + m_databaseProcess = nullptr; +} +#endif + +void WebProcessPool::willStartUsingPrivateBrowsing() +{ + for (auto* processPool : allProcessPools()) + processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(true); +} + +void WebProcessPool::willStopUsingPrivateBrowsing() +{ + for (auto* processPool : allProcessPools()) + processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(false); +} + +void WebProcessPool::windowServerConnectionStateChanged() +{ + size_t processCount = m_processes.size(); + for (size_t i = 0; i < processCount; ++i) + m_processes[i]->windowServerConnectionStateChanged(); +} + +void WebProcessPool::setAnyPageGroupMightHavePrivateBrowsingEnabled(bool privateBrowsingEnabled) +{ + m_iconDatabase->setPrivateBrowsingEnabled(privateBrowsingEnabled); + + if (networkProcess()) { + if (privateBrowsingEnabled) + networkProcess()->send(Messages::NetworkProcess::EnsurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()), 0); + else + networkProcess()->send(Messages::NetworkProcess::DestroyPrivateBrowsingSession(SessionID::legacyPrivateSessionID()), 0); + } + + if (privateBrowsingEnabled) + sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionID::legacyPrivateSessionID())); + else + sendToAllProcesses(Messages::WebProcess::DestroyPrivateBrowsingSession(SessionID::legacyPrivateSessionID())); +} + +void (*s_invalidMessageCallback)(WKStringRef messageName); + +void WebProcessPool::setInvalidMessageCallback(void (*invalidMessageCallback)(WKStringRef messageName)) +{ + s_invalidMessageCallback = invalidMessageCallback; +} + +void WebProcessPool::didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName) +{ + if (!s_invalidMessageCallback) + return; + + StringBuilder messageNameStringBuilder; + messageNameStringBuilder.append(messageReceiverName.data(), messageReceiverName.size()); + messageNameStringBuilder.append('.'); + messageNameStringBuilder.append(messageName.data(), messageName.size()); + + s_invalidMessageCallback(toAPI(API::String::create(messageNameStringBuilder.toString()).ptr())); +} + +void WebProcessPool::processDidCachePage(WebProcessProxy* process) +{ + if (m_processWithPageCache && m_processWithPageCache != process) + m_processWithPageCache->releasePageCache(); + m_processWithPageCache = process; +} + +void WebProcessPool::resolvePathsForSandboxExtensions() +{ + m_resolvedPaths.injectedBundlePath = resolvePathForSandboxExtension(injectedBundlePath()); + m_resolvedPaths.applicationCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->applicationCacheDirectory()); + m_resolvedPaths.webSQLDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory()); + m_resolvedPaths.mediaCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaCacheDirectory()); + m_resolvedPaths.mediaKeyStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaKeysStorageDirectory()); + + platformResolvePathsForSandboxExtensions(); +} + +WebProcessProxy& WebProcessPool::createNewWebProcess() +{ + ensureNetworkProcess(); + + Ref<WebProcessProxy> process = WebProcessProxy::create(*this); + + WebProcessCreationParameters parameters; + + parameters.injectedBundlePath = m_resolvedPaths.injectedBundlePath; + if (!parameters.injectedBundlePath.isEmpty()) + SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle); + + parameters.applicationCacheDirectory = m_resolvedPaths.applicationCacheDirectory; + if (!parameters.applicationCacheDirectory.isEmpty()) + SandboxExtension::createHandleWithoutResolvingPath(parameters.applicationCacheDirectory, SandboxExtension::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle); + + parameters.applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName(); + + parameters.webSQLDatabaseDirectory = m_resolvedPaths.webSQLDatabaseDirectory; + if (!parameters.webSQLDatabaseDirectory.isEmpty()) + SandboxExtension::createHandleWithoutResolvingPath(parameters.webSQLDatabaseDirectory, SandboxExtension::ReadWrite, parameters.webSQLDatabaseDirectoryExtensionHandle); + + parameters.mediaCacheDirectory = m_resolvedPaths.mediaCacheDirectory; + if (!parameters.mediaCacheDirectory.isEmpty()) + SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaCacheDirectory, SandboxExtension::ReadWrite, parameters.mediaCacheDirectoryExtensionHandle); + + parameters.mediaKeyStorageDirectory = m_resolvedPaths.mediaKeyStorageDirectory; + if (!parameters.mediaKeyStorageDirectory.isEmpty()) + SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaKeyStorageDirectory, SandboxExtension::ReadWrite, parameters.mediaKeyStorageDirectoryExtensionHandle); + + parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession; + + parameters.cacheModel = cacheModel(); + parameters.languages = userPreferredLanguages(); + + copyToVector(m_schemesToRegisterAsEmptyDocument, parameters.urlSchemesRegisteredAsEmptyDocument); + copyToVector(m_schemesToRegisterAsSecure, parameters.urlSchemesRegisteredAsSecure); + copyToVector(m_schemesToRegisterAsBypassingContentSecurityPolicy, parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy); + copyToVector(m_schemesToSetDomainRelaxationForbiddenFor, parameters.urlSchemesForWhichDomainRelaxationIsForbidden); + copyToVector(m_schemesToRegisterAsLocal, parameters.urlSchemesRegisteredAsLocal); + copyToVector(m_schemesToRegisterAsNoAccess, parameters.urlSchemesRegisteredAsNoAccess); + copyToVector(m_schemesToRegisterAsDisplayIsolated, parameters.urlSchemesRegisteredAsDisplayIsolated); + copyToVector(m_schemesToRegisterAsCORSEnabled, parameters.urlSchemesRegisteredAsCORSEnabled); + copyToVector(m_schemesToRegisterAsAlwaysRevalidated, parameters.urlSchemesRegisteredAsAlwaysRevalidated); + copyToVector(m_schemesToRegisterAsCachePartitioned, parameters.urlSchemesRegisteredAsCachePartitioned); + + parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath; + parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing; + + parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty(); + + parameters.terminationTimeout = 0; + + parameters.textCheckerState = TextChecker::state(); + + parameters.fullKeyboardAccessEnabled = WebProcessProxy::fullKeyboardAccessEnabled(); + + parameters.defaultRequestTimeoutInterval = API::URLRequest::defaultTimeoutInterval(); + +#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) + // FIXME: There should be a generic way for supplements to add to the intialization parameters. + supplement<WebNotificationManagerProxy>()->populateCopyOfNotificationPermissions(parameters.notificationPermissions); +#endif + + parameters.plugInAutoStartOriginHashes = m_plugInAutoStartProvider.autoStartOriginHashesCopy(); + copyToVector(m_plugInAutoStartProvider.autoStartOrigins(), parameters.plugInAutoStartOrigins); + + parameters.memoryCacheDisabled = m_memoryCacheDisabled; + +#if ENABLE(SERVICE_CONTROLS) + auto& serviceController = ServicesController::singleton(); + parameters.hasImageServices = serviceController.hasImageServices(); + parameters.hasSelectionServices = serviceController.hasSelectionServices(); + parameters.hasRichContentServices = serviceController.hasRichContentServices(); + serviceController.refreshExistingServices(); +#endif + +#if ENABLE(NETSCAPE_PLUGIN_API) + parameters.pluginLoadClientPolicies = m_pluginLoadClientPolicies; +#endif + +#if OS(LINUX) + parameters.shouldEnableMemoryPressureReliefLogging = true; + if (MemoryPressureMonitor::isEnabled()) + parameters.memoryPressureMonitorHandle = MemoryPressureMonitor::singleton().createHandle(); +#endif + +#if PLATFORM(WAYLAND) && USE(EGL) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland) + parameters.waylandCompositorDisplayName = WaylandCompositor::singleton().displayName(); +#endif + + parameters.resourceLoadStatisticsEnabled = resourceLoadStatisticsEnabled(); + + // Add any platform specific parameters + platformInitializeWebProcess(parameters); + + RefPtr<API::Object> injectedBundleInitializationUserData = m_injectedBundleClient.getInjectedBundleInitializationUserData(this); + if (!injectedBundleInitializationUserData) + injectedBundleInitializationUserData = m_injectedBundleInitializationUserData; + parameters.initializationUserData = UserData(process->transformObjectsToHandles(injectedBundleInitializationUserData.get())); + + process->send(Messages::WebProcess::InitializeWebProcess(parameters), 0); + +#if PLATFORM(COCOA) + process->send(Messages::WebProcess::SetQOS(webProcessLatencyQOS(), webProcessThroughputQOS()), 0); +#endif + + if (WebPreferences::anyPagesAreUsingPrivateBrowsing()) + process->send(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()), 0); + + if (m_automationSession) + process->send(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier()), 0); + + m_processes.append(process.ptr()); + + ASSERT(m_messagesToInjectedBundlePostedToEmptyContext.isEmpty()); + +#if ENABLE(REMOTE_INSPECTOR) + // Initialize remote inspector connection now that we have a sub-process that is hosting one of our web views. + Inspector::RemoteInspector::singleton(); +#endif + + return process; +} + +void WebProcessPool::warmInitialProcess() +{ + if (m_haveInitialEmptyProcess) { + ASSERT(!m_processes.isEmpty()); + return; + } + + if (m_processes.size() >= maximumNumberOfProcesses()) + return; + + createNewWebProcess(); + m_haveInitialEmptyProcess = true; +} + +void WebProcessPool::enableProcessTermination() +{ + m_processTerminationEnabled = true; + Vector<RefPtr<WebProcessProxy>> processes = m_processes; + for (size_t i = 0; i < processes.size(); ++i) { + if (shouldTerminate(processes[i].get())) + processes[i]->terminate(); + } +} + +bool WebProcessPool::shouldTerminate(WebProcessProxy* process) +{ + ASSERT(m_processes.contains(process)); + + if (!m_processTerminationEnabled) + return false; + + return true; +} + +void WebProcessPool::processDidFinishLaunching(WebProcessProxy* process) +{ + ASSERT(m_processes.contains(process)); + + if (!m_visitedLinksPopulated) { + populateVisitedLinks(); + m_visitedLinksPopulated = true; + } + + // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching + // so check if it needs to be started here + if (m_memorySamplerEnabled) { + SandboxExtension::Handle sampleLogSandboxHandle; + double now = WTF::currentTime(); + String sampleLogFilePath = String::format("WebProcess%llupid%d", static_cast<unsigned long long>(now), process->processIdentifier()); + sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle); + + process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0); + } + + if (m_configuration->fullySynchronousModeIsAllowedForTesting()) + process->connection()->allowFullySynchronousModeForTesting(); + + if (m_configuration->ignoreSynchronousMessagingTimeoutsForTesting()) + process->connection()->ignoreTimeoutsForTesting(); + + m_connectionClient.didCreateConnection(this, process->webConnection()); +} + +void WebProcessPool::disconnectProcess(WebProcessProxy* process) +{ + ASSERT(m_processes.contains(process)); + + if (m_haveInitialEmptyProcess && process == m_processes.last()) + m_haveInitialEmptyProcess = false; + + // FIXME (Multi-WebProcess): <rdar://problem/12239765> Some of the invalidation calls of the other supplements are still necessary in multi-process mode, but they should only affect data structures pertaining to the process being disconnected. + // Clearing everything causes assertion failures, so it's less trouble to skip that for now. + RefPtr<WebProcessProxy> protect(process); + if (m_processWithPageCache == process) + m_processWithPageCache = nullptr; + + static_cast<WebContextSupplement*>(supplement<WebGeolocationManagerProxy>())->processDidClose(process); + + m_processes.removeFirst(process); + +#if ENABLE(GAMEPAD) + if (m_processesUsingGamepads.contains(process)) + processStoppedUsingGamepads(*process); +#endif +} + +WebProcessProxy& WebProcessPool::createNewWebProcessRespectingProcessCountLimit() +{ + if (m_processes.size() < maximumNumberOfProcesses()) + return createNewWebProcess(); + + // Choose the process with fewest pages. + auto& process = *std::min_element(m_processes.begin(), m_processes.end(), [](const RefPtr<WebProcessProxy>& a, const RefPtr<WebProcessProxy>& b) { + return a->pageCount() < b->pageCount(); + }); + + return *process; +} + +Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API::PageConfiguration>&& pageConfiguration) +{ + if (!pageConfiguration->pageGroup()) + pageConfiguration->setPageGroup(m_defaultPageGroup.ptr()); + if (!pageConfiguration->preferences()) + pageConfiguration->setPreferences(&pageConfiguration->pageGroup()->preferences()); + if (!pageConfiguration->userContentController()) + pageConfiguration->setUserContentController(&pageConfiguration->pageGroup()->userContentController()); + if (!pageConfiguration->visitedLinkStore()) + pageConfiguration->setVisitedLinkStore(m_visitedLinkStore.ptr()); + if (!pageConfiguration->websiteDataStore()) { + ASSERT(!pageConfiguration->sessionID().isValid()); + pageConfiguration->setWebsiteDataStore(m_websiteDataStore.get()); + pageConfiguration->setSessionID(pageConfiguration->preferences()->privateBrowsingEnabled() ? SessionID::legacyPrivateSessionID() : SessionID::defaultSessionID()); + } + + RefPtr<WebProcessProxy> process; + if (m_haveInitialEmptyProcess) { + process = m_processes.last(); + m_haveInitialEmptyProcess = false; + } else if (pageConfiguration->relatedPage()) { + // Sharing processes, e.g. when creating the page via window.open(). + process = &pageConfiguration->relatedPage()->process(); + } else + process = &createNewWebProcessRespectingProcessCountLimit(); + + return process->createWebPage(pageClient, WTFMove(pageConfiguration)); +} + +DownloadProxy* WebProcessPool::download(WebPageProxy* initiatingPage, const ResourceRequest& request, const String& suggestedFilename) +{ + DownloadProxy* downloadProxy = createDownloadProxy(request); + SessionID sessionID = initiatingPage ? initiatingPage->sessionID() : SessionID::defaultSessionID(); + + if (initiatingPage) + initiatingPage->handleDownloadRequest(downloadProxy); + + if (networkProcess()) { + ResourceRequest updatedRequest(request); + // Request's firstPartyForCookies will be used as Original URL of the download request. + // We set the value to top level document's URL. + if (initiatingPage) + updatedRequest.setFirstPartyForCookies(URL(URL(), initiatingPage->pageLoadState().url())); + else + updatedRequest.setFirstPartyForCookies(URL()); + networkProcess()->send(Messages::NetworkProcess::DownloadRequest(sessionID, downloadProxy->downloadID(), updatedRequest, suggestedFilename), 0); + return downloadProxy; + } + + return downloadProxy; +} + +DownloadProxy* WebProcessPool::resumeDownload(const API::Data* resumeData, const String& path) +{ + DownloadProxy* downloadProxy = createDownloadProxy(ResourceRequest()); + + SandboxExtension::Handle sandboxExtensionHandle; + if (!path.isEmpty()) + SandboxExtension::createHandle(path, SandboxExtension::ReadWrite, sandboxExtensionHandle); + + if (networkProcess()) { + // FIXME: If we started a download in an ephemeral session and that session still exists, we should find a way to use that same session. + networkProcess()->send(Messages::NetworkProcess::ResumeDownload(SessionID::defaultSessionID(), downloadProxy->downloadID(), resumeData->dataReference(), path, sandboxExtensionHandle), 0); + return downloadProxy; + } + + return downloadProxy; +} + +void WebProcessPool::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody) +{ + for (auto& process : m_processes) { + // FIXME: Return early if the message body contains any references to WKPageRefs/WKFrameRefs etc. since they're local to a process. + process->send(Messages::WebProcess::HandleInjectedBundleMessage(messageName, UserData(process->transformObjectsToHandles(messageBody).get())), 0); + } +} + +void WebProcessPool::populateVisitedLinks() +{ + m_historyClient->populateVisitedLinks(*this); +} + +WebProcessPool::Statistics& WebProcessPool::statistics() +{ + static Statistics statistics = Statistics(); + + return statistics; +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +void WebProcessPool::setAdditionalPluginsDirectory(const String& directory) +{ + Vector<String> directories; + directories.append(directory); + + m_pluginInfoStore.setAdditionalPluginsDirectories(directories); +} + +void WebProcessPool::refreshPlugins() +{ + m_pluginInfoStore.refresh(); + sendToAllProcesses(Messages::WebProcess::RefreshPlugins()); +} + +#endif // ENABLE(NETSCAPE_PLUGIN_API) + +pid_t WebProcessPool::networkProcessIdentifier() +{ + if (!m_networkProcess) + return 0; + + return m_networkProcess->processIdentifier(); +} + +pid_t WebProcessPool::databaseProcessIdentifier() +{ +#if ENABLE(DATABASE_PROCESS) + if (!m_databaseProcess) + return 0; + + return m_databaseProcess->processIdentifier(); +#else + return 0; +#endif +} + +void WebProcessPool::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) +{ + m_alwaysUsesComplexTextCodePath = alwaysUseComplexText; + sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText)); +} + +void WebProcessPool::setShouldUseFontSmoothing(bool useFontSmoothing) +{ + m_shouldUseFontSmoothing = useFontSmoothing; + sendToAllProcesses(Messages::WebProcess::SetShouldUseFontSmoothing(useFontSmoothing)); +} + +void WebProcessPool::registerURLSchemeAsEmptyDocument(const String& urlScheme) +{ + m_schemesToRegisterAsEmptyDocument.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme)); +} + +void WebProcessPool::registerURLSchemeAsSecure(const String& urlScheme) +{ + m_schemesToRegisterAsSecure.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme)); +} + +void WebProcessPool::registerURLSchemeAsBypassingContentSecurityPolicy(const String& urlScheme) +{ + m_schemesToRegisterAsBypassingContentSecurityPolicy.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsBypassingContentSecurityPolicy(urlScheme)); +} + +void WebProcessPool::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) +{ + m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme)); +} + +void WebProcessPool::setCanHandleHTTPSServerTrustEvaluation(bool value) +{ + m_canHandleHTTPSServerTrustEvaluation = value; + if (m_networkProcess) { + m_networkProcess->send(Messages::NetworkProcess::SetCanHandleHTTPSServerTrustEvaluation(value), 0); + return; + } +} + +void WebProcessPool::registerURLSchemeAsLocal(const String& urlScheme) +{ + m_schemesToRegisterAsLocal.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsLocal(urlScheme)); +} + +void WebProcessPool::registerURLSchemeAsNoAccess(const String& urlScheme) +{ + m_schemesToRegisterAsNoAccess.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsNoAccess(urlScheme)); +} + +void WebProcessPool::registerURLSchemeAsDisplayIsolated(const String& urlScheme) +{ + m_schemesToRegisterAsDisplayIsolated.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsDisplayIsolated(urlScheme)); +} + +void WebProcessPool::registerURLSchemeAsCORSEnabled(const String& urlScheme) +{ + m_schemesToRegisterAsCORSEnabled.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCORSEnabled(urlScheme)); +} + +void WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme) +{ + if (!urlScheme) + return; + + globalURLSchemesWithCustomProtocolHandlers().add(urlScheme); + for (auto* processPool : allProcessPools()) + processPool->registerSchemeForCustomProtocol(urlScheme); +} + +void WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme) +{ + if (!urlScheme) + return; + + globalURLSchemesWithCustomProtocolHandlers().remove(urlScheme); + for (auto* processPool : allProcessPools()) + processPool->unregisterSchemeForCustomProtocol(urlScheme); +} + +void WebProcessPool::registerURLSchemeAsCachePartitioned(const String& urlScheme) +{ + m_schemesToRegisterAsCachePartitioned.add(urlScheme); + sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCachePartitioned(urlScheme)); +} + +void WebProcessPool::setCacheModel(CacheModel cacheModel) +{ + m_configuration->setCacheModel(cacheModel); + sendToAllProcesses(Messages::WebProcess::SetCacheModel(cacheModel)); + + if (m_networkProcess) + m_networkProcess->send(Messages::NetworkProcess::SetCacheModel(cacheModel), 0); +} + +void WebProcessPool::setDefaultRequestTimeoutInterval(double timeoutInterval) +{ + sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval)); +} + +DownloadProxy* WebProcessPool::createDownloadProxy(const ResourceRequest& request) +{ + return ensureNetworkProcess().createDownloadProxy(request); +} + +void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver& messageReceiver) +{ + m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver); +} + +void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver& messageReceiver) +{ + m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver); +} + +void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName) +{ + m_messageReceiverMap.removeMessageReceiver(messageReceiverName); +} + +void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID) +{ + m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID); +} + +bool WebProcessPool::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder) +{ + return m_messageReceiverMap.dispatchMessage(connection, decoder); +} + +bool WebProcessPool::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) +{ + return m_messageReceiverMap.dispatchSyncMessage(connection, decoder, replyEncoder); +} + +void WebProcessPool::setEnhancedAccessibility(bool flag) +{ + sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag)); +} + +void WebProcessPool::startMemorySampler(const double interval) +{ + // For new WebProcesses we will also want to start the Memory Sampler + m_memorySamplerEnabled = true; + m_memorySamplerInterval = interval; + + // For UIProcess +#if ENABLE(MEMORY_SAMPLER) + WebMemorySampler::singleton()->start(interval); +#endif + + // For WebProcess + SandboxExtension::Handle sampleLogSandboxHandle; + double now = WTF::currentTime(); + String sampleLogFilePath = String::format("WebProcess%llu", static_cast<unsigned long long>(now)); + sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle); + + sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval)); +} + +void WebProcessPool::stopMemorySampler() +{ + // For WebProcess + m_memorySamplerEnabled = false; + + // For UIProcess +#if ENABLE(MEMORY_SAMPLER) + WebMemorySampler::singleton()->stop(); +#endif + + sendToAllProcesses(Messages::WebProcess::StopMemorySampler()); +} + +void WebProcessPool::setIconDatabasePath(const String& path) +{ + m_overrideIconDatabasePath = path; + if (!m_overrideIconDatabasePath.isEmpty()) { + // This implicitly enables the database on UI process side. + m_iconDatabase->setDatabasePath(path); + } +} + +String WebProcessPool::iconDatabasePath() const +{ + if (!m_overrideIconDatabasePath.isNull()) + return m_overrideIconDatabasePath; + + return platformDefaultIconDatabasePath(); +} + +void WebProcessPool::useTestingNetworkSession() +{ + ASSERT(m_processes.isEmpty()); + ASSERT(!m_networkProcess); + + if (m_networkProcess) + return; + + if (!m_processes.isEmpty()) + return; + + m_shouldUseTestingNetworkSession = true; +} + +void WebProcessPool::clearCachedCredentials() +{ + sendToAllProcesses(Messages::WebProcess::ClearCachedCredentials()); + if (m_networkProcess) + m_networkProcess->send(Messages::NetworkProcess::ClearCachedCredentials(), 0); +} + +void WebProcessPool::terminateDatabaseProcess() +{ +#if ENABLE(DATABASE_PROCESS) + if (!m_databaseProcess) + return; + + m_databaseProcess->terminate(); + m_databaseProcess = nullptr; +#endif +} + +void WebProcessPool::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host) +{ + ensureNetworkProcess(); + m_networkProcess->send(Messages::NetworkProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0); +} + +void WebProcessPool::updateAutomationCapabilities() const +{ +#if ENABLE(REMOTE_INSPECTOR) + Inspector::RemoteInspector::singleton().clientCapabilitiesDidChange(); +#endif +} + +void WebProcessPool::setAutomationSession(RefPtr<WebAutomationSession>&& automationSession) +{ + m_automationSession = WTFMove(automationSession); + +#if ENABLE(REMOTE_INSPECTOR) + if (m_automationSession) { + m_automationSession->init(); + m_automationSession->setProcessPool(this); + + sendToAllProcesses(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier())); + } else + sendToAllProcesses(Messages::WebProcess::DestroyAutomationSessionProxy()); +#endif +} + +void WebProcessPool::setHTTPPipeliningEnabled(bool enabled) +{ +#if PLATFORM(COCOA) + ResourceRequest::setHTTPPipeliningEnabled(enabled); +#else + UNUSED_PARAM(enabled); +#endif +} + +bool WebProcessPool::httpPipeliningEnabled() const +{ +#if PLATFORM(COCOA) + return ResourceRequest::httpPipeliningEnabled(); +#else + return false; +#endif +} + +void WebProcessPool::getStatistics(uint32_t statisticsMask, std::function<void (API::Dictionary*, CallbackBase::Error)> callbackFunction) +{ + if (!statisticsMask) { + callbackFunction(nullptr, CallbackBase::Error::Unknown); + return; + } + + RefPtr<StatisticsRequest> request = StatisticsRequest::create(DictionaryCallback::create(WTFMove(callbackFunction))); + + if (statisticsMask & StatisticsRequestTypeWebContent) + requestWebContentStatistics(request.get()); + + if (statisticsMask & StatisticsRequestTypeNetworking) + requestNetworkingStatistics(request.get()); +} + +void WebProcessPool::requestWebContentStatistics(StatisticsRequest* request) +{ + // FIXME (Multi-WebProcess) <rdar://problem/13200059>: Make getting statistics from multiple WebProcesses work. +} + +void WebProcessPool::requestNetworkingStatistics(StatisticsRequest* request) +{ + if (!m_networkProcess) { + LOG_ERROR("Attempt to get NetworkProcess statistics but the NetworkProcess is unavailable"); + return; + } + + uint64_t requestID = request->addOutstandingRequest(); + m_statisticsRequests.set(requestID, request); + m_networkProcess->send(Messages::NetworkProcess::GetNetworkProcessStatistics(requestID), 0); +} + +static WebProcessProxy* webProcessProxyFromConnection(IPC::Connection& connection, const Vector<RefPtr<WebProcessProxy>>& processes) +{ + for (auto& process : processes) { + if (process->hasConnection(connection)) + return process.get(); + } + + ASSERT_NOT_REACHED(); + return nullptr; +} + +void WebProcessPool::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody) +{ + auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes); + if (!webProcessProxy) + return; + m_injectedBundleClient.didReceiveMessageFromInjectedBundle(this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get()); +} + +void WebProcessPool::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData) +{ + auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes); + if (!webProcessProxy) + return; + + RefPtr<API::Object> returnData; + m_injectedBundleClient.didReceiveSynchronousMessageFromInjectedBundle(this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get(), returnData); + returnUserData = UserData(webProcessProxy->transformObjectsToHandles(returnData.get())); +} + +void WebProcessPool::didGetStatistics(const StatisticsData& statisticsData, uint64_t requestID) +{ + RefPtr<StatisticsRequest> request = m_statisticsRequests.take(requestID); + if (!request) { + LOG_ERROR("Cannot report networking statistics."); + return; + } + + request->completedRequest(requestID, statisticsData); +} + +#if ENABLE(GAMEPAD) + +void WebProcessPool::startedUsingGamepads(IPC::Connection& connection) +{ + auto* proxy = webProcessProxyFromConnection(connection, m_processes); + if (!proxy) + return; + + bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty(); + + ASSERT(!m_processesUsingGamepads.contains(proxy)); + m_processesUsingGamepads.add(proxy); + + if (!wereAnyProcessesUsingGamepads) + UIGamepadProvider::singleton().processPoolStartedUsingGamepads(*this); + + proxy->send(Messages::WebProcess::SetInitialGamepads(UIGamepadProvider::singleton().snapshotGamepads()), 0); +} + +void WebProcessPool::stoppedUsingGamepads(IPC::Connection& connection) +{ + auto* proxy = webProcessProxyFromConnection(connection, m_processes); + if (!proxy) + return; + + ASSERT(m_processesUsingGamepads.contains(proxy)); + processStoppedUsingGamepads(*proxy); +} + +void WebProcessPool::processStoppedUsingGamepads(WebProcessProxy& process) +{ + bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty(); + + ASSERT(m_processesUsingGamepads.contains(&process)); + m_processesUsingGamepads.remove(&process); + + if (wereAnyProcessesUsingGamepads && m_processesUsingGamepads.isEmpty()) + UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this); +} + +void WebProcessPool::gamepadConnected(const UIGamepad& gamepad) +{ + for (auto& process : m_processesUsingGamepads) + process->send(Messages::WebProcess::GamepadConnected(gamepad.fullGamepadData()), 0); +} + +void WebProcessPool::gamepadDisconnected(const UIGamepad& gamepad) +{ + for (auto& process : m_processesUsingGamepads) + process->send(Messages::WebProcess::GamepadDisconnected(gamepad.index()), 0); +} + +void WebProcessPool::setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>& gamepads) +{ + Vector<GamepadData> gamepadDatas; + gamepadDatas.resize(gamepads.size()); + for (size_t i = 0; i < gamepads.size(); ++i) { + if (!gamepads[i]) + continue; + gamepadDatas[i] = gamepads[i]->fullGamepadData(); + } + + for (auto& process : m_processesUsingGamepads) + process->send(Messages::WebProcess::SetInitialGamepads(gamepadDatas), 0); +} + +#endif // ENABLE(GAMEPAD) + +void WebProcessPool::garbageCollectJavaScriptObjects() +{ + sendToAllProcesses(Messages::WebProcess::GarbageCollectJavaScriptObjects()); +} + +void WebProcessPool::setJavaScriptGarbageCollectorTimerEnabled(bool flag) +{ + sendToAllProcesses(Messages::WebProcess::SetJavaScriptGarbageCollectorTimerEnabled(flag)); +} + +void WebProcessPool::addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, SessionID sessionID) +{ + m_plugInAutoStartProvider.addAutoStartOriginHash(pageOrigin, plugInOriginHash, sessionID); +} + +void WebProcessPool::plugInDidReceiveUserInteraction(unsigned plugInOriginHash, SessionID sessionID) +{ + m_plugInAutoStartProvider.didReceiveUserInteraction(plugInOriginHash, sessionID); +} + +PassRefPtr<API::Dictionary> WebProcessPool::plugInAutoStartOriginHashes() const +{ + return m_plugInAutoStartProvider.autoStartOriginsTableCopy(); +} + +void WebProcessPool::setPlugInAutoStartOriginHashes(API::Dictionary& dictionary) +{ + m_plugInAutoStartProvider.setAutoStartOriginsTable(dictionary); +} + +void WebProcessPool::setPlugInAutoStartOrigins(API::Array& array) +{ + m_plugInAutoStartProvider.setAutoStartOriginsArray(array); +} + +void WebProcessPool::setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& dictionary, double time) +{ + m_plugInAutoStartProvider.setAutoStartOriginsFilteringOutEntriesAddedAfterTime(dictionary, time); +} + +void WebProcessPool::registerSchemeForCustomProtocol(const String& scheme) +{ + if (!globalURLSchemesWithCustomProtocolHandlers().contains(scheme)) + m_urlSchemesRegisteredForCustomProtocols.add(scheme); + sendToNetworkingProcess(Messages::CustomProtocolManager::RegisterScheme(scheme)); +} + +void WebProcessPool::unregisterSchemeForCustomProtocol(const String& scheme) +{ + m_urlSchemesRegisteredForCustomProtocols.remove(scheme); + sendToNetworkingProcess(Messages::CustomProtocolManager::UnregisterScheme(scheme)); +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +void WebProcessPool::setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy policy, const String& host, const String& bundleIdentifier, const String& versionString) +{ + HashMap<String, HashMap<String, uint8_t>> policiesByIdentifier; + if (m_pluginLoadClientPolicies.contains(host)) + policiesByIdentifier = m_pluginLoadClientPolicies.get(host); + + HashMap<String, uint8_t> versionsToPolicies; + if (policiesByIdentifier.contains(bundleIdentifier)) + versionsToPolicies = policiesByIdentifier.get(bundleIdentifier); + + versionsToPolicies.set(versionString, policy); + policiesByIdentifier.set(bundleIdentifier, versionsToPolicies); + m_pluginLoadClientPolicies.set(host, policiesByIdentifier); + + sendToAllProcesses(Messages::WebProcess::SetPluginLoadClientPolicy(policy, host, bundleIdentifier, versionString)); +} + +void WebProcessPool::clearPluginClientPolicies() +{ + m_pluginLoadClientPolicies.clear(); + sendToAllProcesses(Messages::WebProcess::ClearPluginClientPolicies()); +} +#endif + +void WebProcessPool::setMemoryCacheDisabled(bool disabled) +{ + m_memoryCacheDisabled = disabled; + sendToAllProcesses(Messages::WebProcess::SetMemoryCacheDisabled(disabled)); +} + +void WebProcessPool::setFontWhitelist(API::Array* array) +{ + m_fontWhitelist.clear(); + if (array) { + for (size_t i = 0; i < array->size(); ++i) { + if (API::String* font = array->at<API::String>(i)) + m_fontWhitelist.append(font->string()); + } + } +} + +void WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit() +{ + // We're estimating an upper bound for a set of background timer fires for a page to be 200ms + // (including all timer fires, all paging-in, and any resulting GC). To ensure this does not + // result in more than 1% CPU load allow for one timer fire per 100x this duration. + static int maximumTimerThrottlePerPageInMS = 200 * 100; + + int limitInMilliseconds = maximumTimerThrottlePerPageInMS * m_hiddenPageThrottlingAutoIncreasesCounter.value(); + sendToAllProcesses(Messages::WebProcess::SetHiddenPageTimerThrottlingIncreaseLimit(limitInMilliseconds)); +} + +void WebProcessPool::reportWebContentCPUTime(int64_t cpuTime, uint64_t activityState) +{ +#if PLATFORM(MAC) + if (m_perActivityStateCPUUsageSampler) + m_perActivityStateCPUUsageSampler->reportWebContentCPUTime(cpuTime, static_cast<WebCore::ActivityStateForCPUSampling>(activityState)); +#else + UNUSED_PARAM(cpuTime); + UNUSED_PARAM(activityState); +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebContext.h b/Source/WebKit2/UIProcess/WebProcessPool.h index 14bb90ab3..a9f656ab8 100644 --- a/Source/WebKit2/UIProcess/WebContext.h +++ b/Source/WebKit2/UIProcess/WebProcessPool.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2010-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,32 +23,33 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebContext_h -#define WebContext_h +#pragma once +#include "APIDictionary.h" #include "APIObject.h" +#include "APIProcessPoolConfiguration.h" +#include "APIWebsiteDataStore.h" #include "DownloadProxyMap.h" #include "GenericCallback.h" -#include "ImmutableDictionary.h" #include "MessageReceiver.h" #include "MessageReceiverMap.h" +#include "NetworkProcessProxy.h" #include "PlugInAutoStartProvider.h" #include "PluginInfoStore.h" -#include "ProcessModel.h" +#include "ProcessThrottler.h" #include "StatisticsRequest.h" -#include "StorageManager.h" -#include "VisitedLinkProvider.h" +#include "VisitedLinkStore.h" #include "WebContextClient.h" #include "WebContextConnectionClient.h" #include "WebContextInjectedBundleClient.h" -#include "WebDownloadClient.h" -#include "WebHistoryClient.h" #include "WebProcessProxy.h" #include <WebCore/LinkHash.h> +#include <WebCore/SessionID.h> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/PassRefPtr.h> +#include <wtf/RefCounter.h> #include <wtf/RefPtr.h> #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> @@ -57,54 +58,63 @@ #include "DatabaseProcessProxy.h" #endif -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessProxy.h" +#if ENABLE(MEDIA_SESSION) +#include "WebMediaSessionFocusManager.h" #endif -#if PLATFORM(MAC) +#if USE(SOUP) +#include <WebCore/SoupNetworkProxySettings.h> +#endif + +#if PLATFORM(COCOA) +OBJC_CLASS NSMutableDictionary; OBJC_CLASS NSObject; OBJC_CLASS NSString; #endif +namespace API { +class AutomationClient; +class CustomProtocolManagerClient; +class DownloadClient; +class LegacyContextHistoryClient; +class PageConfiguration; +} + namespace WebKit { class DownloadProxy; +class HighPerformanceGraphicsUsageSampler; +class UIGamepad; +class PerActivityStateCPUUsageSampler; +class WebAutomationSession; class WebContextSupplement; class WebIconDatabase; class WebPageGroup; class WebPageProxy; +struct NetworkProcessCreationParameters; struct StatisticsData; -struct WebPageConfiguration; struct WebProcessCreationParameters; -typedef GenericCallback<WKDictionaryRef> DictionaryCallback; - -#if ENABLE(NETWORK_INFO) -class WebNetworkInfoManagerProxy; -#endif -#if ENABLE(NETWORK_PROCESS) -struct NetworkProcessCreationParameters; -#endif +typedef GenericCallback<API::Dictionary*> DictionaryCallback; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) int networkProcessLatencyQOS(); int networkProcessThroughputQOS(); int webProcessLatencyQOS(); int webProcessThroughputQOS(); #endif -class WebContext : public API::ObjectImpl<API::Object::Type::Context>, private IPC::MessageReceiver -#if ENABLE(NETSCAPE_PLUGIN_API) - , private PluginInfoStoreClient -#endif +class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, private IPC::MessageReceiver { public: - WebContext(const String& injectedBundlePath); + static Ref<WebProcessPool> create(API::ProcessPoolConfiguration&); - static PassRefPtr<WebContext> create(const String& injectedBundlePath); - virtual ~WebContext(); + explicit WebProcessPool(API::ProcessPoolConfiguration&); + virtual ~WebProcessPool(); - static const Vector<WebContext*>& allContexts(); + API::ProcessPoolConfiguration& configuration() { return m_configuration.get(); } + + static const Vector<WebProcessPool*>& allProcessPools(); template <typename T> T* supplement() @@ -120,22 +130,24 @@ public: void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&); void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&); + void removeMessageReceiver(IPC::StringReference messageReceiverName); void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID); - bool dispatchMessage(IPC::Connection*, IPC::MessageDecoder&); - bool dispatchSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + bool dispatchMessage(IPC::Connection&, IPC::Decoder&); + bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); void initializeClient(const WKContextClientBase*); void initializeInjectedBundleClient(const WKContextInjectedBundleClientBase*); void initializeConnectionClient(const WKContextConnectionClientBase*); - void initializeHistoryClient(const WKContextHistoryClientBase*); - void initializeDownloadClient(const WKContextDownloadClientBase*); - - void setProcessModel(ProcessModel); // Can only be called when there are no processes running. - ProcessModel processModel() const { return m_processModel; } + void setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient>); + void setDownloadClient(std::unique_ptr<API::DownloadClient>); + void setAutomationClient(std::unique_ptr<API::AutomationClient>); + void setCustomProtocolManagerClient(std::unique_ptr<API::CustomProtocolManagerClient>&&); void setMaximumNumberOfProcesses(unsigned); // Can only be called when there are no processes running. - unsigned maximumNumberOfProcesses() const { return m_webProcessCountLimit; } + unsigned maximumNumberOfProcesses() const { return !m_configuration->maximumProcessCount() ? UINT_MAX : m_configuration->maximumProcessCount(); } + + const Vector<RefPtr<WebProcessProxy>>& processes() const { return m_processes; } // WebProcess or NetworkProcess as approporiate for current process model. The connection must be non-null. IPC::Connection* networkingProcessConnection(); @@ -148,57 +160,60 @@ public: template<typename T> void sendToNetworkingProcess(T&& message); template<typename T> void sendToNetworkingProcessRelaunchingIfNecessary(T&& message); - void processWillOpenConnection(WebProcessProxy*); - void processWillCloseConnection(WebProcessProxy*); + // Sends the message to WebProcess or DatabaseProcess as approporiate for current process model. + template<typename T> void sendToDatabaseProcessRelaunchingIfNecessary(T&& message); + void processDidFinishLaunching(WebProcessProxy*); // Disconnect the process from the context. void disconnectProcess(WebProcessProxy*); - StorageManager& storageManager() const { return *m_storageManager; } + API::WebsiteDataStore* websiteDataStore() const { return m_websiteDataStore.get(); } - PassRefPtr<WebPageProxy> createWebPage(PageClient&, WebPageConfiguration); + Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&); - const String& injectedBundlePath() const { return m_injectedBundlePath; } + const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); } - DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&); + DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&, const String& suggestedFilename = { }); + DownloadProxy* resumeDownload(const API::Data* resumeData, const String& path); void setInjectedBundleInitializationUserData(PassRefPtr<API::Object> userData) { m_injectedBundleInitializationUserData = userData; } void postMessageToInjectedBundle(const String&, API::Object*); - // InjectedBundle client - void didReceiveMessageFromInjectedBundle(const String&, API::Object*); - void didReceiveSynchronousMessageFromInjectedBundle(const String&, API::Object*, RefPtr<API::Object>& returnData); - void populateVisitedLinks(); #if ENABLE(NETSCAPE_PLUGIN_API) void setAdditionalPluginsDirectory(const String&); + void refreshPlugins(); PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; } + + void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString); + void clearPluginClientPolicies(); #endif + pid_t networkProcessIdentifier(); + pid_t databaseProcessIdentifier(); + void setAlwaysUsesComplexTextCodePath(bool); void setShouldUseFontSmoothing(bool); void registerURLSchemeAsEmptyDocument(const String&); void registerURLSchemeAsSecure(const String&); + void registerURLSchemeAsBypassingContentSecurityPolicy(const String&); void setDomainRelaxationForbiddenForURLScheme(const String&); + void setCanHandleHTTPSServerTrustEvaluation(bool); void registerURLSchemeAsLocal(const String&); void registerURLSchemeAsNoAccess(const String&); void registerURLSchemeAsDisplayIsolated(const String&); void registerURLSchemeAsCORSEnabled(const String&); + void registerURLSchemeAsCachePartitioned(const String&); - void addVisitedLink(const String&); - void addVisitedLinkHash(WebCore::LinkHash); - - // MessageReceiver. - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + VisitedLinkStore& visitedLinkStore() { return m_visitedLinkStore.get(); } void setCacheModel(CacheModel); - CacheModel cacheModel() const { return m_cacheModel; } + CacheModel cacheModel() const { return m_configuration->cacheModel(); } void setDefaultRequestTimeoutInterval(double); @@ -207,20 +222,20 @@ public: #if USE(SOUP) void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; } + void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&); #endif void setEnhancedAccessibility(bool); // Downloads. - DownloadProxy* createDownloadProxy(); - WebDownloadClient& downloadClient() { return m_downloadClient; } + DownloadProxy* createDownloadProxy(const WebCore::ResourceRequest&); + API::DownloadClient& downloadClient() { return *m_downloadClient; } - WebHistoryClient& historyClient() { return m_historyClient; } + API::LegacyContextHistoryClient& historyClient() { return *m_historyClient; } WebContextClient& client() { return m_client; } + API::CustomProtocolManagerClient& customProtocolManagerClient() const { return *m_customProtocolManagerClient; } + WebIconDatabase* iconDatabase() const { return m_iconDatabase.get(); } -#if ENABLE(NETSCAPE_PLUGIN_API) - WebPluginSiteDataManager* pluginSiteDataManager() const { return m_pluginSiteDataManager.get(); } -#endif struct Statistics { unsigned wkViewCount; @@ -229,19 +244,20 @@ public: }; static Statistics& statistics(); - void setApplicationCacheDirectory(const String& dir) { m_overrideApplicationCacheDirectory = dir; } - void setDatabaseDirectory(const String& dir) { m_overrideDatabaseDirectory = dir; } void setIconDatabasePath(const String&); String iconDatabasePath() const; - void setLocalStorageDirectory(const String&); - void setDiskCacheDirectory(const String& dir) { m_overrideDiskCacheDirectory = dir; } void setCookieStorageDirectory(const String& dir) { m_overrideCookieStorageDirectory = dir; } void useTestingNetworkSession(); + bool isUsingTestingNetworkSession() const { return m_shouldUseTestingNetworkSession; } + + void clearCachedCredentials(); + void terminateDatabaseProcess(); + + void reportWebContentCPUTime(int64_t cpuTime, uint64_t activityState); void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host); - WebProcessProxy& ensureSharedWebProcess(); WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met. void warmInitialProcess(); @@ -250,16 +266,20 @@ public: void disableProcessTermination() { m_processTerminationEnabled = false; } void enableProcessTermination(); + void updateAutomationCapabilities() const; + void setAutomationSession(RefPtr<WebAutomationSession>&&); + WebAutomationSession* automationSession() const { return m_automationSession.get(); } + // Defaults to false. void setHTTPPipeliningEnabled(bool); bool httpPipeliningEnabled() const; - void getStatistics(uint32_t statisticsMask, PassRefPtr<DictionaryCallback>); + void getStatistics(uint32_t statisticsMask, std::function<void (API::Dictionary*, CallbackBase::Error)>); void garbageCollectJavaScriptObjects(); void setJavaScriptGarbageCollectorTimerEnabled(bool flag); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) static bool omitPDFSupport(); #endif @@ -267,32 +287,27 @@ public: void textCheckerStateChanged(); - PassRefPtr<ImmutableDictionary> plugInAutoStartOriginHashes() const; - void setPlugInAutoStartOriginHashes(ImmutableDictionary&); + PassRefPtr<API::Dictionary> plugInAutoStartOriginHashes() const; + void setPlugInAutoStartOriginHashes(API::Dictionary&); void setPlugInAutoStartOrigins(API::Array&); - void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(ImmutableDictionary&, double time); + void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, double time); // Network Process Management - - void setUsesNetworkProcess(bool); - bool usesNetworkProcess() const; - -#if ENABLE(NETWORK_PROCESS) - void ensureNetworkProcess(); + NetworkProcessProxy& ensureNetworkProcess(); NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); } void networkProcessCrashed(NetworkProcessProxy*); - void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>); -#endif + void getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&&); #if ENABLE(DATABASE_PROCESS) void ensureDatabaseProcess(); - void getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>); + DatabaseProcessProxy* databaseProcess() { return m_databaseProcess.get(); } + void getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&&); + void databaseProcessCrashed(DatabaseProcessProxy*); #endif -#if PLATFORM(MAC) +#if PLATFORM(COCOA) bool processSuppressionEnabled() const; - static bool processSuppressionIsEnabledForAllContexts(); #endif void windowServerConnectionStateChanged(); @@ -300,8 +315,6 @@ public: static void willStartUsingPrivateBrowsing(); static void willStopUsingPrivateBrowsing(); - static bool isEphemeralSession(uint64_t sessionID); - #if USE(SOUP) void setIgnoreTLSErrors(bool); bool ignoreTLSErrors() const { return m_ignoreTLSErrors; } @@ -314,21 +327,69 @@ public: bool isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const; void resetHSTSHosts(); + void resetHSTSHostsAddedAfterDate(double startDateIntervalSince1970); -#if ENABLE(CUSTOM_PROTOCOLS) void registerSchemeForCustomProtocol(const String&); void unregisterSchemeForCustomProtocol(const String&); - static HashSet<String>& globalURLSchemesWithCustomProtocolHandlers(); static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); -#endif -#if PLATFORM(MAC) - void updateProcessSuppressionState() const; +#if PLATFORM(COCOA) + void updateProcessSuppressionState(); + + NSMutableDictionary *ensureBundleParameters(); + NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); } +#else + void updateProcessSuppressionState() const { } #endif + void updateHiddenPageThrottlingAutoIncreaseLimit(); + void setMemoryCacheDisabled(bool); + void setFontWhitelist(API::Array*); + + UserObservablePageCounter::Token userObservablePageCount() + { + return m_userObservablePageCounter.count(); + } + + ProcessSuppressionDisabledToken processSuppressionDisabledForPageCount() + { + return m_processSuppressionDisabledForPageCounter.count(); + } + + HiddenPageThrottlingAutoIncreasesCounter::Token hiddenPageThrottlingAutoIncreasesCount() + { + return m_hiddenPageThrottlingAutoIncreasesCounter.count(); + } + + // FIXME: Move these to API::WebsiteDataStore. + static String legacyPlatformDefaultLocalStorageDirectory(); + static String legacyPlatformDefaultIndexedDBDatabaseDirectory(); + static String legacyPlatformDefaultWebSQLDatabaseDirectory(); + static String legacyPlatformDefaultMediaKeysStorageDirectory(); + static String legacyPlatformDefaultMediaCacheDirectory(); + static String legacyPlatformDefaultApplicationCacheDirectory(); + static String legacyPlatformDefaultNetworkCacheDirectory(); + static bool isNetworkCacheEnabled(); + + bool resourceLoadStatisticsEnabled() { return m_resourceLoadStatisticsEnabled; } + void setResourceLoadStatisticsEnabled(bool enabled) { m_resourceLoadStatisticsEnabled = enabled; } + + bool alwaysRunsAtBackgroundPriority() { return m_alwaysRunsAtBackgroundPriority; } + +#if ENABLE(GAMEPAD) + void gamepadConnected(const UIGamepad&); + void gamepadDisconnected(const UIGamepad&); + + void setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>&); +#endif + +#if PLATFORM(COCOA) + bool cookieStoragePartitioningEnabled() const { return m_cookieStoragePartitioningEnabled; } + void setCookieStoragePartitioningEnabled(bool); +#endif private: void platformInitialize(); @@ -341,88 +402,58 @@ private: void requestWebContentStatistics(StatisticsRequest*); void requestNetworkingStatistics(StatisticsRequest*); -#if ENABLE(NETWORK_PROCESS) void platformInitializeNetworkProcess(NetworkProcessCreationParameters&); -#endif -#if PLATFORM(MAC) -#if PLATFORM(IOS) - void writeWebContentToPasteboard(const WebCore::PasteboardWebContent&); - void writeImageToPasteboard(const WebCore::PasteboardImage&); - void writeStringToPasteboard(const String& pasteboardType, const String&); - void readStringFromPasteboard(uint64_t index, const String& pasteboardType, WTF::String&); - void readURLFromPasteboard(uint64_t index, const String& pasteboardType, String&); - void readBufferFromPasteboard(uint64_t index, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size); - void getPasteboardItemsCount(uint64_t& itemsCount); -#endif - void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes); - void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames); - void getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String&); - void getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size); - void pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, uint64_t& newChangeCount); - void getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount); - void getPasteboardUniqueName(String& pasteboardName); - void getPasteboardColor(const String& pasteboardName, WebCore::Color&); - void getPasteboardURL(const String& pasteboardName, WTF::String&); - void addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); - void setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount); - void setPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames, uint64_t& newChangeCount); - void setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String&, uint64_t& newChangeCount); - void setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle&, uint64_t size, uint64_t& newChangeCount); -#endif + void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody); + void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, UserData& returnUserData); -#if !PLATFORM(MAC) - // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require - // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed. - void dummy(bool&); + void didGetStatistics(const StatisticsData&, uint64_t callbackID); + +#if ENABLE(GAMEPAD) + void startedUsingGamepads(IPC::Connection&); + void stoppedUsingGamepads(IPC::Connection&); + + void processStoppedUsingGamepads(WebProcessProxy&); #endif - void didGetStatistics(const StatisticsData&, uint64_t callbackID); - - // Implemented in generated WebContextMessageReceiver.cpp - void didReceiveWebContextMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncWebContextMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + // IPC::MessageReceiver. + // Implemented in generated WebProcessPoolMessageReceiver.cpp + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; static void languageChanged(void* context); void languageChanged(); - String applicationCacheDirectory() const; - String platformDefaultApplicationCacheDirectory() const; - - String databaseDirectory() const; - String platformDefaultDatabaseDirectory() const; - String platformDefaultIconDatabasePath() const; - String localStorageDirectory() const; - String platformDefaultLocalStorageDirectory() const; - - String diskCacheDirectory() const; - String platformDefaultDiskCacheDirectory() const; - +#if PLATFORM(IOS) String cookieStorageDirectory() const; - String platformDefaultCookieStorageDirectory() const; +#endif -#if PLATFORM(MAC) +#if PLATFORM(IOS) + String parentBundleDirectory() const; + String networkingCachesDirectory() const; + String webContentCachesDirectory() const; + String containerTemporaryDirectory() const; +#endif + +#if PLATFORM(COCOA) void registerNotificationObservers(); void unregisterNotificationObservers(); #endif - void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash); - void plugInDidReceiveUserInteraction(unsigned plugInOriginHash); + void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID); + void plugInDidReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID); void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool); -#if ENABLE(NETSCAPE_PLUGIN_API) - // PluginInfoStoreClient: - virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) override; -#endif + void resolvePathsForSandboxExtensions(); + void platformResolvePathsForSandboxExtensions(); + + Ref<API::ProcessPoolConfiguration> m_configuration; IPC::MessageReceiverMap m_messageReceiverMap; - ProcessModel m_processModel; - unsigned m_webProcessCountLimit; // The limit has no effect when process model is ProcessModelSharedSecondaryProcess. - Vector<RefPtr<WebProcessProxy>> m_processes; bool m_haveInitialEmptyProcess; @@ -431,79 +462,82 @@ private: Ref<WebPageGroup> m_defaultPageGroup; RefPtr<API::Object> m_injectedBundleInitializationUserData; - String m_injectedBundlePath; WebContextInjectedBundleClient m_injectedBundleClient; WebContextClient m_client; WebContextConnectionClient m_connectionClient; - WebDownloadClient m_downloadClient; - WebHistoryClient m_historyClient; + std::unique_ptr<API::AutomationClient> m_automationClient; + std::unique_ptr<API::DownloadClient> m_downloadClient; + std::unique_ptr<API::LegacyContextHistoryClient> m_historyClient; + std::unique_ptr<API::CustomProtocolManagerClient> m_customProtocolManagerClient; + + RefPtr<WebAutomationSession> m_automationSession; #if ENABLE(NETSCAPE_PLUGIN_API) PluginInfoStore m_pluginInfoStore; #endif - VisitedLinkProvider m_visitedLinkProvider; + Ref<VisitedLinkStore> m_visitedLinkStore; + bool m_visitedLinksPopulated; + PlugInAutoStartProvider m_plugInAutoStartProvider; HashSet<String> m_schemesToRegisterAsEmptyDocument; HashSet<String> m_schemesToRegisterAsSecure; + HashSet<String> m_schemesToRegisterAsBypassingContentSecurityPolicy; HashSet<String> m_schemesToSetDomainRelaxationForbiddenFor; HashSet<String> m_schemesToRegisterAsLocal; HashSet<String> m_schemesToRegisterAsNoAccess; HashSet<String> m_schemesToRegisterAsDisplayIsolated; HashSet<String> m_schemesToRegisterAsCORSEnabled; + HashSet<String> m_schemesToRegisterAsAlwaysRevalidated; + HashSet<String> m_schemesToRegisterAsCachePartitioned; bool m_alwaysUsesComplexTextCodePath; bool m_shouldUseFontSmoothing; + Vector<String> m_fontWhitelist; + // Messages that were posted before any pages were created. // The client should use initialization messages instead, so that a restarted process would get the same state. Vector<std::pair<String, RefPtr<API::Object>>> m_messagesToInjectedBundlePostedToEmptyContext; - CacheModel m_cacheModel; - bool m_memorySamplerEnabled; double m_memorySamplerInterval; RefPtr<WebIconDatabase> m_iconDatabase; -#if ENABLE(NETSCAPE_PLUGIN_API) - RefPtr<WebPluginSiteDataManager> m_pluginSiteDataManager; -#endif - RefPtr<StorageManager> m_storageManager; + const RefPtr<API::WebsiteDataStore> m_websiteDataStore; typedef HashMap<const char*, RefPtr<WebContextSupplement>, PtrHash<const char*>> WebContextSupplementMap; WebContextSupplementMap m_supplements; #if USE(SOUP) - HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy; + HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy { HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain }; + WebCore::SoupNetworkProxySettings m_networkProxySettings; #endif + HashSet<String, ASCIICaseInsensitiveHash> m_urlSchemesRegisteredForCustomProtocols; #if PLATFORM(MAC) RetainPtr<NSObject> m_enhancedAccessibilityObserver; RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver; RetainPtr<NSObject> m_automaticSpellingCorrectionNotificationObserver; -#if !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 RetainPtr<NSObject> m_automaticQuoteSubstitutionNotificationObserver; RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver; -#endif + + std::unique_ptr<HighPerformanceGraphicsUsageSampler> m_highPerformanceGraphicsUsageSampler; + std::unique_ptr<PerActivityStateCPUUsageSampler> m_perActivityStateCPUUsageSampler; #endif - String m_overrideApplicationCacheDirectory; - String m_overrideDatabaseDirectory; String m_overrideIconDatabasePath; - String m_overrideLocalStorageDirectory; - String m_overrideDiskCacheDirectory; String m_overrideCookieStorageDirectory; bool m_shouldUseTestingNetworkSession; bool m_processTerminationEnabled; -#if ENABLE(NETWORK_PROCESS) - bool m_usesNetworkProcess; + bool m_canHandleHTTPSServerTrustEvaluation; + bool m_didNetworkProcessCrash; RefPtr<NetworkProcessProxy> m_networkProcess; -#endif #if ENABLE(DATABASE_PROCESS) RefPtr<DatabaseProcessProxy> m_databaseProcess; @@ -513,68 +547,84 @@ private: HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests; #if USE(SOUP) - bool m_ignoreTLSErrors; + bool m_ignoreTLSErrors { true }; #endif bool m_memoryCacheDisabled; + bool m_resourceLoadStatisticsEnabled { false }; + + bool m_alwaysRunsAtBackgroundPriority; + + UserObservablePageCounter m_userObservablePageCounter; + ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter; + HiddenPageThrottlingAutoIncreasesCounter m_hiddenPageThrottlingAutoIncreasesCounter; + RunLoop::Timer<WebProcessPool> m_hiddenPageThrottlingTimer; + +#if PLATFORM(COCOA) + RetainPtr<NSMutableDictionary> m_bundleParameters; + ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken; +#endif + +#if ENABLE(CONTENT_EXTENSIONS) + HashMap<String, String> m_encodedContentExtensions; +#endif + +#if ENABLE(NETSCAPE_PLUGIN_API) + HashMap<String, HashMap<String, HashMap<String, uint8_t>>> m_pluginLoadClientPolicies; +#endif + +#if ENABLE(GAMEPAD) + HashSet<WebProcessProxy*> m_processesUsingGamepads; +#endif + +#if PLATFORM(COCOA) + bool m_cookieStoragePartitioningEnabled { false }; +#endif + + struct Paths { + String injectedBundlePath; + String applicationCacheDirectory; + String webSQLDatabaseDirectory; + String mediaCacheDirectory; + String mediaKeyStorageDirectory; + String uiProcessBundleResourcePath; + +#if PLATFORM(IOS) + String cookieStorageDirectory; + String containerCachesDirectory; + String containerTemporaryDirectory; +#endif + }; + Paths m_resolvedPaths; }; template<typename T> -void WebContext::sendToNetworkingProcess(T&& message) +void WebProcessPool::sendToNetworkingProcess(T&& message) { - switch (m_processModel) { - case ProcessModelSharedSecondaryProcess: -#if ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess) { - if (m_networkProcess && m_networkProcess->canSendMessage()) - m_networkProcess->send(std::forward<T>(message), 0); - return; - } -#endif - if (!m_processes.isEmpty() && m_processes[0]->canSendMessage()) - m_processes[0]->send(std::forward<T>(message), 0); - return; - case ProcessModelMultipleSecondaryProcesses: -#if ENABLE(NETWORK_PROCESS) - if (m_networkProcess && m_networkProcess->canSendMessage()) - m_networkProcess->send(std::forward<T>(message), 0); - return; -#else - break; -#endif - } - ASSERT_NOT_REACHED(); + if (m_networkProcess && m_networkProcess->canSendMessage()) + m_networkProcess->send(std::forward<T>(message), 0); } template<typename T> -void WebContext::sendToNetworkingProcessRelaunchingIfNecessary(T&& message) +void WebProcessPool::sendToNetworkingProcessRelaunchingIfNecessary(T&& message) { - switch (m_processModel) { - case ProcessModelSharedSecondaryProcess: -#if ENABLE(NETWORK_PROCESS) - if (m_usesNetworkProcess) { - ensureNetworkProcess(); - m_networkProcess->send(std::forward<T>(message), 0); - return; - } -#endif - ensureSharedWebProcess(); - m_processes[0]->send(std::forward<T>(message), 0); - return; - case ProcessModelMultipleSecondaryProcesses: -#if ENABLE(NETWORK_PROCESS) - ensureNetworkProcess(); - m_networkProcess->send(std::forward<T>(message), 0); - return; + ensureNetworkProcess(); + m_networkProcess->send(std::forward<T>(message), 0); +} + +template<typename T> +void WebProcessPool::sendToDatabaseProcessRelaunchingIfNecessary(T&& message) +{ +#if ENABLE(DATABASE_PROCESS) + ensureDatabaseProcess(); + m_databaseProcess->send(std::forward<T>(message), 0); #else - break; + sendToAllProcessesRelaunchingThemIfNecessary(std::forward<T>(message)); #endif - } - ASSERT_NOT_REACHED(); } template<typename T> -void WebContext::sendToAllProcesses(const T& message) +void WebProcessPool::sendToAllProcesses(const T& message) { size_t processCount = m_processes.size(); for (size_t i = 0; i < processCount; ++i) { @@ -585,20 +635,15 @@ void WebContext::sendToAllProcesses(const T& message) } template<typename T> -void WebContext::sendToAllProcessesRelaunchingThemIfNecessary(const T& message) +void WebProcessPool::sendToAllProcessesRelaunchingThemIfNecessary(const T& message) { -// FIXME (Multi-WebProcess): WebContext doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode. - if (m_processModel == ProcessModelSharedSecondaryProcess) - ensureSharedWebProcess(); + // FIXME (Multi-WebProcess): WebProcessPool doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode. sendToAllProcesses(message); } template<typename T> -void WebContext::sendToOneProcess(T&& message) +void WebProcessPool::sendToOneProcess(T&& message) { - if (m_processModel == ProcessModelSharedSecondaryProcess) - ensureSharedWebProcess(); - bool messageSent = false; size_t processCount = m_processes.size(); for (size_t i = 0; i < processCount; ++i) { @@ -610,7 +655,7 @@ void WebContext::sendToOneProcess(T&& message) } } - if (!messageSent && m_processModel == ProcessModelMultipleSecondaryProcesses) { + if (!messageSent) { warmInitialProcess(); RefPtr<WebProcessProxy> process = m_processes.last(); if (process->canSendMessage()) @@ -619,5 +664,3 @@ void WebContext::sendToOneProcess(T&& message) } } // namespace WebKit - -#endif // WebContext_h diff --git a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebProcessPool.messages.in index b399cab43..8990c0094 100644 --- a/Source/WebKit2/UIProcess/WebDatabaseManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebProcessPool.messages.in @@ -20,13 +20,20 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(SQL_DATABASE) +messages -> WebProcessPool { + HandleMessage(String messageName, WebKit::UserData messageBody) WantsConnection + HandleSynchronousMessage(String messageName, WebKit::UserData messageBody) -> (WebKit::UserData returnData) WantsConnection -messages -> WebDatabaseManagerProxy { - DidGetDatabasesByOrigin(Vector<WebKit::OriginAndDatabases> originAndDatabases, uint64_t callbackID); - DidGetDatabaseOrigins(Vector<String> originIdentifiers, uint64_t callbackID) - DidModifyOrigin(String originIdentifier) - DidModifyDatabase(String originIdentifier, String databaseIdentifier) -} + DidGetStatistics(struct WebKit::StatisticsData statisticsData, uint64_t callbackID) + +#if ENABLE(GAMEPAD) + StartedUsingGamepads() WantsConnection + StoppedUsingGamepads() WantsConnection +#endif -#endif // ENABLE(SQL_DATABASE) + # Plug-in messages. + void AddPlugInAutoStartOriginHash(String pageOrigin, uint32_t hash, WebCore::SessionID sessionID) + void PlugInDidReceiveUserInteraction(uint32_t hash, WebCore::SessionID sessionID) + + ReportWebContentCPUTime(int64_t cpuTime, uint64_t activityState) +} diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.cpp b/Source/WebKit2/UIProcess/WebProcessProxy.cpp index be18b2c35..d8bc5b76f 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/WebProcessProxy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,31 +27,41 @@ #include "WebProcessProxy.h" #include "APIFrameHandle.h" -#include "CustomProtocolManagerProxyMessages.h" +#include "APIPageGroupHandle.h" +#include "APIPageHandle.h" #include "DataReference.h" #include "DownloadProxyMap.h" +#include "Logging.h" #include "PluginInfoStore.h" #include "PluginProcessManager.h" #include "TextChecker.h" #include "TextCheckerState.h" +#include "UnresponsiveWebProcessTerminator.h" #include "UserData.h" #include "WebBackForwardListItem.h" -#include "WebContext.h" +#include "WebIconDatabase.h" +#include "WebInspectorUtilities.h" #include "WebNavigationDataStore.h" #include "WebNotificationManagerProxy.h" +#include "WebPageGroup.h" #include "WebPageProxy.h" -#include "WebPluginSiteDataManager.h" +#include "WebPasteboardProxy.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" #include "WebProcessProxyMessages.h" +#include "WebUserContentControllerProxy.h" +#include "WebsiteData.h" #include <WebCore/SuddenTermination.h> #include <WebCore/URL.h> #include <stdio.h> #include <wtf/NeverDestroyed.h> #include <wtf/RunLoop.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuilder.h> #include <wtf/text/WTFString.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) +#include "ObjCObjectGraph.h" #include "PDFPlugin.h" #endif @@ -79,28 +89,33 @@ static WebProcessProxy::WebPageProxyMap& globalPageMap() return pageMap; } -PassRefPtr<WebProcessProxy> WebProcessProxy::create(WebContext& context) +Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool) { - return adoptRef(new WebProcessProxy(context)); + return adoptRef(*new WebProcessProxy(processPool)); } -WebProcessProxy::WebProcessProxy(WebContext& context) - : m_responsivenessTimer(this) - , m_context(context) +WebProcessProxy::WebProcessProxy(WebProcessPool& processPool) + : ChildProcessProxy(processPool.alwaysRunsAtBackgroundPriority()) + , m_responsivenessTimer(*this) + , m_processPool(processPool) , m_mayHaveUniversalFileReadSandboxExtension(false) -#if ENABLE(CUSTOM_PROTOCOLS) - , m_customProtocolManagerProxy(this, context) -#endif -#if PLATFORM(MAC) - , m_processSuppressionEnabled(false) -#endif , m_numberOfTimesSuddenTerminationWasDisabled(0) + , m_throttler(*this) + , m_isResponsive(NoOrMaybe::Maybe) + , m_visiblePageCounter([this](RefCounterEvent) { updateBackgroundResponsivenessTimer(); }) + , m_backgroundResponsivenessTimer(processPool.configuration().unresponsiveBackgroundProcessesTerminationEnabled() ? std::make_unique<UnresponsiveWebProcessTerminator>(*this) : nullptr) { + WebPasteboardProxy::singleton().addWebProcessProxy(*this); + connect(); } WebProcessProxy::~WebProcessProxy() { + ASSERT(m_pageURLRetainCountMap.isEmpty()); + + WebPasteboardProxy::singleton().removeWebProcessProxy(*this); + if (m_webConnection) m_webConnection->invalidate(); @@ -110,37 +125,50 @@ WebProcessProxy::~WebProcessProxy() void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) { - launchOptions.processType = ProcessLauncher::WebProcess; - platformGetLaunchOptions(launchOptions); + launchOptions.processType = ProcessLauncher::ProcessType::Web; + + ChildProcessProxy::getLaunchOptions(launchOptions); + + if (WebKit::isInspectorProcessPool(m_processPool)) + launchOptions.extraInitializationData.add(ASCIILiteral("inspector-process"), ASCIILiteral("1")); + + auto overrideLanguages = m_processPool->configuration().overrideLanguages(); + if (overrideLanguages.size()) { + StringBuilder languageString; + for (size_t i = 0; i < overrideLanguages.size(); ++i) { + if (i) + languageString.append(','); + languageString.append(overrideLanguages[i]); + } + launchOptions.extraInitializationData.add(ASCIILiteral("OverrideLanguages"), languageString.toString()); + } } -void WebProcessProxy::connectionWillOpen(IPC::Connection* connection) +void WebProcessProxy::connectionWillOpen(IPC::Connection& connection) { - ASSERT(this->connection() == connection); + ASSERT(this->connection() == &connection); #if ENABLE(SEC_ITEM_SHIM) - SecItemShimProxy::shared().initializeConnection(connection); + SecItemShimProxy::singleton().initializeConnection(connection); #endif - for (WebPageProxyMap::iterator it = m_pageMap.begin(), end = m_pageMap.end(); it != end; ++it) - it->value->connectionWillOpen(connection); - - m_context->processWillOpenConnection(this); + for (auto& page : m_pageMap.values()) + page->connectionWillOpen(connection); } -void WebProcessProxy::connectionWillClose(IPC::Connection* connection) +void WebProcessProxy::processWillShutDown(IPC::Connection& connection) { - ASSERT(this->connection() == connection); + ASSERT_UNUSED(connection, this->connection() == &connection); - for (WebPageProxyMap::iterator it = m_pageMap.begin(), end = m_pageMap.end(); it != end; ++it) - it->value->connectionWillClose(connection); + for (auto& page : m_pageMap.values()) + page->webProcessWillShutDown(); - m_context->processWillCloseConnection(this); + releaseRemainingIconsForPageURLs(); } -void WebProcessProxy::disconnect() +void WebProcessProxy::shutDown() { - clearConnection(); + shutDownProcess(); if (m_webConnection) { m_webConnection->invalidate(); @@ -148,18 +176,26 @@ void WebProcessProxy::disconnect() } m_responsivenessTimer.invalidate(); + m_tokenForHoldingLockedFiles = nullptr; Vector<RefPtr<WebFrameProxy>> frames; copyValuesToVector(m_frameMap, frames); for (size_t i = 0, size = frames.size(); i < size; ++i) - frames[i]->disconnect(); + frames[i]->webProcessWillShutDown(); m_frameMap.clear(); - if (m_downloadProxyMap) - m_downloadProxyMap->processDidClose(); + for (VisitedLinkStore* visitedLinkStore : m_visitedLinkStores) + visitedLinkStore->removeProcess(*this); + m_visitedLinkStores.clear(); + + for (WebUserContentControllerProxy* webUserContentControllerProxy : m_webUserContentControllerProxies) + webUserContentControllerProxy->removeProcess(*this); + m_webUserContentControllerProxies.clear(); - m_context->disconnectProcess(this); + m_userInitiatedActionMap.clear(); + + m_processPool->disconnectProcess(this); } WebPageProxy* WebProcessProxy::webPage(uint64_t pageID) @@ -167,53 +203,122 @@ WebPageProxy* WebProcessProxy::webPage(uint64_t pageID) return globalPageMap().get(pageID); } -PassRefPtr<WebPageProxy> WebProcessProxy::createWebPage(PageClient& pageClient, const WebPageConfiguration& configuration) +void WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType> dataTypes, Vector<String>& topPrivatelyOwnedDomains, bool shouldNotifyPage, std::function<void()> completionHandler) +{ + struct CallbackAggregator : ThreadSafeRefCounted<CallbackAggregator> { + explicit CallbackAggregator(std::function<void()> completionHandler) + : completionHandler(WTFMove(completionHandler)) + { + } + + void addPendingCallback() + { + ++pendingCallbacks; + } + + void removePendingCallback() + { + ASSERT(pendingCallbacks); + --pendingCallbacks; + + callIfNeeded(); + } + + void callIfNeeded() + { + if (!pendingCallbacks) + completionHandler(); + } + + unsigned pendingCallbacks = 0; + std::function<void()> completionHandler; + }; + + RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler))); + + for (auto& page : globalPageMap()) { + if (!page.value->websiteDataStore().isPersistent()) + continue; + callbackAggregator->addPendingCallback(); + page.value->websiteDataStore().removeDataForTopPrivatelyOwnedDomains(dataTypes, { }, topPrivatelyOwnedDomains, [callbackAggregator, shouldNotifyPage, page]() { + if (shouldNotifyPage) + page.value->postMessageToInjectedBundle("WebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished", nullptr); + WTF::RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } +} + +Ref<WebPageProxy> WebProcessProxy::createWebPage(PageClient& pageClient, Ref<API::PageConfiguration>&& pageConfiguration) { uint64_t pageID = generatePageID(); - RefPtr<WebPageProxy> webPage = WebPageProxy::create(pageClient, *this, pageID, configuration); - m_pageMap.set(pageID, webPage.get()); - globalPageMap().set(pageID, webPage.get()); -#if PLATFORM(MAC) - if (webPage->isProcessSuppressible()) - m_processSuppressiblePages.add(pageID); - updateProcessSuppressionState(); -#endif - return webPage.release(); + Ref<WebPageProxy> webPage = WebPageProxy::create(pageClient, *this, pageID, WTFMove(pageConfiguration)); + + m_pageMap.set(pageID, webPage.ptr()); + globalPageMap().set(pageID, webPage.ptr()); + + updateBackgroundResponsivenessTimer(); + + return webPage; } void WebProcessProxy::addExistingWebPage(WebPageProxy* webPage, uint64_t pageID) { + ASSERT(!m_pageMap.contains(pageID)); + ASSERT(!globalPageMap().contains(pageID)); + m_pageMap.set(pageID, webPage); globalPageMap().set(pageID, webPage); -#if PLATFORM(MAC) - if (webPage->isProcessSuppressible()) - m_processSuppressiblePages.add(pageID); - updateProcessSuppressionState(); -#endif + + updateBackgroundResponsivenessTimer(); } void WebProcessProxy::removeWebPage(uint64_t pageID) { m_pageMap.remove(pageID); globalPageMap().remove(pageID); -#if PLATFORM(MAC) - m_processSuppressiblePages.remove(pageID); - updateProcessSuppressionState(); -#endif + + updateBackgroundResponsivenessTimer(); + + Vector<uint64_t> itemIDsToRemove; + for (auto& idAndItem : m_backForwardListItemMap) { + if (idAndItem.value->pageID() == pageID) + itemIDsToRemove.append(idAndItem.key); + } + for (auto itemID : itemIDsToRemove) + m_backForwardListItemMap.remove(itemID); // If this was the last WebPage open in that web process, and we have no other reason to keep it alive, let it go. // We only allow this when using a network process, as otherwise the WebProcess needs to preserve its session state. - if (m_context->usesNetworkProcess() && canTerminateChildProcess()) { - abortProcessLaunchIfNeeded(); - disconnect(); - } + if (state() == State::Terminated || !canTerminateChildProcess()) + return; + + shutDown(); } -Vector<WebPageProxy*> WebProcessProxy::pages() const +void WebProcessProxy::addVisitedLinkStore(VisitedLinkStore& store) { - Vector<WebPageProxy*> result; - copyValuesToVector(m_pageMap, result); - return result; + m_visitedLinkStores.add(&store); + store.addProcess(*this); +} + +void WebProcessProxy::addWebUserContentControllerProxy(WebUserContentControllerProxy& proxy) +{ + m_webUserContentControllerProxies.add(&proxy); + proxy.addProcess(*this); +} + +void WebProcessProxy::didDestroyVisitedLinkStore(VisitedLinkStore& store) +{ + ASSERT(m_visitedLinkStores.contains(&store)); + m_visitedLinkStores.remove(&store); +} + +void WebProcessProxy::didDestroyWebUserContentControllerProxy(WebUserContentControllerProxy& proxy) +{ + ASSERT(m_webUserContentControllerProxies.contains(&proxy)); + m_webUserContentControllerProxies.remove(&proxy); } WebBackForwardListItem* WebProcessProxy::webBackForwardItem(uint64_t itemID) const @@ -230,6 +335,11 @@ void WebProcessProxy::registerNewWebBackForwardListItem(WebBackForwardListItem* m_backForwardListItemMap.set(item->itemID(), item); } +void WebProcessProxy::removeBackForwardItem(uint64_t itemID) +{ + m_backForwardListItemMap.remove(itemID); +} + void WebProcessProxy::assumeReadAccessToBaseURL(const String& urlString) { URL url(URL(), urlString); @@ -251,11 +361,19 @@ bool WebProcessProxy::hasAssumedReadAccessToURL(const URL& url) const return false; String path = url.fileSystemPath(); - for (const String& assumedAccessPath : m_localPathsWithAssumedReadAccess) { + auto startsWithURLPath = [&path](const String& assumedAccessPath) { // There are no ".." components, because URL removes those. - if (path.startsWith(assumedAccessPath)) - return true; - } + return path.startsWith(assumedAccessPath); + }; + + auto& platformPaths = platformPathsWithAssumedReadAccess(); + auto platformPathsEnd = platformPaths.end(); + if (std::find_if(platformPaths.begin(), platformPathsEnd, startsWithURLPath) != platformPathsEnd) + return true; + + auto localPathsEnd = m_localPathsWithAssumedReadAccess.end(); + if (std::find_if(m_localPathsWithAssumedReadAccess.begin(), localPathsEnd, startsWithURLPath) != localPathsEnd) + return true; return false; } @@ -285,9 +403,11 @@ bool WebProcessProxy::checkURLReceivedFromWebProcess(const URL& url) // One case where we don't have sandbox extensions for file URLs in b/f list is if the list has been reinstated after a crash or a browser restart. String path = url.fileSystemPath(); for (WebBackForwardListItemMap::iterator iter = m_backForwardListItemMap.begin(), end = m_backForwardListItemMap.end(); iter != end; ++iter) { - if (URL(URL(), iter->value->url()).fileSystemPath() == path) + URL itemURL(URL(), iter->value->url()); + if (itemURL.isLocalFile() && itemURL.fileSystemPath() == path) return true; - if (URL(URL(), iter->value->originalURL()).fileSystemPath() == path) + URL itemOriginalURL(URL(), iter->value->originalURL()); + if (itemOriginalURL.isLocalFile() && itemOriginalURL.fileSystemPath() == path) return true; } @@ -296,44 +416,44 @@ bool WebProcessProxy::checkURLReceivedFromWebProcess(const URL& url) return false; } -#if !PLATFORM(MAC) +#if !PLATFORM(COCOA) bool WebProcessProxy::fullKeyboardAccessEnabled() { return false; } #endif -void WebProcessProxy::addBackForwardItem(uint64_t itemID, const String& originalURL, const String& url, const String& title, const IPC::DataReference& backForwardData) +void WebProcessProxy::addBackForwardItem(uint64_t itemID, uint64_t pageID, const PageState& pageState) { - MESSAGE_CHECK_URL(originalURL); - MESSAGE_CHECK_URL(url); - - WebBackForwardListItemMap::AddResult result = m_backForwardListItemMap.add(itemID, nullptr); - if (result.isNewEntry) { - result.iterator->value = WebBackForwardListItem::create(originalURL, url, title, backForwardData.data(), backForwardData.size(), itemID); + MESSAGE_CHECK_URL(pageState.mainFrameState.originalURLString); + MESSAGE_CHECK_URL(pageState.mainFrameState.urlString); + + auto& backForwardListItem = m_backForwardListItemMap.add(itemID, nullptr).iterator->value; + if (!backForwardListItem) { + BackForwardListItemState backForwardListItemState; + backForwardListItemState.identifier = itemID; + backForwardListItemState.pageState = pageState; + backForwardListItem = WebBackForwardListItem::create(WTFMove(backForwardListItemState), pageID); return; } // Update existing item. - result.iterator->value->setOriginalURL(originalURL); - result.iterator->value->setURL(url); - result.iterator->value->setTitle(title); - result.iterator->value->setBackForwardData(backForwardData.data(), backForwardData.size()); + backForwardListItem->setPageState(pageState); } #if ENABLE(NETSCAPE_PLUGIN_API) void WebProcessProxy::getPlugins(bool refresh, Vector<PluginInfo>& plugins, Vector<PluginInfo>& applicationPlugins) { if (refresh) - m_context->pluginInfoStore().refresh(); + m_processPool->pluginInfoStore().refresh(); - Vector<PluginModuleInfo> pluginModules = m_context->pluginInfoStore().plugins(); + Vector<PluginModuleInfo> pluginModules = m_processPool->pluginInfoStore().plugins(); for (size_t i = 0; i < pluginModules.size(); ++i) plugins.append(pluginModules[i].info); #if ENABLE(PDFKIT_PLUGIN) // Add built-in PDF last, so that it's not used when a real plug-in is installed. - if (!m_context->omitPDFSupport()) { + if (!m_processPool->omitPDFSupport()) { plugins.append(PDFPlugin::pluginInfo()); applicationPlugins.append(PDFPlugin::pluginInfo()); } @@ -344,32 +464,84 @@ void WebProcessProxy::getPlugins(bool refresh, Vector<PluginInfo>& plugins, Vect #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(NETSCAPE_PLUGIN_API) -void WebProcessProxy::getPluginProcessConnection(uint64_t pluginProcessToken, PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply) +void WebProcessProxy::getPluginProcessConnection(uint64_t pluginProcessToken, Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&& reply) { - PluginProcessManager::shared().getPluginProcessConnection(pluginProcessToken, reply); + PluginProcessManager::singleton().getPluginProcessConnection(pluginProcessToken, WTFMove(reply)); } #endif -#if ENABLE(NETWORK_PROCESS) -void WebProcessProxy::getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply> reply) +void WebProcessProxy::getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&& reply) { - m_context->getNetworkProcessConnection(reply); + m_processPool->getNetworkProcessConnection(WTFMove(reply)); } -#endif // ENABLE(NETWORK_PROCESS) #if ENABLE(DATABASE_PROCESS) -void WebProcessProxy::getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply> reply) +void WebProcessProxy::getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&& reply) { - m_context->getDatabaseProcessConnection(reply); + m_processPool->getDatabaseProcessConnection(WTFMove(reply)); } #endif // ENABLE(DATABASE_PROCESS) -void WebProcessProxy::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder) +void WebProcessProxy::retainIconForPageURL(const String& pageURL) +{ + WebIconDatabase* iconDatabase = processPool().iconDatabase(); + if (!iconDatabase || pageURL.isEmpty()) + return; + + // Track retain counts so we can release them if the WebProcess terminates early. + auto result = m_pageURLRetainCountMap.add(pageURL, 1); + if (!result.isNewEntry) + ++result.iterator->value; + + iconDatabase->retainIconForPageURL(pageURL); +} + +void WebProcessProxy::releaseIconForPageURL(const String& pageURL) +{ + WebIconDatabase* iconDatabase = processPool().iconDatabase(); + if (!iconDatabase || pageURL.isEmpty()) + return; + + // Track retain counts so we can release them if the WebProcess terminates early. + auto result = m_pageURLRetainCountMap.find(pageURL); + if (result == m_pageURLRetainCountMap.end()) + return; + + --result->value; + if (!result->value) + m_pageURLRetainCountMap.remove(result); + + iconDatabase->releaseIconForPageURL(pageURL); +} + +void WebProcessProxy::releaseRemainingIconsForPageURLs() +{ + WebIconDatabase* iconDatabase = processPool().iconDatabase(); + if (!iconDatabase) + return; + + for (auto& entry : m_pageURLRetainCountMap) { + uint64_t count = entry.value; + for (uint64_t i = 0; i < count; ++i) + iconDatabase->releaseIconForPageURL(entry.key); + } + + m_pageURLRetainCountMap.clear(); +} + +#if !PLATFORM(COCOA) +bool WebProcessProxy::platformIsBeingDebugged() const +{ + return false; +} +#endif + +void WebProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder) { if (dispatchMessage(connection, decoder)) return; - if (m_context->dispatchMessage(connection, decoder)) + if (m_processPool->dispatchMessage(connection, decoder)) return; if (decoder.messageReceiverName() == Messages::WebProcessProxy::messageReceiverName()) { @@ -380,12 +552,12 @@ void WebProcessProxy::didReceiveMessage(IPC::Connection* connection, IPC::Messag // FIXME: Add unhandled message logging. } -void WebProcessProxy::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder) +void WebProcessProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder) { if (dispatchSyncMessage(connection, decoder, replyEncoder)) return; - if (m_context->dispatchSyncMessage(connection, decoder, replyEncoder)) + if (m_processPool->dispatchSyncMessage(connection, decoder, replyEncoder)) return; if (decoder.messageReceiverName() == Messages::WebProcessProxy::messageReceiverName()) { @@ -396,7 +568,7 @@ void WebProcessProxy::didReceiveSyncMessage(IPC::Connection* connection, IPC::Me // FIXME: Add unhandled message logging. } -void WebProcessProxy::didClose(IPC::Connection*) +void WebProcessProxy::didClose(IPC::Connection&) { // Protect ourselves, as the call to disconnect() below may otherwise cause us // to be deleted before we can finish our work. @@ -407,18 +579,18 @@ void WebProcessProxy::didClose(IPC::Connection*) Vector<RefPtr<WebPageProxy>> pages; copyValuesToVector(m_pageMap, pages); - disconnect(); + shutDown(); for (size_t i = 0, size = pages.size(); i < size; ++i) pages[i]->processDidCrash(); } -void WebProcessProxy::didReceiveInvalidMessage(IPC::Connection* connection, IPC::StringReference messageReceiverName, IPC::StringReference messageName) +void WebProcessProxy::didReceiveInvalidMessage(IPC::Connection& connection, IPC::StringReference messageReceiverName, IPC::StringReference messageName) { WTFLogAlways("Received an invalid message \"%s.%s\" from the web process.\n", messageReceiverName.toString().data(), messageName.toString().data()); - WebContext::didReceiveInvalidMessage(messageReceiverName, messageName); + WebProcessPool::didReceiveInvalidMessage(messageReceiverName, messageName); // Terminate the WebProcess. terminate(); @@ -428,40 +600,72 @@ void WebProcessProxy::didReceiveInvalidMessage(IPC::Connection* connection, IPC: didClose(connection); } -void WebProcessProxy::didBecomeUnresponsive(ResponsivenessTimer*) +void WebProcessProxy::didBecomeUnresponsive() { + m_isResponsive = NoOrMaybe::No; + Vector<RefPtr<WebPageProxy>> pages; copyValuesToVector(m_pageMap, pages); - for (size_t i = 0, size = pages.size(); i < size; ++i) - pages[i]->processDidBecomeUnresponsive(); + + auto isResponsiveCallbacks = WTFMove(m_isResponsiveCallbacks); + + for (auto& page : pages) + page->processDidBecomeUnresponsive(); + + bool isWebProcessResponsive = false; + for (auto& callback : isResponsiveCallbacks) + callback(isWebProcessResponsive); } -void WebProcessProxy::interactionOccurredWhileUnresponsive(ResponsivenessTimer*) +void WebProcessProxy::didBecomeResponsive() { + m_isResponsive = NoOrMaybe::Maybe; + Vector<RefPtr<WebPageProxy>> pages; copyValuesToVector(m_pageMap, pages); - for (size_t i = 0, size = pages.size(); i < size; ++i) - pages[i]->interactionOccurredWhileProcessUnresponsive(); + for (auto& page : pages) + page->processDidBecomeResponsive(); } -void WebProcessProxy::didBecomeResponsive(ResponsivenessTimer*) +void WebProcessProxy::willChangeIsResponsive() { Vector<RefPtr<WebPageProxy>> pages; copyValuesToVector(m_pageMap, pages); - for (size_t i = 0, size = pages.size(); i < size; ++i) - pages[i]->processDidBecomeResponsive(); + for (auto& page : pages) + page->willChangeProcessIsResponsive(); +} + +void WebProcessProxy::didChangeIsResponsive() +{ + Vector<RefPtr<WebPageProxy>> pages; + copyValuesToVector(m_pageMap, pages); + for (auto& page : pages) + page->didChangeProcessIsResponsive(); +} + +bool WebProcessProxy::mayBecomeUnresponsive() +{ + return !platformIsBeingDebugged(); } void WebProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) { ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); + for (WebPageProxy* page : m_pageMap.values()) { + ASSERT(this == &page->process()); + page->processDidFinishLaunching(); + } + m_webConnection = WebConnectionToWebProcess::create(this); - m_context->processDidFinishLaunching(this); + m_processPool->processDidFinishLaunching(this); -#if PLATFORM(MAC) - updateProcessSuppressionState(); +#if PLATFORM(IOS) + if (connection()) { + if (xpc_connection_t xpcConnection = connection()->xpcConnection()) + m_throttler.didConnectToProcess(xpc_connection_get_pid(xpcConnection)); + } #endif } @@ -499,7 +703,7 @@ void WebProcessProxy::disconnectFramesFromPage(WebPageProxy* page) copyValuesToVector(m_frameMap, frames); for (size_t i = 0, size = frames.size(); i < size; ++i) { if (frames[i]->page() == page) - frames[i]->disconnect(); + frames[i]->webProcessWillShutDown(); } } @@ -513,15 +717,32 @@ size_t WebProcessProxy::frameCountInPage(WebPageProxy* page) const return result; } +auto WebProcessProxy::visiblePageToken() const -> VisibleWebPageToken +{ + return m_visiblePageCounter.count(); +} + +RefPtr<API::UserInitiatedAction> WebProcessProxy::userInitiatedActivity(uint64_t identifier) +{ + if (!UserInitiatedActionMap::isValidKey(identifier) || !identifier) + return nullptr; + + auto result = m_userInitiatedActionMap.ensure(identifier, [] { return API::UserInitiatedAction::create(); }); + return result.iterator->value; +} + +void WebProcessProxy::didDestroyUserGestureToken(uint64_t identifier) +{ + ASSERT(UserInitiatedActionMap::isValidKey(identifier)); + m_userInitiatedActionMap.remove(identifier); +} + bool WebProcessProxy::canTerminateChildProcess() { if (!m_pageMap.isEmpty()) return false; - if (m_downloadProxyMap && !m_downloadProxyMap->isEmpty()) - return false; - - if (!m_context->shouldTerminate(this)) + if (!m_processPool->shouldTerminate(this)) return false; return true; @@ -531,8 +752,8 @@ void WebProcessProxy::shouldTerminate(bool& shouldTerminate) { shouldTerminate = canTerminateChildProcess(); if (shouldTerminate) { - // We know that the web process is going to terminate so disconnect it from the context. - disconnect(); + // We know that the web process is going to terminate so start shutting it down in the UI process. + shutDown(); } } @@ -542,169 +763,342 @@ void WebProcessProxy::updateTextCheckerState() send(Messages::WebProcess::SetTextCheckerState(TextChecker::state()), 0); } -DownloadProxy* WebProcessProxy::createDownloadProxy() +void WebProcessProxy::didSaveToPageCache() { -#if ENABLE(NETWORK_PROCESS) - ASSERT(!m_context->usesNetworkProcess()); -#endif + m_processPool->processDidCachePage(this); +} - if (!m_downloadProxyMap) - m_downloadProxyMap = adoptPtr(new DownloadProxyMap(this)); +void WebProcessProxy::releasePageCache() +{ + if (canSendMessage()) + send(Messages::WebProcess::ReleasePageCache(), 0); +} - return m_downloadProxyMap->createDownloadProxy(m_context.get()); +void WebProcessProxy::windowServerConnectionStateChanged() +{ + for (const auto& page : m_pageMap.values()) + page->activityStateDidChange(ActivityState::IsVisuallyIdle); } -void WebProcessProxy::didNavigateWithNavigationData(uint64_t pageID, const WebNavigationDataStore& store, uint64_t frameID) +void WebProcessProxy::fetchWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, Function<void (WebsiteData)> completionHandler) { - WebPageProxy* page = webPage(pageID); - if (!page) - return; - - WebFrameProxy* frame = webFrame(frameID); - MESSAGE_CHECK(frame); - MESSAGE_CHECK(frame->page() == page); - - m_context->historyClient().didNavigateWithNavigationData(&m_context.get(), page, store, frame); + ASSERT(canSendMessage()); + + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is taking a background assertion because the Web process is fetching Website data", this); + + connection()->sendWithReply(Messages::WebProcess::FetchWebsiteData(sessionID, dataTypes), 0, RunLoop::main(), [this, token, completionHandler = WTFMove(completionHandler), sessionID](auto reply) { + if (!reply) { + completionHandler(WebsiteData { }); + return; + } + + completionHandler(WTFMove(std::get<0>(*reply))); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is releasing a background assertion because the Web process is done fetching Website data", this); + }); } -void WebProcessProxy::didPerformClientRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID) +void WebProcessProxy::deleteWebsiteData(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, std::chrono::system_clock::time_point modifiedSince, Function<void ()> completionHandler) { - WebPageProxy* page = webPage(pageID); - if (!page) - return; + ASSERT(canSendMessage()); - if (sourceURLString.isEmpty() || destinationURLString.isEmpty()) - return; - - WebFrameProxy* frame = webFrame(frameID); - MESSAGE_CHECK(frame); - MESSAGE_CHECK(frame->page() == page); - MESSAGE_CHECK_URL(sourceURLString); - MESSAGE_CHECK_URL(destinationURLString); + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is taking a background assertion because the Web process is deleting Website data", this); + + connection()->sendWithReply(Messages::WebProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince), 0, RunLoop::main(), [this, token, completionHandler = WTFMove(completionHandler), sessionID](auto reply) { + completionHandler(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is releasing a background assertion because the Web process is done deleting Website data", this); + }); +} + +void WebProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, const Vector<WebCore::SecurityOriginData>& origins, Function<void()> completionHandler) +{ + ASSERT(canSendMessage()); - m_context->historyClient().didPerformClientRedirect(&m_context.get(), page, sourceURLString, destinationURLString, frame); + auto token = throttler().backgroundActivityToken(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is taking a background assertion because the Web process is deleting Website data for several origins", this); + + connection()->sendWithReply(Messages::WebProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins), 0, RunLoop::main(), [this, token, completionHandler = WTFMove(completionHandler), sessionID](auto reply) { + completionHandler(); + RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - WebProcessProxy is releasing a background assertion because the Web process is done deleting Website data for several origins", this); + }); } -void WebProcessProxy::didPerformServerRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID) +void WebProcessProxy::requestTermination() { - WebPageProxy* page = webPage(pageID); - if (!page) + if (state() == State::Terminated) return; - - if (sourceURLString.isEmpty() || destinationURLString.isEmpty()) - return; - - WebFrameProxy* frame = webFrame(frameID); - MESSAGE_CHECK(frame); - MESSAGE_CHECK(frame->page() == page); - MESSAGE_CHECK_URL(sourceURLString); - MESSAGE_CHECK_URL(destinationURLString); - m_context->historyClient().didPerformServerRedirect(&m_context.get(), page, sourceURLString, destinationURLString, frame); + ChildProcessProxy::terminate(); + + if (webConnection()) + webConnection()->didClose(); + + shutDown(); } -void WebProcessProxy::didUpdateHistoryTitle(uint64_t pageID, const String& title, const String& url, uint64_t frameID) +void WebProcessProxy::enableSuddenTermination() { - WebPageProxy* page = webPage(pageID); - if (!page) + if (state() != State::Running) return; - WebFrameProxy* frame = webFrame(frameID); - MESSAGE_CHECK(frame); - MESSAGE_CHECK(frame->page() == page); - MESSAGE_CHECK_URL(url); + ASSERT(m_numberOfTimesSuddenTerminationWasDisabled); + WebCore::enableSuddenTermination(); + --m_numberOfTimesSuddenTerminationWasDisabled; +} - m_context->historyClient().didUpdateHistoryTitle(&m_context.get(), page, title, url, frame); +void WebProcessProxy::disableSuddenTermination() +{ + if (state() != State::Running) + return; + + WebCore::disableSuddenTermination(); + ++m_numberOfTimesSuddenTerminationWasDisabled; } -void WebProcessProxy::pageSuppressibilityChanged(WebKit::WebPageProxy *page) +RefPtr<API::Object> WebProcessProxy::transformHandlesToObjects(API::Object* object) { -#if PLATFORM(MAC) - if (page->isProcessSuppressible()) - m_processSuppressiblePages.add(page->pageID()); - else - m_processSuppressiblePages.remove(page->pageID()); - updateProcessSuppressionState(); -#else - UNUSED_PARAM(page); + struct Transformer final : UserData::Transformer { + Transformer(WebProcessProxy& webProcessProxy) + : m_webProcessProxy(webProcessProxy) + { + } + + bool shouldTransformObject(const API::Object& object) const override + { + switch (object.type()) { + case API::Object::Type::FrameHandle: + return static_cast<const API::FrameHandle&>(object).isAutoconverting(); + + case API::Object::Type::PageHandle: + return static_cast<const API::PageHandle&>(object).isAutoconverting(); + + case API::Object::Type::PageGroupHandle: +#if PLATFORM(COCOA) + case API::Object::Type::ObjCObjectGraph: +#endif + return true; + + default: + return false; + } + } + + RefPtr<API::Object> transformObject(API::Object& object) const override + { + switch (object.type()) { + case API::Object::Type::FrameHandle: + ASSERT(static_cast<API::FrameHandle&>(object).isAutoconverting()); + return m_webProcessProxy.webFrame(static_cast<API::FrameHandle&>(object).frameID()); + + case API::Object::Type::PageGroupHandle: + return WebPageGroup::get(static_cast<API::PageGroupHandle&>(object).webPageGroupData().pageGroupID); + + case API::Object::Type::PageHandle: + ASSERT(static_cast<API::PageHandle&>(object).isAutoconverting()); + return m_webProcessProxy.webPage(static_cast<API::PageHandle&>(object).pageID()); + +#if PLATFORM(COCOA) + case API::Object::Type::ObjCObjectGraph: + return m_webProcessProxy.transformHandlesToObjects(static_cast<ObjCObjectGraph&>(object)); #endif + default: + return &object; + } + } + + WebProcessProxy& m_webProcessProxy; + }; + + return UserData::transform(object, Transformer(*this)); } -void WebProcessProxy::pagePreferencesChanged(WebKit::WebPageProxy *page) +RefPtr<API::Object> WebProcessProxy::transformObjectsToHandles(API::Object* object) { -#if PLATFORM(MAC) - if (page->isProcessSuppressible()) - m_processSuppressiblePages.add(page->pageID()); - else - m_processSuppressiblePages.remove(page->pageID()); - updateProcessSuppressionState(); -#else - UNUSED_PARAM(page); + struct Transformer final : UserData::Transformer { + bool shouldTransformObject(const API::Object& object) const override + { + switch (object.type()) { + case API::Object::Type::Frame: + case API::Object::Type::Page: + case API::Object::Type::PageGroup: +#if PLATFORM(COCOA) + case API::Object::Type::ObjCObjectGraph: +#endif + return true; + + default: + return false; + } + } + + RefPtr<API::Object> transformObject(API::Object& object) const override + { + switch (object.type()) { + case API::Object::Type::Frame: + return API::FrameHandle::createAutoconverting(static_cast<const WebFrameProxy&>(object).frameID()); + + case API::Object::Type::Page: + return API::PageHandle::createAutoconverting(static_cast<const WebPageProxy&>(object).pageID()); + + case API::Object::Type::PageGroup: + return API::PageGroupHandle::create(WebPageGroupData(static_cast<const WebPageGroup&>(object).data())); + +#if PLATFORM(COCOA) + case API::Object::Type::ObjCObjectGraph: + return transformObjectsToHandles(static_cast<ObjCObjectGraph&>(object)); #endif + + default: + return &object; + } + } + }; + + return UserData::transform(object, Transformer()); } -void WebProcessProxy::didSaveToPageCache() +void WebProcessProxy::sendProcessWillSuspendImminently() { - m_context->processDidCachePage(this); + if (!canSendMessage()) + return; + + bool handled = false; + sendSync(Messages::WebProcess::ProcessWillSuspendImminently(), Messages::WebProcess::ProcessWillSuspendImminently::Reply(handled), 0, 1_s); } -void WebProcessProxy::releasePageCache() +void WebProcessProxy::sendPrepareToSuspend() { if (canSendMessage()) - send(Messages::WebProcess::ReleasePageCache(), 0); + send(Messages::WebProcess::PrepareToSuspend(), 0); } -void WebProcessProxy::windowServerConnectionStateChanged() +void WebProcessProxy::sendCancelPrepareToSuspend() { - for (const auto& page : m_pageMap.values()) - page->viewStateDidChange(ViewState::IsVisuallyIdle); + if (canSendMessage()) + send(Messages::WebProcess::CancelPrepareToSuspend(), 0); } -void WebProcessProxy::requestTermination() +void WebProcessProxy::sendProcessDidResume() { - if (!isValid()) - return; + if (canSendMessage()) + send(Messages::WebProcess::ProcessDidResume(), 0); +} - ChildProcessProxy::terminate(); +void WebProcessProxy::processReadyToSuspend() +{ + m_throttler.processReadyToSuspend(); +} - if (webConnection()) - webConnection()->didClose(); +void WebProcessProxy::didCancelProcessSuspension() +{ + m_throttler.didCancelProcessSuspension(); +} - disconnect(); +void WebProcessProxy::reinstateNetworkProcessAssertionState(NetworkProcessProxy& newNetworkProcessProxy) +{ +#if PLATFORM(IOS) + ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess); + + // The network process crashed; take new tokens for the new network process. + if (m_backgroundTokenForNetworkProcess) + m_backgroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().backgroundActivityToken(); + else if (m_foregroundTokenForNetworkProcess) + m_foregroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().foregroundActivityToken(); +#else + UNUSED_PARAM(newNetworkProcessProxy); +#endif } -void WebProcessProxy::enableSuddenTermination() +void WebProcessProxy::didSetAssertionState(AssertionState state) { - if (!isValid()) - return; +#if PLATFORM(IOS) + ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess); + + switch (state) { + case AssertionState::Suspended: + RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Suspended) release all assertions for network process", this); + m_foregroundTokenForNetworkProcess = nullptr; + m_backgroundTokenForNetworkProcess = nullptr; + for (auto& page : m_pageMap.values()) + page->processWillBecomeSuspended(); + break; + + case AssertionState::Background: + RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Background) taking background assertion for network process", this); + m_backgroundTokenForNetworkProcess = processPool().ensureNetworkProcess().throttler().backgroundActivityToken(); + m_foregroundTokenForNetworkProcess = nullptr; + break; + + case AssertionState::Foreground: + RELEASE_LOG(ProcessSuspension, "%p - WebProcessProxy::didSetAssertionState(Foreground) taking foreground assertion for network process", this); + m_foregroundTokenForNetworkProcess = processPool().ensureNetworkProcess().throttler().foregroundActivityToken(); + m_backgroundTokenForNetworkProcess = nullptr; + for (auto& page : m_pageMap.values()) + page->processWillBecomeForeground(); + break; + } - ASSERT(m_numberOfTimesSuddenTerminationWasDisabled); - WebCore::enableSuddenTermination(); - --m_numberOfTimesSuddenTerminationWasDisabled; + ASSERT(!m_backgroundTokenForNetworkProcess || !m_foregroundTokenForNetworkProcess); +#else + UNUSED_PARAM(state); +#endif +} + +void WebProcessProxy::setIsHoldingLockedFiles(bool isHoldingLockedFiles) +{ + if (!isHoldingLockedFiles) { + RELEASE_LOG(ProcessSuspension, "UIProcess is releasing a background assertion because the WebContent process is no longer holding locked files"); + m_tokenForHoldingLockedFiles = nullptr; + return; + } + if (!m_tokenForHoldingLockedFiles) { + RELEASE_LOG(ProcessSuspension, "UIProcess is taking a background assertion because the WebContent process is holding locked files"); + m_tokenForHoldingLockedFiles = m_throttler.backgroundActivityToken(); + } } -void WebProcessProxy::disableSuddenTermination() +void WebProcessProxy::isResponsive(std::function<void(bool isWebProcessResponsive)> callback) { - if (!isValid()) + if (m_isResponsive == NoOrMaybe::No) { + if (callback) { + RunLoop::main().dispatch([callback = WTFMove(callback)] { + bool isWebProcessResponsive = false; + callback(isWebProcessResponsive); + }); + } return; + } - WebCore::disableSuddenTermination(); - ++m_numberOfTimesSuddenTerminationWasDisabled; + if (callback) + m_isResponsiveCallbacks.append(callback); + + responsivenessTimer().start(); + send(Messages::WebProcess::MainThreadPing(), 0); } -RefPtr<API::Object> WebProcessProxy::apiObjectByConvertingToHandles(API::Object* object) +void WebProcessProxy::didReceiveMainThreadPing() { - return UserData::transform(object, [](const API::Object& object) -> RefPtr<API::Object> { - switch (object.type()) { - case API::Object::Type::Frame: { - auto& frame = static_cast<const WebFrameProxy&>(object); - return API::FrameHandle::create(frame.frameID()); - } + responsivenessTimer().stop(); - default: - return nullptr; - } - }); + auto isResponsiveCallbacks = WTFMove(m_isResponsiveCallbacks); + bool isWebProcessResponsive = true; + for (auto& callback : isResponsiveCallbacks) + callback(isWebProcessResponsive); } +void WebProcessProxy::updateBackgroundResponsivenessTimer() +{ + if (m_backgroundResponsivenessTimer) + m_backgroundResponsivenessTimer->updateState(); +} + +#if !PLATFORM(COCOA) +const HashSet<String>& WebProcessProxy::platformPathsWithAssumedReadAccess() +{ + static NeverDestroyed<HashSet<String>> platformPathsWithAssumedReadAccess; + return platformPathsWithAssumedReadAccess; +} +#endif + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.h b/Source/WebKit2/UIProcess/WebProcessProxy.h index a6d872241..e31894e90 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.h +++ b/Source/WebKit2/UIProcess/WebProcessProxy.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2010-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,69 +23,78 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebProcessProxy_h -#define WebProcessProxy_h +#pragma once -#include "APISession.h" +#include "APIUserInitiatedAction.h" #include "ChildProcessProxy.h" #include "MessageReceiverMap.h" -#include "PlatformProcessIdentifier.h" #include "PluginInfoStore.h" #include "ProcessLauncher.h" +#include "ProcessThrottlerClient.h" #include "ResponsivenessTimer.h" #include "WebConnectionToWebProcess.h" #include "WebPageProxy.h" #include "WebProcessProxyMessages.h" #include <WebCore/LinkHash.h> +#include <memory> #include <wtf/Forward.h> #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> -#if ENABLE(CUSTOM_PROTOCOLS) -#include "CustomProtocolManagerProxy.h" +#if PLATFORM(IOS) +#include "ProcessThrottler.h" #endif namespace WebCore { +class ResourceRequest; class URL; struct PluginInfo; }; namespace WebKit { -class DownloadProxyMap; +class NetworkProcessProxy; +class UnresponsiveWebProcessTerminator; class WebBackForwardListItem; -class WebContext; class WebPageGroup; +class WebProcessPool; +enum class WebsiteDataType; struct WebNavigationDataStore; +struct WebsiteData; -class WebProcessProxy : public ChildProcessProxy, ResponsivenessTimer::Client { +class WebProcessProxy : public ChildProcessProxy, ResponsivenessTimer::Client, private ProcessThrottlerClient { public: typedef HashMap<uint64_t, RefPtr<WebBackForwardListItem>> WebBackForwardListItemMap; typedef HashMap<uint64_t, RefPtr<WebFrameProxy>> WebFrameProxyMap; typedef HashMap<uint64_t, WebPageProxy*> WebPageProxyMap; + typedef HashMap<uint64_t, RefPtr<API::UserInitiatedAction>> UserInitiatedActionMap; - static PassRefPtr<WebProcessProxy> create(WebContext&); + static Ref<WebProcessProxy> create(WebProcessPool&); ~WebProcessProxy(); - static WebProcessProxy* fromConnection(IPC::Connection* connection) - { - return static_cast<WebProcessProxy*>(ChildProcessProxy::fromConnection(connection)); - } - WebConnection* webConnection() const { return m_webConnection.get(); } - WebContext& context() { return m_context.get(); } + WebProcessPool& processPool() { return m_processPool; } static WebPageProxy* webPage(uint64_t pageID); - PassRefPtr<WebPageProxy> createWebPage(PageClient&, const WebPageConfiguration&); + Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&); void addExistingWebPage(WebPageProxy*, uint64_t pageID); void removeWebPage(uint64_t pageID); - Vector<WebPageProxy*> pages() const; + + WTF::IteratorRange<WebPageProxyMap::const_iterator::Values> pages() const { return m_pageMap.values(); } + unsigned pageCount() const { return m_pageMap.size(); } + unsigned visiblePageCount() const { return m_visiblePageCounter.value(); } + + void addVisitedLinkStore(VisitedLinkStore&); + void addWebUserContentControllerProxy(WebUserContentControllerProxy&); + void didDestroyVisitedLinkStore(VisitedLinkStore&); + void didDestroyWebUserContentControllerProxy(WebUserContentControllerProxy&); WebBackForwardListItem* webBackForwardItem(uint64_t itemID) const; + RefPtr<API::UserInitiatedAction> userInitiatedActivity(uint64_t); - ResponsivenessTimer* responsivenessTimer() { return &m_responsivenessTimer; } + ResponsivenessTimer& responsivenessTimer() { return m_responsivenessTimer; } WebFrameProxy* webFrame(uint64_t) const; bool canCreateFrame(uint64_t frameID) const; @@ -93,9 +102,12 @@ public: void disconnectFramesFromPage(WebPageProxy*); // Including main frame. size_t frameCountInPage(WebPageProxy*) const; // Including main frame. + VisibleWebPageToken visiblePageToken() const; + void updateTextCheckerState(); void registerNewWebBackForwardListItem(WebBackForwardListItem*); + void removeBackForwardItem(uint64_t); void willAcquireUniversalFileReadSandboxExtension() { m_mayHaveUniversalFileReadSandboxExtension = true; } void assumeReadAccessToBaseURL(const String&); @@ -106,45 +118,59 @@ public: static bool fullKeyboardAccessEnabled(); - DownloadProxy* createDownloadProxy(); - - void pageSuppressibilityChanged(WebPageProxy*); - void pagePreferencesChanged(WebPageProxy*); - void didSaveToPageCache(); void releasePageCache(); -#if PLATFORM(MAC) - bool allPagesAreProcessSuppressible() const; - void updateProcessSuppressionState(); -#endif + void fetchWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, Function<void(WebsiteData)> completionHandler); + void deleteWebsiteData(WebCore::SessionID, OptionSet<WebsiteDataType>, std::chrono::system_clock::time_point modifiedSince, Function<void()> completionHandler); + void deleteWebsiteDataForOrigins(WebCore::SessionID, OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, Function<void()> completionHandler); + static void deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType>, Vector<String>& topPrivatelyOwnedDomains, bool shouldNotifyPages, std::function<void()> completionHandler); void enableSuddenTermination(); void disableSuddenTermination(); + bool isSuddenTerminationEnabled() { return !m_numberOfTimesSuddenTerminationWasDisabled; } void requestTermination(); - RefPtr<API::Object> apiObjectByConvertingToHandles(API::Object*); + RefPtr<API::Object> transformHandlesToObjects(API::Object*); + static RefPtr<API::Object> transformObjectsToHandles(API::Object*); + +#if PLATFORM(COCOA) + RefPtr<ObjCObjectGraph> transformHandlesToObjects(ObjCObjectGraph&); + static RefPtr<ObjCObjectGraph> transformObjectsToHandles(ObjCObjectGraph&); +#endif void windowServerConnectionStateChanged(); + void processReadyToSuspend(); + void didCancelProcessSuspension(); + + void setIsHoldingLockedFiles(bool); + + ProcessThrottler& throttler() { return m_throttler; } + + void reinstateNetworkProcessAssertionState(NetworkProcessProxy&); + + void isResponsive(std::function<void(bool isWebProcessResponsive)>); + void didReceiveMainThreadPing(); + private: - explicit WebProcessProxy(WebContext&); + explicit WebProcessProxy(WebProcessPool&); // From ChildProcessProxy - virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; - void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&); - virtual void connectionWillOpen(IPC::Connection*) override; - virtual void connectionWillClose(IPC::Connection*) override; + void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; + void connectionWillOpen(IPC::Connection&) override; + void processWillShutDown(IPC::Connection&) override; // Called when the web process has crashed or we know that it will terminate soon. // Will potentially cause the WebProcessProxy object to be freed. - void disconnect(); + void shutDown(); // IPC message handlers. - void addBackForwardItem(uint64_t itemID, const String& originalURLString, const String& urlString, const String& title, const IPC::DataReference& backForwardData); + void addBackForwardItem(uint64_t itemID, uint64_t pageID, const PageState&); void didDestroyFrame(uint64_t); - + void didDestroyUserGestureToken(uint64_t); + void shouldTerminate(bool& shouldTerminate); // Plugins @@ -152,46 +178,57 @@ private: void getPlugins(bool refresh, Vector<WebCore::PluginInfo>& plugins, Vector<WebCore::PluginInfo>& applicationPlugins); #endif // ENABLE(NETSCAPE_PLUGIN_API) #if ENABLE(NETSCAPE_PLUGIN_API) - void getPluginProcessConnection(uint64_t pluginProcessToken, PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>); -#endif -#if ENABLE(NETWORK_PROCESS) - void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>); + void getPluginProcessConnection(uint64_t pluginProcessToken, Ref<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>&&); #endif + void getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&&); #if ENABLE(DATABASE_PROCESS) - void getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>); + void getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&&); #endif + void retainIconForPageURL(const String& pageURL); + void releaseIconForPageURL(const String& pageURL); + void releaseRemainingIconsForPageURLs(); + + bool platformIsBeingDebugged() const; + + static const HashSet<String>& platformPathsWithAssumedReadAccess(); + + void updateBackgroundResponsivenessTimer(); + // IPC::Connection::Client friend class WebConnectionToWebProcess; - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; - virtual void didClose(IPC::Connection*) override; - virtual void didReceiveInvalidMessage(IPC::Connection*, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; + void didClose(IPC::Connection&) override; + void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; // ResponsivenessTimer::Client - void didBecomeUnresponsive(ResponsivenessTimer*) override; - void interactionOccurredWhileUnresponsive(ResponsivenessTimer*) override; - void didBecomeResponsive(ResponsivenessTimer*) override; + void didBecomeUnresponsive() override; + void didBecomeResponsive() override; + void willChangeIsResponsive() override; + void didChangeIsResponsive() override; + bool mayBecomeUnresponsive() override; + + // ProcessThrottlerClient + void sendProcessWillSuspendImminently() override; + void sendPrepareToSuspend() override; + void sendCancelPrepareToSuspend() override; + void sendProcessDidResume() override; + void didSetAssertionState(AssertionState) override; // ProcessLauncher::Client - virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; - - // History client - void didNavigateWithNavigationData(uint64_t pageID, const WebNavigationDataStore&, uint64_t frameID); - void didPerformClientRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID); - void didPerformServerRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID); - void didUpdateHistoryTitle(uint64_t pageID, const String& title, const String& url, uint64_t frameID); + void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; // Implemented in generated WebProcessProxyMessageReceiver.cpp - void didReceiveWebProcessProxyMessage(IPC::Connection*, IPC::MessageDecoder&); - void didReceiveSyncWebProcessProxyMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&); + void didReceiveWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&); + void didReceiveSyncWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); bool canTerminateChildProcess(); ResponsivenessTimer m_responsivenessTimer; RefPtr<WebConnectionToWebProcess> m_webConnection; - Ref<WebContext> m_context; + Ref<WebProcessPool> m_processPool; bool m_mayHaveUniversalFileReadSandboxExtension; // True if a read extension for "/" was ever granted - we don't track whether WebProcess still has it. HashSet<String> m_localPathsWithAssumedReadAccess; @@ -199,21 +236,26 @@ private: WebPageProxyMap m_pageMap; WebFrameProxyMap m_frameMap; WebBackForwardListItemMap m_backForwardListItemMap; + UserInitiatedActionMap m_userInitiatedActionMap; - OwnPtr<DownloadProxyMap> m_downloadProxyMap; + HashSet<VisitedLinkStore*> m_visitedLinkStores; + HashSet<WebUserContentControllerProxy*> m_webUserContentControllerProxies; -#if ENABLE(CUSTOM_PROTOCOLS) - CustomProtocolManagerProxy m_customProtocolManagerProxy; + int m_numberOfTimesSuddenTerminationWasDisabled; + ProcessThrottler m_throttler; + ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles; +#if PLATFORM(IOS) + ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess; + ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess; #endif -#if PLATFORM(MAC) - HashSet<uint64_t> m_processSuppressiblePages; - bool m_processSuppressionEnabled; -#endif + HashMap<String, uint64_t> m_pageURLRetainCountMap; - int m_numberOfTimesSuddenTerminationWasDisabled; + enum class NoOrMaybe { No, Maybe } m_isResponsive; + Vector<std::function<void(bool webProcessIsResponsive)>> m_isResponsiveCallbacks; + + VisibleWebPageCounter m_visiblePageCounter; + std::unique_ptr<UnresponsiveWebProcessTerminator> m_backgroundResponsivenessTimer; }; - -} // namespace WebKit -#endif // WebProcessProxy_h +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in index 9d49736b8..f21565ba3 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in @@ -21,16 +21,11 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> WebProcessProxy LegacyReceiver { - - # History client messages. - DidNavigateWithNavigationData(uint64_t pageID, WebKit::WebNavigationDataStore store, uint64_t frameID) - DidPerformClientRedirect(uint64_t pageID, String sourceURLString, String destinationURLString, uint64_t frameID) - DidPerformServerRedirect(uint64_t pageID, String sourceURLString, String destinationURLString, uint64_t frameID) - DidUpdateHistoryTitle(uint64_t pageID, String title, String url, uint64_t frameID) - - AddBackForwardItem(uint64_t itemID, String originalURL, String url, String title, IPC::DataReference backForwardData) + AddBackForwardItem(uint64_t itemID, uint64_t pageID, struct WebKit::PageState pageState) DidDestroyFrame(uint64_t frameID) + DidDestroyUserGestureToken(uint64_t userGestureTokenID) + ShouldTerminate() -> (bool shouldTerminate) EnableSuddenTermination() @@ -41,10 +36,17 @@ messages -> WebProcessProxy LegacyReceiver { GetPlugins(bool refresh) -> (Vector<WebCore::PluginInfo> plugins, Vector<WebCore::PluginInfo> applicationPlugins) GetPluginProcessConnection(uint64_t pluginProcessToken) -> (IPC::Attachment connectionHandle, bool supportsAsynchronousInitialization) Delayed #endif -#if ENABLE(NETWORK_PROCESS) GetNetworkProcessConnection() -> (IPC::Attachment connectionHandle) Delayed -#endif #if ENABLE(DATABASE_PROCESS) GetDatabaseProcessConnection() -> (IPC::Attachment connectionHandle) Delayed #endif + ProcessReadyToSuspend() + DidCancelProcessSuspension() + + SetIsHoldingLockedFiles(bool isHoldingLockedFiles) + + RetainIconForPageURL(String pageURL) + ReleaseIconForPageURL(String pageURL) + + DidReceiveMainThreadPing() } diff --git a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.cpp b/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.cpp deleted file mode 100644 index 7691812fd..000000000 --- a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebResourceCacheManagerProxy.h" - -#include "ImmutableDictionary.h" -#include "SecurityOriginData.h" -#include "WebContext.h" -#include "WebResourceCacheManagerMessages.h" -#include "WebResourceCacheManagerProxyMessages.h" -#include "WebSecurityOrigin.h" - -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessMessages.h" -#endif - -using namespace WebCore; - -namespace WebKit { - -const char* WebResourceCacheManagerProxy::supplementName() -{ - return "WebResourceCacheManagerProxy"; -} - -PassRefPtr<WebResourceCacheManagerProxy> WebResourceCacheManagerProxy::create(WebContext* webContext) -{ - return adoptRef(new WebResourceCacheManagerProxy(webContext)); -} - -WebResourceCacheManagerProxy::WebResourceCacheManagerProxy(WebContext* webContext) - : WebContextSupplement(webContext) -{ - WebContextSupplement::context()->addMessageReceiver(Messages::WebResourceCacheManagerProxy::messageReceiverName(), *this); -} - -WebResourceCacheManagerProxy::~WebResourceCacheManagerProxy() -{ -} - -// WebContextSupplement - -void WebResourceCacheManagerProxy::contextDestroyed() -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -void WebResourceCacheManagerProxy::processDidClose(WebProcessProxy*) -{ - invalidateCallbackMap(m_arrayCallbacks); -} - -bool WebResourceCacheManagerProxy::shouldTerminate(WebProcessProxy*) const -{ - return m_arrayCallbacks.isEmpty(); -} - -void WebResourceCacheManagerProxy::refWebContextSupplement() -{ - API::Object::ref(); -} - -void WebResourceCacheManagerProxy::derefWebContextSupplement() -{ - API::Object::deref(); -} - -void WebResourceCacheManagerProxy::getCacheOrigins(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> When multi-process is enabled, we need to aggregate the callback data from all processes. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebResourceCacheManager::GetCacheOrigins(callbackID)); -} - -void WebResourceCacheManagerProxy::didGetCacheOrigins(const Vector<SecurityOriginData>& origins, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - performAPICallbackWithSecurityOriginDataVector(origins, callback.get()); -} - -void WebResourceCacheManagerProxy::clearCacheForOrigin(WebSecurityOrigin* origin, ResourceCachesToClear cachesToClear) -{ - SecurityOriginData securityOrigin; - securityOrigin.protocol = origin->protocol(); - securityOrigin.host = origin->host(); - securityOrigin.port = origin->port(); - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> There is no need to relaunch all processes. One process to take care of persistent cache is enough. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebResourceCacheManager::ClearCacheForOrigin(securityOrigin, cachesToClear)); -} - -void WebResourceCacheManagerProxy::clearCacheForAllOrigins(ResourceCachesToClear cachesToClear) -{ -#if ENABLE(NETWORK_PROCESS) - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::NetworkProcess::ClearCacheForAllOrigins(cachesToClear)); -#endif - - // FIXME (Multi-WebProcess): <rdar://problem/12239765> There is no need to relaunch all processes. One process to take care of persistent cache is enough. - context()->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebResourceCacheManager::ClearCacheForAllOrigins(cachesToClear)); -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.h b/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.h deleted file mode 100644 index e3f520a91..000000000 --- a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebResourceCacheManagerProxy_h -#define WebResourceCacheManagerProxy_h - -#include "APIObject.h" -#include "Arguments.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "ResourceCachesToClear.h" -#include "WebContextSupplement.h" -#include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> - -namespace WebKit { - -struct SecurityOriginData; -class WebContext; -class WebProcessProxy; -class WebSecurityOrigin; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebResourceCacheManagerProxy : public API::ObjectImpl<API::Object::Type::CacheManager>, public WebContextSupplement, private IPC::MessageReceiver { -public: - static const char* supplementName(); - - static PassRefPtr<WebResourceCacheManagerProxy> create(WebContext*); - virtual ~WebResourceCacheManagerProxy(); - - void getCacheOrigins(PassRefPtr<ArrayCallback>); - void clearCacheForOrigin(WebSecurityOrigin*, ResourceCachesToClear); - void clearCacheForAllOrigins(ResourceCachesToClear); - - using API::Object::ref; - using API::Object::deref; - -private: - explicit WebResourceCacheManagerProxy(WebContext*); - - // WebContextSupplement - virtual void contextDestroyed() override; - virtual void processDidClose(WebProcessProxy*) override; - virtual bool shouldTerminate(WebProcessProxy*) const override; - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; - - // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; - - // Message handlers. - void didGetCacheOrigins(const Vector<SecurityOriginData>& originIdentifiers, uint64_t callbackID); - - HashMap<uint64_t, RefPtr<ArrayCallback>> m_arrayCallbacks; -}; - -} // namespace WebKit - -#endif // DatabaseManagerProxy_h diff --git a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.messages.in deleted file mode 100644 index c1e73a9af..000000000 --- a/Source/WebKit2/UIProcess/WebResourceCacheManagerProxy.messages.in +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2011 Apple Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -messages -> WebResourceCacheManagerProxy { - DidGetCacheOrigins(Vector<WebKit::SecurityOriginData> originIdentifiers, uint64_t callbackID) -} diff --git a/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp new file mode 100644 index 000000000..ddc8cc306 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebResourceLoadStatisticsManager.h" + +#include "Logging.h" +#include "WebResourceLoadStatisticsStore.h" +#include <WebCore/ResourceLoadObserver.h> +#include <WebCore/URL.h> + +using namespace WebCore; + +namespace WebKit { + +void WebResourceLoadStatisticsManager::setPrevalentResource(const String& hostName, bool value) +{ + if (value) + WebCore::ResourceLoadObserver::sharedObserver().setPrevalentResource(URL(URL(), hostName)); + else + WebCore::ResourceLoadObserver::sharedObserver().clearPrevalentResource(URL(URL(), hostName)); +} + +bool WebResourceLoadStatisticsManager::isPrevalentResource(const String& hostName) +{ + return WebCore::ResourceLoadObserver::sharedObserver().isPrevalentResource(URL(URL(), hostName)); +} + +void WebResourceLoadStatisticsManager::setHasHadUserInteraction(const String& hostName, bool value) +{ + if (value) + WebCore::ResourceLoadObserver::sharedObserver().logUserInteraction(URL(URL(), hostName)); + else + WebCore::ResourceLoadObserver::sharedObserver().clearUserInteraction(URL(URL(), hostName)); +} + +bool WebResourceLoadStatisticsManager::hasHadUserInteraction(const String& hostName) +{ + return WebCore::ResourceLoadObserver::sharedObserver().hasHadUserInteraction(URL(URL(), hostName)); +} + +void WebResourceLoadStatisticsManager::setTimeToLiveUserInteraction(double seconds) +{ + WebCore::ResourceLoadObserver::sharedObserver().setTimeToLiveUserInteraction(seconds); +} + +void WebResourceLoadStatisticsManager::fireDataModificationHandler() +{ + WebCore::ResourceLoadObserver::sharedObserver().fireDataModificationHandler(); +} + +void WebResourceLoadStatisticsManager::setNotifyPagesWhenDataRecordsWereScanned(bool value) +{ + WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(value); +} + +void WebResourceLoadStatisticsManager::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) +{ + WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(value); +} + +void WebResourceLoadStatisticsManager::setMinimumTimeBetweeenDataRecordsRemoval(double seconds) +{ + WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(seconds); +} + +void WebResourceLoadStatisticsManager::resetToConsistentState() +{ + WebCore::ResourceLoadObserver::sharedObserver().setTimeToLiveUserInteraction(2592000); + WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(false); + WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(true); + WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(60); + auto store = WebCore::ResourceLoadObserver::sharedObserver().statisticsStore(); + if (store) + store->clear(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebKeyValueStorageManager.h b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h index 3e15f9b4c..0e8102fc7 100644 --- a/Source/WebKit2/UIProcess/WebKeyValueStorageManager.h +++ b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsManager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,43 +23,34 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebKeyValueStorageManager_h -#define WebKeyValueStorageManager_h +#pragma once #include "APIObject.h" -#include "GenericCallback.h" -#include "MessageReceiver.h" -#include "WebContextSupplement.h" -#include <wtf/PassRefPtr.h> + #include <wtf/RefPtr.h> -#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace WebKit { -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebKeyValueStorageManager : public API::ObjectImpl<API::Object::Type::KeyValueStorageManager>, public WebContextSupplement { +class WebResourceLoadStatisticsManager : public API::ObjectImpl<API::Object::Type::WebResourceLoadStatisticsManager> { public: - static const char* supplementName(); - - static PassRefPtr<WebKeyValueStorageManager> create(WebContext*); - virtual ~WebKeyValueStorageManager(); - - void getKeyValueStorageOrigins(PassRefPtr<ArrayCallback>); - void deleteEntriesForOrigin(WebSecurityOrigin*); - void deleteAllEntries(); - - using API::Object::ref; - using API::Object::deref; + static Ref<WebResourceLoadStatisticsManager> create() + { + return adoptRef(*new WebResourceLoadStatisticsManager()); + } + static void setPrevalentResource(const String& hostName, bool value); + static bool isPrevalentResource(const String& hostName); + static void setHasHadUserInteraction(const String& hostName, bool value); + static bool hasHadUserInteraction(const String& hostName); + static void setTimeToLiveUserInteraction(double seconds); + static void setReducedTimestampResolution(double seconds); + static void fireDataModificationHandler(); + static void setNotifyPagesWhenDataRecordsWereScanned(bool); + static void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value); + static void setMinimumTimeBetweeenDataRecordsRemoval(double seconds); + static void resetToConsistentState(); private: - explicit WebKeyValueStorageManager(WebContext*); - - // WebContextSupplement - virtual void refWebContextSupplement() override; - virtual void derefWebContextSupplement() override; }; } // namespace WebKit - -#endif // WebKeyValueStorageManager_h diff --git a/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp new file mode 100644 index 000000000..7871acf9f --- /dev/null +++ b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebResourceLoadStatisticsStore.h" + +#include "WebProcessMessages.h" +#include "WebProcessPool.h" +#include "WebProcessProxy.h" +#include "WebResourceLoadStatisticsStoreMessages.h" +#include "WebsiteDataFetchOption.h" +#include "WebsiteDataType.h" +#include <WebCore/KeyedCoding.h> +#include <WebCore/ResourceLoadObserver.h> +#include <WebCore/ResourceLoadStatistics.h> +#include <wtf/CurrentTime.h> +#include <wtf/MainThread.h> +#include <wtf/MathExtras.h> +#include <wtf/RunLoop.h> +#include <wtf/threads/BinarySemaphore.h> + +using namespace WebCore; + +namespace WebKit { + +static const auto featureVectorLengthThreshold = 3; +static auto minimumTimeBetweeenDataRecordsRemoval = 60; +static OptionSet<WebKit::WebsiteDataType> dataTypesToRemove; +static auto notifyPages = false; +static auto shouldClassifyResourcesBeforeDataRecordsRemoval = true; + +Ref<WebResourceLoadStatisticsStore> WebResourceLoadStatisticsStore::create(const String& resourceLoadStatisticsDirectory) +{ + return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory)); +} + +WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory) + : m_resourceLoadStatisticsStore(ResourceLoadStatisticsStore::create()) + , m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue")) + , m_storagePath(resourceLoadStatisticsDirectory) +{ +} + +WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore() +{ +} + +void WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(bool always) +{ + notifyPages = always; +} + +void WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) +{ + shouldClassifyResourcesBeforeDataRecordsRemoval = value; +} + +void WebResourceLoadStatisticsStore::setMinimumTimeBetweeenDataRecordsRemoval(double seconds) +{ + if (seconds >= 0) + minimumTimeBetweeenDataRecordsRemoval = seconds; +} + +bool WebResourceLoadStatisticsStore::hasPrevalentResourceCharacteristics(const ResourceLoadStatistics& resourceStatistic) +{ + auto subresourceUnderTopFrameOriginsCount = resourceStatistic.subresourceUnderTopFrameOrigins.size(); + auto subresourceUniqueRedirectsToCount = resourceStatistic.subresourceUniqueRedirectsTo.size(); + auto subframeUnderTopFrameOriginsCount = resourceStatistic.subframeUnderTopFrameOrigins.size(); + + if (!subresourceUnderTopFrameOriginsCount + && !subresourceUniqueRedirectsToCount + && !subframeUnderTopFrameOriginsCount) + return false; + + if (subresourceUnderTopFrameOriginsCount > featureVectorLengthThreshold + || subresourceUniqueRedirectsToCount > featureVectorLengthThreshold + || subframeUnderTopFrameOriginsCount > featureVectorLengthThreshold) + return true; + + // The resource is considered prevalent if the feature vector + // is longer than the threshold. + // Vector length for n dimensions is sqrt(a^2 + (...) + n^2). + double vectorLength = 0; + vectorLength += subresourceUnderTopFrameOriginsCount * subresourceUnderTopFrameOriginsCount; + vectorLength += subresourceUniqueRedirectsToCount * subresourceUniqueRedirectsToCount; + vectorLength += subframeUnderTopFrameOriginsCount * subframeUnderTopFrameOriginsCount; + + ASSERT(vectorLength > 0); + + return sqrt(vectorLength) > featureVectorLengthThreshold; +} + +void WebResourceLoadStatisticsStore::classifyResource(ResourceLoadStatistics& resourceStatistic) +{ + if (!resourceStatistic.isPrevalentResource && hasPrevalentResourceCharacteristics(resourceStatistic)) { + resourceStatistic.isPrevalentResource = true; + } +} + +void WebResourceLoadStatisticsStore::removeDataRecords() +{ + if (m_dataRecordsRemovalPending) + return; + + Vector<String> prevalentResourceDomains = coreStore().prevalentResourceDomainsWithoutUserInteraction(); + if (!prevalentResourceDomains.size()) + return; + + double now = currentTime(); + if (m_lastTimeDataRecordsWereRemoved + && now < m_lastTimeDataRecordsWereRemoved + minimumTimeBetweeenDataRecordsRemoval) + return; + + m_dataRecordsRemovalPending = true; + m_lastTimeDataRecordsWereRemoved = now; + + if (dataTypesToRemove.isEmpty()) { + dataTypesToRemove |= WebsiteDataType::Cookies; + dataTypesToRemove |= WebsiteDataType::DiskCache; + dataTypesToRemove |= WebsiteDataType::MemoryCache; + dataTypesToRemove |= WebsiteDataType::OfflineWebApplicationCache; + dataTypesToRemove |= WebsiteDataType::SessionStorage; + dataTypesToRemove |= WebsiteDataType::LocalStorage; + dataTypesToRemove |= WebsiteDataType::WebSQLDatabases; + dataTypesToRemove |= WebsiteDataType::IndexedDBDatabases; + dataTypesToRemove |= WebsiteDataType::MediaKeys; + dataTypesToRemove |= WebsiteDataType::HSTSCache; + dataTypesToRemove |= WebsiteDataType::SearchFieldRecentSearches; +#if ENABLE(NETSCAPE_PLUGIN_API) + dataTypesToRemove |= WebsiteDataType::PlugInData; +#endif +#if ENABLE(MEDIA_STREAM) + dataTypesToRemove |= WebsiteDataType::MediaDeviceIdentifier; +#endif + } + + // Switch to the main thread to get the default website data store + RunLoop::main().dispatch([prevalentResourceDomains = WTFMove(prevalentResourceDomains), this] () mutable { + WebProcessProxy::deleteWebsiteDataForTopPrivatelyOwnedDomainsInAllPersistentDataStores(dataTypesToRemove, prevalentResourceDomains, notifyPages, [this]() mutable { + m_dataRecordsRemovalPending = false; + }); + }); +} + +void WebResourceLoadStatisticsStore::processStatisticsAndDataRecords() +{ + if (shouldClassifyResourcesBeforeDataRecordsRemoval) { + coreStore().processStatistics([this] (ResourceLoadStatistics& resourceStatistic) { + classifyResource(resourceStatistic); + }); + } + removeDataRecords(); + + auto encoder = coreStore().createEncoderFromData(); + + writeEncoderToDisk(*encoder.get(), "full_browsing_session"); +} + +void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(const Vector<WebCore::ResourceLoadStatistics>& origins) +{ + coreStore().mergeStatistics(origins); + processStatisticsAndDataRecords(); +} + +void WebResourceLoadStatisticsStore::setResourceLoadStatisticsEnabled(bool enabled) +{ + if (enabled == m_resourceLoadStatisticsEnabled) + return; + + m_resourceLoadStatisticsEnabled = enabled; + + readDataFromDiskIfNeeded(); +} + +bool WebResourceLoadStatisticsStore::resourceLoadStatisticsEnabled() const +{ + return m_resourceLoadStatisticsEnabled; +} + + +void WebResourceLoadStatisticsStore::registerSharedResourceLoadObserver() +{ + ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceLoadStatisticsStore.copyRef()); + m_resourceLoadStatisticsStore->setNotificationCallback([this] { + if (m_resourceLoadStatisticsStore->isEmpty()) + return; + processStatisticsAndDataRecords(); + }); +} + +void WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded() +{ + if (!m_resourceLoadStatisticsEnabled) + return; + + m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] { + coreStore().clear(); + + auto decoder = createDecoderFromDisk("full_browsing_session"); + if (!decoder) + return; + + coreStore().readDataFromDecoder(*decoder); + }); +} + +void WebResourceLoadStatisticsStore::processWillOpenConnection(WebProcessProxy&, IPC::Connection& connection) +{ + connection.addWorkQueueMessageReceiver(Messages::WebResourceLoadStatisticsStore::messageReceiverName(), m_statisticsQueue.get(), this); +} + +void WebResourceLoadStatisticsStore::processDidCloseConnection(WebProcessProxy&, IPC::Connection& connection) +{ + connection.removeWorkQueueMessageReceiver(Messages::WebResourceLoadStatisticsStore::messageReceiverName()); +} + +void WebResourceLoadStatisticsStore::applicationWillTerminate() +{ + BinarySemaphore semaphore; + m_statisticsQueue->dispatch([this, &semaphore] { + // Make sure any ongoing work in our queue is finished before we terminate. + semaphore.signal(); + }); + semaphore.wait(WallTime::infinity()); +} + +String WebResourceLoadStatisticsStore::persistentStoragePath(const String& label) const +{ + if (m_storagePath.isEmpty()) + return emptyString(); + + // TODO Decide what to call this file + return pathByAppendingComponent(m_storagePath, label + "_resourceLog.plist"); +} + +void WebResourceLoadStatisticsStore::writeEncoderToDisk(KeyedEncoder& encoder, const String& label) const +{ + RefPtr<SharedBuffer> rawData = encoder.finishEncoding(); + if (!rawData) + return; + + String resourceLog = persistentStoragePath(label); + if (resourceLog.isEmpty()) + return; + + if (!m_storagePath.isEmpty()) + makeAllDirectories(m_storagePath); + + auto handle = openFile(resourceLog, OpenForWrite); + if (!handle) + return; + + int64_t writtenBytes = writeToFile(handle, rawData->data(), rawData->size()); + closeFile(handle); + + if (writtenBytes != static_cast<int64_t>(rawData->size())) + WTFLogAlways("WebResourceLoadStatisticsStore: We only wrote %d out of %d bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size()); +} + +std::unique_ptr<KeyedDecoder> WebResourceLoadStatisticsStore::createDecoderFromDisk(const String& label) const +{ + String resourceLog = persistentStoragePath(label); + if (resourceLog.isEmpty()) + return nullptr; + + RefPtr<SharedBuffer> rawData = SharedBuffer::createWithContentsOfFile(resourceLog); + if (!rawData) + return nullptr; + + return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(rawData->data()), rawData->size()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h new file mode 100644 index 000000000..5e4900764 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2016-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebResourceLoadStatisticsStore_h +#define WebResourceLoadStatisticsStore_h + +#include "APIObject.h" +#include "Connection.h" +#include "WebsiteDataRecord.h" +#include <WebCore/ResourceLoadStatisticsStore.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WTF { +class WorkQueue; +} + +namespace WebCore { +class KeyedDecoder; +class KeyedEncoder; +struct ResourceLoadStatistics; +} + +namespace WebKit { + +class WebProcessPool; +class WebProcessProxy; + +class WebResourceLoadStatisticsStore : public IPC::Connection::WorkQueueMessageReceiver { +public: + static Ref<WebResourceLoadStatisticsStore> create(const String&); + static void setNotifyPagesWhenDataRecordsWereScanned(bool); + static void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool); + static void setMinimumTimeBetweeenDataRecordsRemoval(double); + virtual ~WebResourceLoadStatisticsStore(); + + void setResourceLoadStatisticsEnabled(bool); + bool resourceLoadStatisticsEnabled() const; + void registerSharedResourceLoadObserver(); + + void resourceLoadStatisticsUpdated(const Vector<WebCore::ResourceLoadStatistics>& origins); + + void processWillOpenConnection(WebProcessProxy&, IPC::Connection&); + void processDidCloseConnection(WebProcessProxy&, IPC::Connection&); + void applicationWillTerminate(); + + void readDataFromDiskIfNeeded(); + + WebCore::ResourceLoadStatisticsStore& coreStore() { return m_resourceLoadStatisticsStore.get(); } + const WebCore::ResourceLoadStatisticsStore& coreStore() const { return m_resourceLoadStatisticsStore.get(); } + +private: + explicit WebResourceLoadStatisticsStore(const String&); + + void processStatisticsAndDataRecords(); + + bool hasPrevalentResourceCharacteristics(const WebCore::ResourceLoadStatistics&); + void classifyResource(WebCore::ResourceLoadStatistics&); + void removeDataRecords(); + + String persistentStoragePath(const String& label) const; + + // IPC::MessageReceiver + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; + + void writeEncoderToDisk(WebCore::KeyedEncoder&, const String& label) const; + std::unique_ptr<WebCore::KeyedDecoder> createDecoderFromDisk(const String& label) const; + + Ref<WebCore::ResourceLoadStatisticsStore> m_resourceLoadStatisticsStore; + Ref<WTF::WorkQueue> m_statisticsQueue; + String m_storagePath; + bool m_resourceLoadStatisticsEnabled { false }; + + double m_lastTimeDataRecordsWereRemoved { 0 }; + bool m_dataRecordsRemovalPending { false }; +}; + +} // namespace WebKit + +#endif // WebResourceLoadStatisticsStore_h diff --git a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in index 13a72cf5c..eb8582ded 100644 --- a/Source/WebKit2/UIProcess/WebMediaCacheManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in @@ -1,4 +1,4 @@ -# Copyright (C) 2011 Apple Inc. All rights reserved. +# Copyright (C) 2016 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -20,6 +20,6 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -messages -> WebMediaCacheManagerProxy { - DidGetHostnamesWithMediaCache(Vector<String> hostnames, uint64_t callbackID); +messages -> WebResourceLoadStatisticsStore { + ResourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics> origins) } diff --git a/Source/WebKit2/UIProcess/WebTextChecker.cpp b/Source/WebKit2/UIProcess/WebTextChecker.cpp index 934c58941..8a85434ea 100644 --- a/Source/WebKit2/UIProcess/WebTextChecker.cpp +++ b/Source/WebKit2/UIProcess/WebTextChecker.cpp @@ -28,12 +28,12 @@ #include "TextChecker.h" #include "WKAPICast.h" -#include "WebContext.h" +#include "WebProcessPool.h" #include <wtf/RefPtr.h> namespace WebKit { -WebTextChecker* WebTextChecker::shared() +WebTextChecker* WebTextChecker::singleton() { static WebTextChecker* textChecker = adoptRef(new WebTextChecker).leakRef(); return textChecker; @@ -50,7 +50,7 @@ void WebTextChecker::setClient(const WKTextCheckerClientBase* client) static void updateStateForAllContexts() { - const Vector<WebContext*>& contexts = WebContext::allContexts(); + const Vector<WebProcessPool*>& contexts = WebProcessPool::allProcessPools(); for (size_t i = 0; i < contexts.size(); ++i) contexts[i]->textCheckerStateChanged(); } diff --git a/Source/WebKit2/UIProcess/WebTextChecker.h b/Source/WebKit2/UIProcess/WebTextChecker.h index 359e81ee5..7c945c726 100644 --- a/Source/WebKit2/UIProcess/WebTextChecker.h +++ b/Source/WebKit2/UIProcess/WebTextChecker.h @@ -37,7 +37,7 @@ class WebPageProxy; class WebTextChecker : public API::ObjectImpl<API::Object::Type::TextChecker> { public: - static WebTextChecker* shared(); + static WebTextChecker* singleton(); void setClient(const WKTextCheckerClientBase*); WebTextCheckerClient& client() { return m_client; } diff --git a/Source/WebKit2/UIProcess/WebUIClient.cpp b/Source/WebKit2/UIProcess/WebUIClient.cpp deleted file mode 100644 index 513889c3f..000000000 --- a/Source/WebKit2/UIProcess/WebUIClient.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebUIClient.h" - -#include "APINumber.h" -#include "ImmutableDictionary.h" -#include "NativeWebKeyboardEvent.h" -#include "NativeWebWheelEvent.h" -#include "NotificationPermissionRequest.h" -#include "PluginInformation.h" -#include "WKAPICast.h" -#include "WebColorPickerResultListenerProxy.h" -#include "WebOpenPanelResultListenerProxy.h" -#include "WebPageProxy.h" -#include <WebCore/FloatRect.h> -#include <WebCore/IntSize.h> -#include <WebCore/WindowFeatures.h> -#include <string.h> -#include <wtf/text/WTFString.h> - -using namespace WebCore; - -namespace WebKit { - -PassRefPtr<WebPageProxy> WebUIClient::createNewPage(WebPageProxy* page, const ResourceRequest& resourceRequest, const WindowFeatures& windowFeatures, WebEvent::Modifiers modifiers, WebMouseEvent::Button button) -{ - if (!m_client.base.version && !m_client.createNewPage_deprecatedForUseWithV0) - return 0; - - if (m_client.base.version > 0 && !m_client.createNewPage) - return 0; - - ImmutableDictionary::MapType map; - if (windowFeatures.xSet) - map.set("x", API::Double::create(windowFeatures.x)); - if (windowFeatures.ySet) - map.set("y", API::Double::create(windowFeatures.y)); - if (windowFeatures.widthSet) - map.set("width", API::Double::create(windowFeatures.width)); - if (windowFeatures.heightSet) - map.set("height", API::Double::create(windowFeatures.height)); - map.set("menuBarVisible", API::Boolean::create(windowFeatures.menuBarVisible)); - map.set("statusBarVisible", API::Boolean::create(windowFeatures.statusBarVisible)); - map.set("toolBarVisible", API::Boolean::create(windowFeatures.toolBarVisible)); - map.set("locationBarVisible", API::Boolean::create(windowFeatures.locationBarVisible)); - map.set("scrollbarsVisible", API::Boolean::create(windowFeatures.scrollbarsVisible)); - map.set("resizable", API::Boolean::create(windowFeatures.resizable)); - map.set("fullscreen", API::Boolean::create(windowFeatures.fullscreen)); - map.set("dialog", API::Boolean::create(windowFeatures.dialog)); - RefPtr<ImmutableDictionary> featuresMap = ImmutableDictionary::create(std::move(map)); - - if (!m_client.base.version) - return adoptRef(toImpl(m_client.createNewPage_deprecatedForUseWithV0(toAPI(page), toAPI(featuresMap.get()), toAPI(modifiers), toAPI(button), m_client.base.clientInfo))); - - RefPtr<API::URLRequest> request = API::URLRequest::create(resourceRequest); - return adoptRef(toImpl(m_client.createNewPage(toAPI(page), toAPI(request.get()), toAPI(featuresMap.get()), toAPI(modifiers), toAPI(button), m_client.base.clientInfo))); -} - -void WebUIClient::showPage(WebPageProxy* page) -{ - if (!m_client.showPage) - return; - - m_client.showPage(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::close(WebPageProxy* page) -{ - if (!m_client.close) - return; - - m_client.close(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::takeFocus(WebPageProxy* page, WKFocusDirection direction) -{ - if (!m_client.takeFocus) - return; - - m_client.takeFocus(toAPI(page), direction, m_client.base.clientInfo); -} - -void WebUIClient::focus(WebPageProxy* page) -{ - if (!m_client.focus) - return; - - m_client.focus(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::unfocus(WebPageProxy* page) -{ - if (!m_client.unfocus) - return; - - m_client.unfocus(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::runJavaScriptAlert(WebPageProxy* page, const String& message, WebFrameProxy* frame) -{ - if (!m_client.runJavaScriptAlert) - return; - - m_client.runJavaScriptAlert(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); -} - -bool WebUIClient::runJavaScriptConfirm(WebPageProxy* page, const String& message, WebFrameProxy* frame) -{ - if (!m_client.runJavaScriptConfirm) - return false; - - return m_client.runJavaScriptConfirm(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); -} - -String WebUIClient::runJavaScriptPrompt(WebPageProxy* page, const String& message, const String& defaultValue, WebFrameProxy* frame) -{ - if (!m_client.runJavaScriptPrompt) - return String(); - - API::String* string = toImpl(m_client.runJavaScriptPrompt(toAPI(page), toAPI(message.impl()), toAPI(defaultValue.impl()), toAPI(frame), m_client.base.clientInfo)); - if (!string) - return String(); - - String result = string->string(); - string->deref(); - - return result; -} - -void WebUIClient::setStatusText(WebPageProxy* page, const String& text) -{ - if (!m_client.setStatusText) - return; - - m_client.setStatusText(toAPI(page), toAPI(text.impl()), m_client.base.clientInfo); -} - -void WebUIClient::mouseDidMoveOverElement(WebPageProxy* page, const WebHitTestResult::Data& data, WebEvent::Modifiers modifiers, API::Object* userData) -{ - if (!m_client.mouseDidMoveOverElement && !m_client.mouseDidMoveOverElement_deprecatedForUseWithV0) - return; - - if (m_client.base.version > 0 && !m_client.mouseDidMoveOverElement) - return; - - if (!m_client.base.version) { - m_client.mouseDidMoveOverElement_deprecatedForUseWithV0(toAPI(page), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo); - return; - } - - RefPtr<WebHitTestResult> webHitTestResult = WebHitTestResult::create(data); - m_client.mouseDidMoveOverElement(toAPI(page), toAPI(webHitTestResult.get()), toAPI(modifiers), toAPI(userData), m_client.base.clientInfo); -} - -#if ENABLE(NETSCAPE_PLUGIN_API) -void WebUIClient::unavailablePluginButtonClicked(WebPageProxy* page, WKPluginUnavailabilityReason pluginUnavailabilityReason, ImmutableDictionary* pluginInformation) -{ - if (pluginUnavailabilityReason == kWKPluginUnavailabilityReasonPluginMissing) { - if (m_client.missingPluginButtonClicked_deprecatedForUseWithV0) - m_client.missingPluginButtonClicked_deprecatedForUseWithV0( - toAPI(page), - toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), - toAPI(pluginInformation->get<API::String>(pluginInformationPluginURLKey())), - toAPI(pluginInformation->get<API::String>(pluginInformationPluginspageAttributeURLKey())), - m_client.base.clientInfo); - } - - if (m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1) - m_client.unavailablePluginButtonClicked_deprecatedForUseWithV1( - toAPI(page), - pluginUnavailabilityReason, - toAPI(pluginInformation->get<API::String>(pluginInformationMIMETypeKey())), - toAPI(pluginInformation->get<API::String>(pluginInformationPluginURLKey())), - toAPI(pluginInformation->get<API::String>(pluginInformationPluginspageAttributeURLKey())), - m_client.base.clientInfo); - - if (m_client.unavailablePluginButtonClicked) - m_client.unavailablePluginButtonClicked( - toAPI(page), - pluginUnavailabilityReason, - toAPI(pluginInformation), - m_client.base.clientInfo); -} -#endif // ENABLE(NETSCAPE_PLUGIN_API) - -bool WebUIClient::implementsDidNotHandleKeyEvent() const -{ - return m_client.didNotHandleKeyEvent; -} - -void WebUIClient::didNotHandleKeyEvent(WebPageProxy* page, const NativeWebKeyboardEvent& event) -{ - if (!m_client.didNotHandleKeyEvent) - return; - m_client.didNotHandleKeyEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo); -} - -bool WebUIClient::implementsDidNotHandleWheelEvent() const -{ - return m_client.didNotHandleWheelEvent; -} - -void WebUIClient::didNotHandleWheelEvent(WebPageProxy* page, const NativeWebWheelEvent& event) -{ - if (!m_client.didNotHandleWheelEvent) - return; - m_client.didNotHandleWheelEvent(toAPI(page), event.nativeEvent(), m_client.base.clientInfo); -} - -bool WebUIClient::toolbarsAreVisible(WebPageProxy* page) -{ - if (!m_client.toolbarsAreVisible) - return true; - return m_client.toolbarsAreVisible(toAPI(page), m_client.base.clientInfo); - -} -void WebUIClient::setToolbarsAreVisible(WebPageProxy* page, bool visible) -{ - if (!m_client.setToolbarsAreVisible) - return; - m_client.setToolbarsAreVisible(toAPI(page), visible, m_client.base.clientInfo); -} - -bool WebUIClient::menuBarIsVisible(WebPageProxy* page) -{ - if (!m_client.menuBarIsVisible) - return true; - return m_client.menuBarIsVisible(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::setMenuBarIsVisible(WebPageProxy* page, bool visible) -{ - if (!m_client.setMenuBarIsVisible) - return; - m_client.setMenuBarIsVisible(toAPI(page), visible, m_client.base.clientInfo); -} - -bool WebUIClient::statusBarIsVisible(WebPageProxy* page) -{ - if (!m_client.statusBarIsVisible) - return true; - return m_client.statusBarIsVisible(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::setStatusBarIsVisible(WebPageProxy* page, bool visible) -{ - if (!m_client.setStatusBarIsVisible) - return; - m_client.setStatusBarIsVisible(toAPI(page), visible, m_client.base.clientInfo); -} - -bool WebUIClient::isResizable(WebPageProxy* page) -{ - if (!m_client.isResizable) - return true; - return m_client.isResizable(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::setIsResizable(WebPageProxy* page, bool resizable) -{ - if (!m_client.setIsResizable) - return; - m_client.setIsResizable(toAPI(page), resizable, m_client.base.clientInfo); -} - -void WebUIClient::setWindowFrame(WebPageProxy* page, const FloatRect& frame) -{ - if (!m_client.setWindowFrame) - return; - - m_client.setWindowFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo); -} - -FloatRect WebUIClient::windowFrame(WebPageProxy* page) -{ - if (!m_client.getWindowFrame) - return FloatRect(); - - return toFloatRect(m_client.getWindowFrame(toAPI(page), m_client.base.clientInfo)); -} - -bool WebUIClient::canRunBeforeUnloadConfirmPanel() const -{ - return m_client.runBeforeUnloadConfirmPanel; -} - -bool WebUIClient::runBeforeUnloadConfirmPanel(WebPageProxy* page, const String& message, WebFrameProxy* frame) -{ - if (!m_client.runBeforeUnloadConfirmPanel) - return true; - - return m_client.runBeforeUnloadConfirmPanel(toAPI(page), toAPI(message.impl()), toAPI(frame), m_client.base.clientInfo); -} - -void WebUIClient::didDraw(WebPageProxy* page) -{ - if (!m_client.didDraw) - return; - - m_client.didDraw(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::pageDidScroll(WebPageProxy* page) -{ - if (!m_client.pageDidScroll) - return; - - m_client.pageDidScroll(toAPI(page), m_client.base.clientInfo); -} - -unsigned long long WebUIClient::exceededDatabaseQuota(WebPageProxy* page, WebFrameProxy* frame, WebSecurityOrigin* origin, const String& databaseName, const String& databaseDisplayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage) -{ - if (!m_client.exceededDatabaseQuota) - return currentQuota; - - return m_client.exceededDatabaseQuota(toAPI(page), toAPI(frame), toAPI(origin), toAPI(databaseName.impl()), toAPI(databaseDisplayName.impl()), currentQuota, currentOriginUsage, currentDatabaseUsage, expectedUsage, m_client.base.clientInfo); -} - -bool WebUIClient::runOpenPanel(WebPageProxy* page, WebFrameProxy* frame, WebOpenPanelParameters* parameters, WebOpenPanelResultListenerProxy* listener) -{ - if (!m_client.runOpenPanel) - return false; - - m_client.runOpenPanel(toAPI(page), toAPI(frame), toAPI(parameters), toAPI(listener), m_client.base.clientInfo); - return true; -} - -bool WebUIClient::decidePolicyForGeolocationPermissionRequest(WebPageProxy* page, WebFrameProxy* frame, WebSecurityOrigin* origin, GeolocationPermissionRequestProxy* permissionRequest) -{ - if (!m_client.decidePolicyForGeolocationPermissionRequest) - return false; - - m_client.decidePolicyForGeolocationPermissionRequest(toAPI(page), toAPI(frame), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo); - return true; -} - -bool WebUIClient::decidePolicyForNotificationPermissionRequest(WebPageProxy* page, WebSecurityOrigin* origin, NotificationPermissionRequest* permissionRequest) -{ - if (!m_client.decidePolicyForNotificationPermissionRequest) - return false; - - m_client.decidePolicyForNotificationPermissionRequest(toAPI(page), toAPI(origin), toAPI(permissionRequest), m_client.base.clientInfo); - return true; -} - -float WebUIClient::headerHeight(WebPageProxy* page, WebFrameProxy* frame) -{ - if (!m_client.headerHeight) - return 0; - - return m_client.headerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo); -} - -float WebUIClient::footerHeight(WebPageProxy* page, WebFrameProxy* frame) -{ - if (!m_client.footerHeight) - return 0; - - return m_client.footerHeight(toAPI(page), toAPI(frame), m_client.base.clientInfo); -} - -void WebUIClient::drawHeader(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) -{ - if (!m_client.drawHeader) - return; - - m_client.drawHeader(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo); -} - -void WebUIClient::drawFooter(WebPageProxy* page, WebFrameProxy* frame, const WebCore::FloatRect& rect) -{ - if (!m_client.drawFooter) - return; - - m_client.drawFooter(toAPI(page), toAPI(frame), toAPI(rect), m_client.base.clientInfo); -} - -void WebUIClient::printFrame(WebPageProxy* page, WebFrameProxy* frame) -{ - if (!m_client.printFrame) - return; - - m_client.printFrame(toAPI(page), toAPI(frame), m_client.base.clientInfo); -} - -bool WebUIClient::canRunModal() const -{ - return m_client.runModal; -} - -void WebUIClient::runModal(WebPageProxy* page) -{ - if (!m_client.runModal) - return; - - m_client.runModal(toAPI(page), m_client.base.clientInfo); -} - -void WebUIClient::saveDataToFileInDownloadsFolder(WebPageProxy* page, const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data* data) -{ - if (!m_client.saveDataToFileInDownloadsFolder) - return; - - m_client.saveDataToFileInDownloadsFolder(toAPI(page), toAPI(suggestedFilename.impl()), toAPI(mimeType.impl()), toURLRef(originatingURLString.impl()), toAPI(data), m_client.base.clientInfo); -} - -bool WebUIClient::shouldInterruptJavaScript(WebPageProxy* page) -{ - if (!m_client.shouldInterruptJavaScript) - return false; - - return m_client.shouldInterruptJavaScript(toAPI(page), m_client.base.clientInfo); -} - -#if ENABLE(INPUT_TYPE_COLOR) -bool WebUIClient::showColorPicker(WebPageProxy* page, const String& initialColor, WebColorPickerResultListenerProxy* listener) -{ - if (!m_client.showColorPicker) - return false; - - m_client.showColorPicker(toAPI(page), toAPI(initialColor.impl()), toAPI(listener), m_client.base.clientInfo); - return true; -} - -bool WebUIClient::hideColorPicker(WebPageProxy* page) -{ - if (!m_client.hideColorPicker) - return false; - - m_client.hideColorPicker(toAPI(page), m_client.base.clientInfo); - return true; -} -#endif - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebUIClient.h b/Source/WebKit2/UIProcess/WebUIClient.h deleted file mode 100644 index 27c6bde49..000000000 --- a/Source/WebKit2/UIProcess/WebUIClient.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebUIClient_h -#define WebUIClient_h - -#include "APIClient.h" -#include "WKPage.h" -#include "WebEvent.h" -#include "WebHitTestResult.h" -#include "WebOpenPanelParameters.h" -#include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> - -namespace API { -class Data; - -template<> struct ClientTraits<WKPageUIClientBase> { - typedef std::tuple<WKPageUIClientV0, WKPageUIClientV1, WKPageUIClientV2> Versions; -}; -} - -namespace WebCore { - class FloatRect; - class IntSize; - class ResourceRequest; - struct WindowFeatures; -} - -namespace WebKit { - -class GeolocationPermissionRequestProxy; -class ImmutableDictionary; -class NativeWebKeyboardEvent; -class NativeWebWheelEvent; -class NotificationPermissionRequest; -class WebColorPickerResultListenerProxy; -class WebFrameProxy; -class WebPageProxy; -class WebSecurityOrigin; -class WebOpenPanelResultListenerProxy; - -class WebUIClient : public API::Client<WKPageUIClientBase> { -public: - PassRefPtr<WebPageProxy> createNewPage(WebPageProxy*, const WebCore::ResourceRequest&, const WebCore::WindowFeatures&, WebEvent::Modifiers, WebMouseEvent::Button); - void showPage(WebPageProxy*); - void close(WebPageProxy*); - - void takeFocus(WebPageProxy*, WKFocusDirection); - void focus(WebPageProxy*); - void unfocus(WebPageProxy*); - - void runJavaScriptAlert(WebPageProxy*, const String&, WebFrameProxy*); - bool runJavaScriptConfirm(WebPageProxy*, const String&, WebFrameProxy*); - String runJavaScriptPrompt(WebPageProxy*, const String&, const String&, WebFrameProxy*); - - void setStatusText(WebPageProxy*, const String&); - void mouseDidMoveOverElement(WebPageProxy*, const WebHitTestResult::Data&, WebEvent::Modifiers, API::Object*); -#if ENABLE(NETSCAPE_PLUGIN_API) - void unavailablePluginButtonClicked(WebPageProxy*, WKPluginUnavailabilityReason, ImmutableDictionary*); -#endif // ENABLE(NETSCAPE_PLUGIN_API) - - bool implementsDidNotHandleKeyEvent() const; - void didNotHandleKeyEvent(WebPageProxy*, const NativeWebKeyboardEvent&); - - bool implementsDidNotHandleWheelEvent() const; - void didNotHandleWheelEvent(WebPageProxy*, const NativeWebWheelEvent&); - - bool toolbarsAreVisible(WebPageProxy*); - void setToolbarsAreVisible(WebPageProxy*, bool); - bool menuBarIsVisible(WebPageProxy*); - void setMenuBarIsVisible(WebPageProxy*, bool); - bool statusBarIsVisible(WebPageProxy*); - void setStatusBarIsVisible(WebPageProxy*, bool); - bool isResizable(WebPageProxy*); - void setIsResizable(WebPageProxy*, bool); - - void setWindowFrame(WebPageProxy*, const WebCore::FloatRect&); - WebCore::FloatRect windowFrame(WebPageProxy*); - - bool canRunBeforeUnloadConfirmPanel() const; - bool runBeforeUnloadConfirmPanel(WebPageProxy*, const String&, WebFrameProxy*); - - void didDraw(WebPageProxy*); - void pageDidScroll(WebPageProxy*); - - unsigned long long exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, WebSecurityOrigin*, const String& databaseName, const String& databaseDisplayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage); - - bool runOpenPanel(WebPageProxy*, WebFrameProxy*, WebOpenPanelParameters*, WebOpenPanelResultListenerProxy*); - bool decidePolicyForGeolocationPermissionRequest(WebPageProxy*, WebFrameProxy*, WebSecurityOrigin*, GeolocationPermissionRequestProxy*); - bool decidePolicyForNotificationPermissionRequest(WebPageProxy*, WebSecurityOrigin*, NotificationPermissionRequest*); - - // Printing. - float headerHeight(WebPageProxy*, WebFrameProxy*); - float footerHeight(WebPageProxy*, WebFrameProxy*); - void drawHeader(WebPageProxy*, WebFrameProxy*, const WebCore::FloatRect&); - void drawFooter(WebPageProxy*, WebFrameProxy*, const WebCore::FloatRect&); - void printFrame(WebPageProxy*, WebFrameProxy*); - - bool canRunModal() const; - void runModal(WebPageProxy*); - - void saveDataToFileInDownloadsFolder(WebPageProxy*, const String& suggestedFilename, const String& mimeType, const String& originatingURLString, API::Data*); - - bool shouldInterruptJavaScript(WebPageProxy*); - -#if ENABLE(INPUT_TYPE_COLOR) - bool showColorPicker(WebPageProxy*, const String&, WebColorPickerResultListenerProxy*); - bool hideColorPicker(WebPageProxy*); -#endif -}; - -} // namespace WebKit - -#endif // WebUIClient_h diff --git a/Source/WebKit2/UIProcess/WebVibrationProxy.cpp b/Source/WebKit2/UIProcess/WebVibrationProxy.cpp index 282257b03..48d290ce3 100644 --- a/Source/WebKit2/UIProcess/WebVibrationProxy.cpp +++ b/Source/WebKit2/UIProcess/WebVibrationProxy.cpp @@ -28,27 +28,27 @@ #if ENABLE(VIBRATION) -#include "WebContext.h" #include "WebPageProxy.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" #include "WebVibrationProxyMessages.h" namespace WebKit { -PassRefPtr<WebVibrationProxy> WebVibrationProxy::create(WebPageProxy* page) +Ref<WebVibrationProxy> WebVibrationProxy::create(WebPageProxy* page) { - return adoptRef(new WebVibrationProxy(page)); + return adoptRef(*new WebVibrationProxy(page)); } WebVibrationProxy::WebVibrationProxy(WebPageProxy* page) : m_page(page) { - m_page->process().context().addMessageReceiver(Messages::WebVibrationProxy::messageReceiverName(), m_page->pageID(), *this); + m_page->process().processPool().addMessageReceiver(Messages::WebVibrationProxy::messageReceiverName(), m_page->pageID(), *this); } WebVibrationProxy::~WebVibrationProxy() { - m_page->process().context().removeMessageReceiver(Messages::WebVibrationProxy::messageReceiverName(), m_page->pageID()); + m_page->process().processPool().removeMessageReceiver(Messages::WebVibrationProxy::messageReceiverName(), m_page->pageID()); } void WebVibrationProxy::invalidate() diff --git a/Source/WebKit2/UIProcess/WebVibrationProxy.h b/Source/WebKit2/UIProcess/WebVibrationProxy.h index 5f65be651..f6645a723 100644 --- a/Source/WebKit2/UIProcess/WebVibrationProxy.h +++ b/Source/WebKit2/UIProcess/WebVibrationProxy.h @@ -39,7 +39,7 @@ class WebPageProxy; class WebVibrationProxy : public API::ObjectImpl<API::Object::Type::Vibration>, private IPC::MessageReceiver { public: - static PassRefPtr<WebVibrationProxy> create(WebPageProxy*); + static Ref<WebVibrationProxy> create(WebPageProxy*); virtual ~WebVibrationProxy(); void invalidate(); @@ -50,7 +50,7 @@ private: explicit WebVibrationProxy(WebPageProxy*); // IPC::MessageReceiver - virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override; + void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; void vibrate(uint32_t vibrationTime); void cancelVibration(); diff --git a/Source/WebKit2/UIProcess/WebViewportAttributes.cpp b/Source/WebKit2/UIProcess/WebViewportAttributes.cpp new file mode 100644 index 000000000..64b4a7679 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebViewportAttributes.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebViewportAttributes.h" + +namespace WebKit { + +WebViewportAttributes::WebViewportAttributes(const WebCore::ViewportAttributes& attributes) + : m_attributes(attributes) +{ +} + +WebViewportAttributes::~WebViewportAttributes() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/WebViewportAttributes.h b/Source/WebKit2/UIProcess/WebViewportAttributes.h new file mode 100644 index 000000000..e3b16006c --- /dev/null +++ b/Source/WebKit2/UIProcess/WebViewportAttributes.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list Viewof conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebViewportAttributes_h +#define WebViewportAttributes_h + +#include "APIObject.h" +#include <WebCore/ViewportArguments.h> + +namespace WebKit { + +class WebViewportAttributes : public API::ObjectImpl<API::Object::Type::ViewportAttributes> { +public: + static Ref<WebViewportAttributes> create(const WebCore::ViewportAttributes& attributes) + { + return adoptRef(*new WebViewportAttributes(attributes)); + } + + virtual ~WebViewportAttributes(); + + const WebCore::ViewportAttributes& originalAttributes() const { return m_attributes; } + +private: + explicit WebViewportAttributes(const WebCore::ViewportAttributes&); + + WebCore::ViewportAttributes m_attributes; +}; + +} // namespace WebKit + +#endif // WebViewportAttributes_h diff --git a/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.cpp b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.cpp new file mode 100644 index 000000000..174a0b200 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebsiteDataRecord.h" + +#include <WebCore/LocalizedStrings.h> +#include <WebCore/PublicSuffix.h> +#include <WebCore/SecurityOrigin.h> + +#if PLATFORM(COCOA) +#import <WebCore/CFNetworkSPI.h> +#endif + +static String displayNameForLocalFiles() +{ + return WEB_UI_STRING("Local documents on your computer", "'Website' name displayed when local documents have stored local data"); +} + +namespace WebKit { + +String WebsiteDataRecord::displayNameForCookieHostName(const String& hostName) +{ +#if PLATFORM(COCOA) + if (hostName == String(kCFHTTPCookieLocalFileDomain)) + return displayNameForLocalFiles(); +#else + if (hostName == "localhost") + return hostName; +#endif + +#if ENABLE(PUBLIC_SUFFIX_LIST) + return WebCore::topPrivatelyControlledDomain(hostName.startsWith('.') ? hostName.substring(1) : hostName); +#endif + + return String(); +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +String WebsiteDataRecord::displayNameForPluginDataHostName(const String& hostName) +{ +#if ENABLE(PUBLIC_SUFFIX_LIST) + return WebCore::topPrivatelyControlledDomain(hostName); +#endif + + return String(); +} +#endif + +String WebsiteDataRecord::displayNameForOrigin(const WebCore::SecurityOriginData& securityOrigin) +{ + const auto& protocol = securityOrigin.protocol; + + if (protocol == "file") + return displayNameForLocalFiles(); + +#if ENABLE(PUBLIC_SUFFIX_LIST) + if (protocol == "http" || protocol == "https") + return WebCore::topPrivatelyControlledDomain(securityOrigin.host); +#endif + + return String(); +} + +void WebsiteDataRecord::add(WebsiteDataType type, const WebCore::SecurityOriginData& origin) +{ + types |= type; + + origins.add(origin); +} + +void WebsiteDataRecord::addCookieHostName(const String& hostName) +{ + types |= WebsiteDataType::Cookies; + + cookieHostNames.add(hostName); +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +void WebsiteDataRecord::addPluginDataHostName(const String& hostName) +{ + types |= WebsiteDataType::PlugInData; + + pluginDataHostNames.add(hostName); +} +#endif + +} diff --git a/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.h b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.h new file mode 100644 index 000000000..137fc1c31 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataRecord.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "WebsiteDataType.h" +#include <WebCore/SecurityOriginData.h> +#include <WebCore/SecurityOriginHash.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/OptionSet.h> +#include <wtf/Optional.h> +#include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class SecurityOrigin; +} + +namespace WebKit { + +struct WebsiteDataRecord { + static String displayNameForCookieHostName(const String& hostName); +#if ENABLE(NETSCAPE_PLUGIN_API) + static String displayNameForPluginDataHostName(const String& hostName); +#endif + static String displayNameForOrigin(const WebCore::SecurityOriginData&); + + void add(WebsiteDataType, const WebCore::SecurityOriginData&); + void addCookieHostName(const String& hostName); +#if ENABLE(NETSCAPE_PLUGIN_API) + void addPluginDataHostName(const String& hostName); +#endif + + String displayName; + OptionSet<WebsiteDataType> types; + + struct Size { + uint64_t totalSize; + HashMap<unsigned, uint64_t> typeSizes; + }; + std::optional<Size> size; + + HashSet<WebCore::SecurityOriginData> origins; + HashSet<String> cookieHostNames; +#if ENABLE(NETSCAPE_PLUGIN_API) + HashSet<String> pluginDataHostNames; +#endif +}; + +} diff --git a/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp new file mode 100644 index 000000000..8fec3e4e1 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp @@ -0,0 +1,1207 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebsiteDataStore.h" + +#include "APIProcessPoolConfiguration.h" +#include "APIWebsiteDataRecord.h" +#include "NetworkProcessMessages.h" +#include "StorageManager.h" +#include "WebProcessMessages.h" +#include "WebProcessPool.h" +#include "WebResourceLoadStatisticsStore.h" +#include "WebResourceLoadStatisticsStoreMessages.h" +#include "WebsiteData.h" +#include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/DatabaseTracker.h> +#include <WebCore/HTMLMediaElement.h> +#include <WebCore/OriginLock.h> +#include <WebCore/SecurityOrigin.h> +#include <WebCore/SecurityOriginData.h> +#include <wtf/RunLoop.h> + +#if ENABLE(NETSCAPE_PLUGIN_API) +#include "PluginProcessManager.h" +#endif + +namespace WebKit { + +static WebCore::SessionID generateNonPersistentSessionID() +{ + // FIXME: We count backwards here to not conflict with API::Session. + static uint64_t sessionID = std::numeric_limits<uint64_t>::max(); + + return WebCore::SessionID(--sessionID); +} + +static uint64_t generateIdentifier() +{ + static uint64_t identifier; + + return ++identifier; +} + +Ref<WebsiteDataStore> WebsiteDataStore::createNonPersistent() +{ + return adoptRef(*new WebsiteDataStore(generateNonPersistentSessionID())); +} + +Ref<WebsiteDataStore> WebsiteDataStore::create(Configuration configuration) +{ + return adoptRef(*new WebsiteDataStore(WTFMove(configuration))); +} + +WebsiteDataStore::WebsiteDataStore(Configuration configuration) + : m_identifier(generateIdentifier()) + , m_sessionID(WebCore::SessionID::defaultSessionID()) + , m_configuration(WTFMove(configuration)) + , m_storageManager(StorageManager::create(m_configuration.localStorageDirectory)) + , m_resourceLoadStatistics(WebResourceLoadStatisticsStore::create(m_configuration.resourceLoadStatisticsDirectory)) + , m_queue(WorkQueue::create("com.apple.WebKit.WebsiteDataStore")) +{ + platformInitialize(); +} + +WebsiteDataStore::WebsiteDataStore(WebCore::SessionID sessionID) + : m_identifier(generateIdentifier()) + , m_sessionID(sessionID) + , m_configuration() + , m_queue(WorkQueue::create("com.apple.WebKit.WebsiteDataStore")) +{ + platformInitialize(); +} + +WebsiteDataStore::~WebsiteDataStore() +{ + platformDestroy(); + + if (m_sessionID.isEphemeral()) { + for (auto& processPool : WebProcessPool::allProcessPools()) + processPool->sendToNetworkingProcess(Messages::NetworkProcess::DestroyPrivateBrowsingSession(m_sessionID)); + } +} + +void WebsiteDataStore::cloneSessionData(WebPageProxy& sourcePage, WebPageProxy& newPage) +{ + auto& sourceDataStore = sourcePage.websiteDataStore(); + auto& newDataStore = newPage.websiteDataStore(); + + // FIXME: Handle this. + if (&sourceDataStore != &newDataStore) + return; + + if (!sourceDataStore.m_storageManager) + return; + + sourceDataStore.m_storageManager->cloneSessionStorageNamespace(sourcePage.pageID(), newPage.pageID()); +} + +enum class ProcessAccessType { + None, + OnlyIfLaunched, + Launch, +}; + +static ProcessAccessType computeNetworkProcessAccessTypeForDataFetch(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore) +{ + ProcessAccessType processAccessType = ProcessAccessType::None; + + if (dataTypes.contains(WebsiteDataType::Cookies)) { + if (isNonPersistentStore) + processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched); + else + processAccessType = std::max(processAccessType, ProcessAccessType::Launch); + } + + if (dataTypes.contains(WebsiteDataType::DiskCache) && !isNonPersistentStore) + processAccessType = std::max(processAccessType, ProcessAccessType::Launch); + + return processAccessType; +} + +static ProcessAccessType computeWebProcessAccessTypeForDataFetch(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore) +{ + UNUSED_PARAM(isNonPersistentStore); + + ProcessAccessType processAccessType = ProcessAccessType::None; + + if (dataTypes.contains(WebsiteDataType::MemoryCache)) + return ProcessAccessType::OnlyIfLaunched; + + return processAccessType; +} + +void WebsiteDataStore::fetchData(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, std::function<void (Vector<WebsiteDataRecord>)> completionHandler) +{ + struct CallbackAggregator final : ThreadSafeRefCounted<CallbackAggregator> { + explicit CallbackAggregator(OptionSet<WebsiteDataFetchOption> fetchOptions, std::function<void (Vector<WebsiteDataRecord>)> completionHandler) + : fetchOptions(fetchOptions) + , completionHandler(WTFMove(completionHandler)) + { + } + + ~CallbackAggregator() + { + ASSERT(!pendingCallbacks); + } + + void addPendingCallback() + { + pendingCallbacks++; + } + + void removePendingCallback(WebsiteData websiteData) + { + ASSERT(pendingCallbacks); + --pendingCallbacks; + + for (auto& entry : websiteData.entries) { + auto displayName = WebsiteDataRecord::displayNameForOrigin(entry.origin); + if (!displayName) + continue; + + auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value; + if (!record.displayName) + record.displayName = WTFMove(displayName); + + record.add(entry.type, entry.origin); + + if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes)) { + if (!record.size) + record.size = WebsiteDataRecord::Size { 0, { } }; + + record.size->totalSize += entry.size; + record.size->typeSizes.add(static_cast<unsigned>(entry.type), 0).iterator->value += entry.size; + } + } + + for (auto& hostName : websiteData.hostNamesWithCookies) { + auto displayName = WebsiteDataRecord::displayNameForCookieHostName(hostName); + if (!displayName) + continue; + + auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value; + if (!record.displayName) + record.displayName = WTFMove(displayName); + + record.addCookieHostName(hostName); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + for (auto& hostName : websiteData.hostNamesWithPluginData) { + auto displayName = WebsiteDataRecord::displayNameForPluginDataHostName(hostName); + if (!displayName) + continue; + + auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value; + if (!record.displayName) + record.displayName = WTFMove(displayName); + + record.addPluginDataHostName(hostName); + } +#endif + + callIfNeeded(); + } + + void callIfNeeded() + { + if (pendingCallbacks) + return; + + RunLoop::main().dispatch([callbackAggregator = makeRef(*this)]() mutable { + + WTF::Vector<WebsiteDataRecord> records; + records.reserveInitialCapacity(callbackAggregator->m_websiteDataRecords.size()); + + for (auto& record : callbackAggregator->m_websiteDataRecords.values()) + records.uncheckedAppend(WTFMove(record)); + + callbackAggregator->completionHandler(WTFMove(records)); + }); + } + + const OptionSet<WebsiteDataFetchOption> fetchOptions; + + unsigned pendingCallbacks = 0; + std::function<void (Vector<WebsiteDataRecord>)> completionHandler; + + HashMap<String, WebsiteDataRecord> m_websiteDataRecords; + }; + + RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(fetchOptions, WTFMove(completionHandler))); + +#if ENABLE(VIDEO) + if (dataTypes.contains(WebsiteDataType::DiskCache)) { + callbackAggregator->addPendingCallback(); + m_queue->dispatch([fetchOptions, mediaCacheDirectory = m_configuration.mediaCacheDirectory.isolatedCopy(), callbackAggregator] { + // FIXME: Make HTMLMediaElement::originsInMediaCache return a collection of SecurityOriginDatas. + HashSet<RefPtr<WebCore::SecurityOrigin>> origins = WebCore::HTMLMediaElement::originsInMediaCache(mediaCacheDirectory); + WebsiteData websiteData; + + for (auto& origin : origins) { + WebsiteData::Entry entry { WebCore::SecurityOriginData::fromSecurityOrigin(*origin), WebsiteDataType::DiskCache, 0 }; + websiteData.entries.append(WTFMove(entry)); + } + + RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins), websiteData = WTFMove(websiteData)]() mutable { + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + }); + } +#endif + + auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataFetch(dataTypes, !isPersistent()); + if (networkProcessAccessType != ProcessAccessType::None) { + for (auto& processPool : processPools()) { + switch (networkProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!processPool->networkProcess()) + continue; + break; + + case ProcessAccessType::Launch: + processPool->ensureNetworkProcess(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + callbackAggregator->addPendingCallback(); + processPool->networkProcess()->fetchWebsiteData(m_sessionID, dataTypes, fetchOptions, [callbackAggregator, processPool](WebsiteData websiteData) { + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + } + } + + auto webProcessAccessType = computeWebProcessAccessTypeForDataFetch(dataTypes, !isPersistent()); + if (webProcessAccessType != ProcessAccessType::None) { + for (auto& process : processes()) { + switch (webProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!process->canSendMessage()) + continue; + break; + + case ProcessAccessType::Launch: + // FIXME: Handle this. + ASSERT_NOT_REACHED(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + callbackAggregator->addPendingCallback(); + process->fetchWebsiteData(m_sessionID, dataTypes, [callbackAggregator](WebsiteData websiteData) { + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + } + } + + if (dataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->getSessionStorageOrigins([callbackAggregator](HashSet<WebCore::SecurityOriginData>&& origins) { + WebsiteData websiteData; + + while (!origins.isEmpty()) + websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::SessionStorage, 0 }); + + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + } + + if (dataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->getLocalStorageOrigins([callbackAggregator](HashSet<WebCore::SecurityOriginData>&& origins) { + WebsiteData websiteData; + + while (!origins.isEmpty()) + websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::LocalStorage, 0 }); + + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + } + + if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([fetchOptions, applicationCacheDirectory = m_configuration.applicationCacheDirectory.isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration.applicationCacheFlatFileSubdirectoryName.isolatedCopy(), callbackAggregator] { + auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName); + + WebsiteData websiteData; + + HashSet<RefPtr<WebCore::SecurityOrigin>> origins; + // FIXME: getOriginsWithCache should return a collection of SecurityOriginDatas. + storage->getOriginsWithCache(origins); + + for (auto& origin : origins) { + uint64_t size = fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes) ? storage->diskUsageForOrigin(*origin) : 0; + WebsiteData::Entry entry { WebCore::SecurityOriginData::fromSecurityOrigin(*origin), WebsiteDataType::OfflineWebApplicationCache, size }; + + websiteData.entries.append(WTFMove(entry)); + } + + RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins), websiteData = WTFMove(websiteData)]() mutable { + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + }); + } + + if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([webSQLDatabaseDirectory = m_configuration.webSQLDatabaseDirectory.isolatedCopy(), callbackAggregator] { + auto origins = WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory)->origins(); + RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins)]() mutable { + WebsiteData websiteData; + for (auto& origin : origins) + websiteData.entries.append(WebsiteData::Entry { WTFMove(origin), WebsiteDataType::WebSQLDatabases, 0 }); + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + }); + } + +#if ENABLE(DATABASE_PROCESS) + if (dataTypes.contains(WebsiteDataType::IndexedDBDatabases) && isPersistent()) { + for (auto& processPool : processPools()) { + processPool->ensureDatabaseProcess(); + + callbackAggregator->addPendingCallback(); + processPool->databaseProcess()->fetchWebsiteData(m_sessionID, dataTypes, [callbackAggregator, processPool](WebsiteData websiteData) { + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + } + } +#endif + + if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([mediaKeysStorageDirectory = m_configuration.mediaKeysStorageDirectory.isolatedCopy(), callbackAggregator] { + auto origins = mediaKeyOrigins(mediaKeysStorageDirectory); + + RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins)]() mutable { + WebsiteData websiteData; + for (auto& origin : origins) + websiteData.entries.append(WebsiteData::Entry { origin, WebsiteDataType::MediaKeys, 0 }); + + callbackAggregator->removePendingCallback(WTFMove(websiteData)); + }); + }); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) { + class State { + public: + static void fetchData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins) + { + new State(WTFMove(callbackAggregator), WTFMove(plugins)); + } + + private: + State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins) + : m_callbackAggregator(WTFMove(callbackAggregator)) + , m_plugins(WTFMove(plugins)) + { + m_callbackAggregator->addPendingCallback(); + + fetchWebsiteDataForNextPlugin(); + } + + ~State() + { + ASSERT(m_plugins.isEmpty()); + } + + void fetchWebsiteDataForNextPlugin() + { + if (m_plugins.isEmpty()) { + WebsiteData websiteData; + websiteData.hostNamesWithPluginData = WTFMove(m_hostNames); + + m_callbackAggregator->removePendingCallback(WTFMove(websiteData)); + + delete this; + return; + } + + auto plugin = m_plugins.takeLast(); + PluginProcessManager::singleton().fetchWebsiteData(plugin, [this](Vector<String> hostNames) { + for (auto& hostName : hostNames) + m_hostNames.add(WTFMove(hostName)); + fetchWebsiteDataForNextPlugin(); + }); + } + + Ref<CallbackAggregator> m_callbackAggregator; + Vector<PluginModuleInfo> m_plugins; + HashSet<String> m_hostNames; + }; + + State::fetchData(*callbackAggregator, plugins()); + } +#endif + + callbackAggregator->callIfNeeded(); +} + +void WebsiteDataStore::fetchDataForTopPrivatelyOwnedDomains(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, const Vector<String>& topPrivatelyOwnedDomains, std::function<void(Vector<WebsiteDataRecord>)> completionHandler) +{ + fetchData(dataTypes, fetchOptions, [topPrivatelyOwnedDomains, completionHandler, this](auto existingDataRecords) { + Vector<WebsiteDataRecord> matchingDataRecords; + Vector<String> domainsWithDataRecords; + for (auto& dataRecord : existingDataRecords) { + bool dataRecordAdded; + for (auto& dataRecordOriginData : dataRecord.origins) { + dataRecordAdded = false; + String dataRecordHost = dataRecordOriginData.securityOrigin().get().host(); + for (auto& topPrivatelyOwnedDomain : topPrivatelyOwnedDomains) { + if (dataRecordHost.endsWithIgnoringASCIICase(topPrivatelyOwnedDomain)) { + auto suffixStart = dataRecordHost.length() - topPrivatelyOwnedDomain.length(); + if (!suffixStart || dataRecordHost[suffixStart - 1] == '.') { + matchingDataRecords.append(dataRecord); + domainsWithDataRecords.append(topPrivatelyOwnedDomain); + dataRecordAdded = true; + break; + } + } + } + if (dataRecordAdded) + break; + } + } + completionHandler(matchingDataRecords); + }); +} + +static ProcessAccessType computeNetworkProcessAccessTypeForDataRemoval(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore) +{ + ProcessAccessType processAccessType = ProcessAccessType::None; + + if (dataTypes.contains(WebsiteDataType::Cookies)) { + if (isNonPersistentStore) + processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched); + else + processAccessType = std::max(processAccessType, ProcessAccessType::Launch); + } + + if (dataTypes.contains(WebsiteDataType::DiskCache) && !isNonPersistentStore) + processAccessType = std::max(processAccessType, ProcessAccessType::Launch); + + if (dataTypes.contains(WebsiteDataType::HSTSCache)) + processAccessType = std::max(processAccessType, ProcessAccessType::Launch); + + return processAccessType; +} + +static ProcessAccessType computeWebProcessAccessTypeForDataRemoval(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore) +{ + UNUSED_PARAM(isNonPersistentStore); + + ProcessAccessType processAccessType = ProcessAccessType::None; + + if (dataTypes.contains(WebsiteDataType::MemoryCache)) + processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched); + + return processAccessType; +} + +void WebsiteDataStore::removeData(OptionSet<WebsiteDataType> dataTypes, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) +{ + struct CallbackAggregator : ThreadSafeRefCounted<CallbackAggregator> { + explicit CallbackAggregator (std::function<void ()> completionHandler) + : completionHandler(WTFMove(completionHandler)) + { + } + + void addPendingCallback() + { + pendingCallbacks++; + } + + void removePendingCallback() + { + ASSERT(pendingCallbacks); + --pendingCallbacks; + + callIfNeeded(); + } + + void callIfNeeded() + { + if (!pendingCallbacks) + RunLoop::main().dispatch(WTFMove(completionHandler)); + } + + unsigned pendingCallbacks = 0; + std::function<void()> completionHandler; + }; + + RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler))); + +#if ENABLE(VIDEO) + if (dataTypes.contains(WebsiteDataType::DiskCache)) { + callbackAggregator->addPendingCallback(); + m_queue->dispatch([modifiedSince, mediaCacheDirectory = m_configuration.mediaCacheDirectory.isolatedCopy(), callbackAggregator] { + WebCore::HTMLMediaElement::clearMediaCache(mediaCacheDirectory, modifiedSince); + + WTF::RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } +#endif + + auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); + if (networkProcessAccessType != ProcessAccessType::None) { + for (auto& processPool : processPools()) { + switch (networkProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!processPool->networkProcess()) + continue; + break; + + case ProcessAccessType::Launch: + processPool->ensureNetworkProcess(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + callbackAggregator->addPendingCallback(); + processPool->networkProcess()->deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator, processPool] { + callbackAggregator->removePendingCallback(); + }); + } + } + + auto webProcessAccessType = computeWebProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); + if (webProcessAccessType != ProcessAccessType::None) { + for (auto& process : processes()) { + switch (webProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!process->canSendMessage()) + continue; + break; + + case ProcessAccessType::Launch: + // FIXME: Handle this. + ASSERT_NOT_REACHED(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + callbackAggregator->addPendingCallback(); + process->deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + } + + if (dataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->deleteSessionStorageOrigins([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + + if (dataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->deleteLocalStorageOriginsModifiedSince(modifiedSince, [callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + + if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([applicationCacheDirectory = m_configuration.applicationCacheDirectory.isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration.applicationCacheFlatFileSubdirectoryName.isolatedCopy(), callbackAggregator] { + auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName); + + storage->deleteAllCaches(); + + WTF::RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + + if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([webSQLDatabaseDirectory = m_configuration.webSQLDatabaseDirectory.isolatedCopy(), callbackAggregator, modifiedSince] { + WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory)->deleteDatabasesModifiedSince(modifiedSince); + + RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + +#if ENABLE(DATABASE_PROCESS) + if (dataTypes.contains(WebsiteDataType::IndexedDBDatabases) && isPersistent()) { + for (auto& processPool : processPools()) { + processPool->ensureDatabaseProcess(); + + callbackAggregator->addPendingCallback(); + processPool->databaseProcess()->deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator, processPool] { + callbackAggregator->removePendingCallback(); + }); + } + } +#endif + + if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([mediaKeysStorageDirectory = m_configuration.mediaKeysStorageDirectory.isolatedCopy(), callbackAggregator, modifiedSince] { + removeMediaKeys(mediaKeysStorageDirectory, modifiedSince); + + RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + + if (dataTypes.contains(WebsiteDataType::SearchFieldRecentSearches) && isPersistent()) { + callbackAggregator->addPendingCallback(); + + m_queue->dispatch([modifiedSince, callbackAggregator] { + platformRemoveRecentSearches(modifiedSince); + + RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) { + class State { + public: + static void deleteData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, std::chrono::system_clock::time_point modifiedSince) + { + new State(WTFMove(callbackAggregator), WTFMove(plugins), modifiedSince); + } + + private: + State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, std::chrono::system_clock::time_point modifiedSince) + : m_callbackAggregator(WTFMove(callbackAggregator)) + , m_plugins(WTFMove(plugins)) + , m_modifiedSince(modifiedSince) + { + m_callbackAggregator->addPendingCallback(); + + deleteWebsiteDataForNextPlugin(); + } + + ~State() + { + ASSERT(m_plugins.isEmpty()); + } + + void deleteWebsiteDataForNextPlugin() + { + if (m_plugins.isEmpty()) { + m_callbackAggregator->removePendingCallback(); + + delete this; + return; + } + + auto plugin = m_plugins.takeLast(); + PluginProcessManager::singleton().deleteWebsiteData(plugin, m_modifiedSince, [this] { + deleteWebsiteDataForNextPlugin(); + }); + } + + Ref<CallbackAggregator> m_callbackAggregator; + Vector<PluginModuleInfo> m_plugins; + std::chrono::system_clock::time_point m_modifiedSince; + }; + + State::deleteData(*callbackAggregator, plugins(), modifiedSince); + } +#endif + + // There's a chance that we don't have any pending callbacks. If so, we want to dispatch the completion handler right away. + callbackAggregator->callIfNeeded(); +} + +void WebsiteDataStore::removeData(OptionSet<WebsiteDataType> dataTypes, const Vector<WebsiteDataRecord>& dataRecords, std::function<void ()> completionHandler) +{ + Vector<WebCore::SecurityOriginData> origins; + + for (const auto& dataRecord : dataRecords) { + for (auto& origin : dataRecord.origins) + origins.append(origin); + } + + struct CallbackAggregator : ThreadSafeRefCounted<CallbackAggregator> { + explicit CallbackAggregator (std::function<void ()> completionHandler) + : completionHandler(WTFMove(completionHandler)) + { + } + + void addPendingCallback() + { + pendingCallbacks++; + } + + void removePendingCallback() + { + ASSERT(pendingCallbacks); + --pendingCallbacks; + + callIfNeeded(); + } + + void callIfNeeded() + { + if (!pendingCallbacks) + RunLoop::main().dispatch(WTFMove(completionHandler)); + } + + unsigned pendingCallbacks = 0; + std::function<void()> completionHandler; + }; + + RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler))); + + if (dataTypes.contains(WebsiteDataType::DiskCache)) { + HashSet<WebCore::SecurityOriginData> origins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + origins.add(origin); + } + +#if ENABLE(VIDEO) + callbackAggregator->addPendingCallback(); + m_queue->dispatch([origins = WTFMove(origins), mediaCacheDirectory = m_configuration.mediaCacheDirectory.isolatedCopy(), callbackAggregator] { + + // FIXME: Move SecurityOrigin::toRawString to SecurityOriginData and + // make HTMLMediaElement::clearMediaCacheForOrigins take SecurityOriginData. + HashSet<RefPtr<WebCore::SecurityOrigin>> securityOrigins; + for (auto& origin : origins) + securityOrigins.add(origin.securityOrigin()); + WebCore::HTMLMediaElement::clearMediaCacheForOrigins(mediaCacheDirectory, securityOrigins); + + WTF::RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); +#endif + } + + auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); + if (networkProcessAccessType != ProcessAccessType::None) { + for (auto& processPool : processPools()) { + switch (networkProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!processPool->networkProcess()) + continue; + break; + + case ProcessAccessType::Launch: + processPool->ensureNetworkProcess(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + Vector<String> cookieHostNames; + for (const auto& dataRecord : dataRecords) { + for (auto& hostName : dataRecord.cookieHostNames) + cookieHostNames.append(hostName); + } + + callbackAggregator->addPendingCallback(); + processPool->networkProcess()->deleteWebsiteDataForOrigins(m_sessionID, dataTypes, origins, cookieHostNames, [callbackAggregator, processPool] { + callbackAggregator->removePendingCallback(); + }); + } + } + + auto webProcessAccessType = computeWebProcessAccessTypeForDataRemoval(dataTypes, !isPersistent()); + if (webProcessAccessType != ProcessAccessType::None) { + for (auto& process : processes()) { + switch (webProcessAccessType) { + case ProcessAccessType::OnlyIfLaunched: + if (!process->canSendMessage()) + continue; + break; + + case ProcessAccessType::Launch: + // FIXME: Handle this. + ASSERT_NOT_REACHED(); + break; + + case ProcessAccessType::None: + ASSERT_NOT_REACHED(); + } + + callbackAggregator->addPendingCallback(); + + process->deleteWebsiteDataForOrigins(m_sessionID, dataTypes, origins, [callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + } + + if (dataTypes.contains(WebsiteDataType::SessionStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->deleteSessionStorageEntriesForOrigins(origins, [callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + + if (dataTypes.contains(WebsiteDataType::LocalStorage) && m_storageManager) { + callbackAggregator->addPendingCallback(); + + m_storageManager->deleteLocalStorageEntriesForOrigins(origins, [callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + } + + if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) { + HashSet<WebCore::SecurityOriginData> origins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + origins.add(origin); + } + + callbackAggregator->addPendingCallback(); + m_queue->dispatch([origins = WTFMove(origins), applicationCacheDirectory = m_configuration.applicationCacheDirectory.isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration.applicationCacheFlatFileSubdirectoryName.isolatedCopy(), callbackAggregator] { + auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName); + + for (const auto& origin : origins) + storage->deleteCacheForOrigin(origin.securityOrigin()); + + WTF::RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + + if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) { + HashSet<WebCore::SecurityOriginData> origins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + origins.add(origin); + } + + callbackAggregator->addPendingCallback(); + m_queue->dispatch([origins = WTFMove(origins), callbackAggregator, webSQLDatabaseDirectory = m_configuration.webSQLDatabaseDirectory.isolatedCopy()] { + auto databaseTracker = WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory); + for (auto& origin : origins) + databaseTracker->deleteOrigin(origin); + RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + +#if ENABLE(DATABASE_PROCESS) + if (dataTypes.contains(WebsiteDataType::IndexedDBDatabases) && isPersistent()) { + for (auto& processPool : processPools()) { + processPool->ensureDatabaseProcess(); + + callbackAggregator->addPendingCallback(); + processPool->databaseProcess()->deleteWebsiteDataForOrigins(m_sessionID, dataTypes, origins, [callbackAggregator, processPool] { + callbackAggregator->removePendingCallback(); + }); + } + } +#endif + + if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) { + HashSet<WebCore::SecurityOriginData> origins; + for (const auto& dataRecord : dataRecords) { + for (const auto& origin : dataRecord.origins) + origins.add(origin); + } + + callbackAggregator->addPendingCallback(); + m_queue->dispatch([mediaKeysStorageDirectory = m_configuration.mediaKeysStorageDirectory.isolatedCopy(), callbackAggregator, origins = WTFMove(origins)] { + + removeMediaKeys(mediaKeysStorageDirectory, origins); + + RunLoop::main().dispatch([callbackAggregator] { + callbackAggregator->removePendingCallback(); + }); + }); + } + +#if ENABLE(NETSCAPE_PLUGIN_API) + if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) { + Vector<String> hostNames; + for (const auto& dataRecord : dataRecords) { + for (const auto& hostName : dataRecord.pluginDataHostNames) + hostNames.append(hostName); + } + + + class State { + public: + static void deleteData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames) + { + new State(WTFMove(callbackAggregator), WTFMove(plugins), WTFMove(hostNames)); + } + + private: + State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames) + : m_callbackAggregator(WTFMove(callbackAggregator)) + , m_plugins(WTFMove(plugins)) + , m_hostNames(WTFMove(hostNames)) + { + m_callbackAggregator->addPendingCallback(); + + deleteWebsiteDataForNextPlugin(); + } + + ~State() + { + ASSERT(m_plugins.isEmpty()); + } + + void deleteWebsiteDataForNextPlugin() + { + if (m_plugins.isEmpty()) { + m_callbackAggregator->removePendingCallback(); + + delete this; + return; + } + + auto plugin = m_plugins.takeLast(); + PluginProcessManager::singleton().deleteWebsiteDataForHostNames(plugin, m_hostNames, [this] { + deleteWebsiteDataForNextPlugin(); + }); + } + + Ref<CallbackAggregator> m_callbackAggregator; + Vector<PluginModuleInfo> m_plugins; + Vector<String> m_hostNames; + }; + + State::deleteData(*callbackAggregator, plugins(), WTFMove(hostNames)); + } +#endif + + // There's a chance that we don't have any pending callbacks. If so, we want to dispatch the completion handler right away. + callbackAggregator->callIfNeeded(); +} + +void WebsiteDataStore::removeDataForTopPrivatelyOwnedDomains(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, const Vector<String>& topPrivatelyOwnedDomains, std::function<void()> completionHandler) +{ + fetchDataForTopPrivatelyOwnedDomains(dataTypes, fetchOptions, topPrivatelyOwnedDomains, [dataTypes, completionHandler, this](auto websiteDataRecords) { + this->removeData(dataTypes, websiteDataRecords, [completionHandler]() { + completionHandler(); + }); + }); +} + +void WebsiteDataStore::webPageWasAdded(WebPageProxy& webPageProxy) +{ + if (m_storageManager) + m_storageManager->createSessionStorageNamespace(webPageProxy.pageID(), std::numeric_limits<unsigned>::max()); +} + +void WebsiteDataStore::webPageWasRemoved(WebPageProxy& webPageProxy) +{ + if (m_storageManager) + m_storageManager->destroySessionStorageNamespace(webPageProxy.pageID()); +} + +void WebsiteDataStore::webProcessWillOpenConnection(WebProcessProxy& webProcessProxy, IPC::Connection& connection) +{ + if (m_storageManager) + m_storageManager->processWillOpenConnection(webProcessProxy, connection); + + if (m_resourceLoadStatistics) + m_resourceLoadStatistics->processWillOpenConnection(webProcessProxy, connection); +} + +void WebsiteDataStore::webPageWillOpenConnection(WebPageProxy& webPageProxy, IPC::Connection& connection) +{ + if (m_storageManager) + m_storageManager->setAllowedSessionStorageNamespaceConnection(webPageProxy.pageID(), &connection); +} + +void WebsiteDataStore::webPageDidCloseConnection(WebPageProxy& webPageProxy, IPC::Connection&) +{ + if (m_storageManager) + m_storageManager->setAllowedSessionStorageNamespaceConnection(webPageProxy.pageID(), nullptr); +} + +void WebsiteDataStore::webProcessDidCloseConnection(WebProcessProxy& webProcessProxy, IPC::Connection& connection) +{ + if (m_resourceLoadStatistics) + m_resourceLoadStatistics->processDidCloseConnection(webProcessProxy, connection); + + if (m_storageManager) + m_storageManager->processDidCloseConnection(webProcessProxy, connection); +} + +HashSet<RefPtr<WebProcessPool>> WebsiteDataStore::processPools() const +{ + HashSet<RefPtr<WebProcessPool>> processPools; + for (auto& process : processes()) + processPools.add(&process->processPool()); + + if (processPools.isEmpty()) { + // Check if we're one of the legacy data stores. + for (auto& processPool : WebProcessPool::allProcessPools()) { + if (auto dataStore = processPool->websiteDataStore()) { + if (&dataStore->websiteDataStore() == this) { + processPools.add(processPool); + break; + } + } + } + } + + if (processPools.isEmpty()) { + auto processPool = WebProcessPool::create(API::ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration(m_configuration)); + processPools.add(processPool.ptr()); + } + + return processPools; +} + +#if ENABLE(NETSCAPE_PLUGIN_API) +Vector<PluginModuleInfo> WebsiteDataStore::plugins() const +{ + Vector<PluginModuleInfo> plugins; + + for (auto& processPool : processPools()) { + for (auto& plugin : processPool->pluginInfoStore().plugins()) + plugins.append(plugin); + } + + return plugins; +} +#endif + +static String computeMediaKeyFile(const String& mediaKeyDirectory) +{ + return WebCore::pathByAppendingComponent(mediaKeyDirectory, "SecureStop.plist"); +} + +Vector<WebCore::SecurityOriginData> WebsiteDataStore::mediaKeyOrigins(const String& mediaKeysStorageDirectory) +{ + ASSERT(!mediaKeysStorageDirectory.isEmpty()); + + Vector<WebCore::SecurityOriginData> origins; + + for (const auto& originPath : WebCore::listDirectory(mediaKeysStorageDirectory, "*")) { + auto mediaKeyFile = computeMediaKeyFile(originPath); + if (!WebCore::fileExists(mediaKeyFile)) + continue; + + auto mediaKeyIdentifier = WebCore::pathGetFileName(originPath); + + if (auto securityOrigin = WebCore::SecurityOriginData::fromDatabaseIdentifier(mediaKeyIdentifier)) + origins.append(*securityOrigin); + } + + return origins; +} + +void WebsiteDataStore::removeMediaKeys(const String& mediaKeysStorageDirectory, std::chrono::system_clock::time_point modifiedSince) +{ + ASSERT(!mediaKeysStorageDirectory.isEmpty()); + + for (const auto& mediaKeyDirectory : WebCore::listDirectory(mediaKeysStorageDirectory, "*")) { + auto mediaKeyFile = computeMediaKeyFile(mediaKeyDirectory); + + time_t modificationTime; + if (!WebCore::getFileModificationTime(mediaKeyFile, modificationTime)) + continue; + + if (std::chrono::system_clock::from_time_t(modificationTime) < modifiedSince) + continue; + + WebCore::deleteFile(mediaKeyFile); + WebCore::deleteEmptyDirectory(mediaKeyDirectory); + } +} + +void WebsiteDataStore::removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>& origins) +{ + ASSERT(!mediaKeysStorageDirectory.isEmpty()); + + for (const auto& origin : origins) { + auto mediaKeyDirectory = WebCore::pathByAppendingComponent(mediaKeysStorageDirectory, origin.databaseIdentifier()); + auto mediaKeyFile = computeMediaKeyFile(mediaKeyDirectory); + + WebCore::deleteFile(mediaKeyFile); + WebCore::deleteEmptyDirectory(mediaKeyDirectory); + } +} + +bool WebsiteDataStore::resourceLoadStatisticsEnabled() const +{ + return m_resourceLoadStatistics ? m_resourceLoadStatistics->resourceLoadStatisticsEnabled() : false; +} + +void WebsiteDataStore::setResourceLoadStatisticsEnabled(bool enabled) +{ + if (!m_resourceLoadStatistics) + return; + + if (enabled == resourceLoadStatisticsEnabled()) + return; + + m_resourceLoadStatistics->setResourceLoadStatisticsEnabled(enabled); + + for (auto& processPool : WebProcessPool::allProcessPools()) { + processPool->setResourceLoadStatisticsEnabled(enabled); + processPool->sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(enabled)); + } +} + +void WebsiteDataStore::registerSharedResourceLoadObserver() +{ + if (!m_resourceLoadStatistics) + return; + + m_resourceLoadStatistics->registerSharedResourceLoadObserver(); +} + +} diff --git a/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h new file mode 100644 index 000000000..cba299d0b --- /dev/null +++ b/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "WebProcessLifetimeObserver.h" +#include <WebCore/SecurityOriginData.h> +#include <WebCore/SecurityOriginHash.h> +#include <WebCore/SessionID.h> +#include <functional> +#include <wtf/HashSet.h> +#include <wtf/OptionSet.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/WorkQueue.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class SecurityOrigin; +} + +namespace WebKit { + +class StorageManager; +class WebPageProxy; +class WebProcessPool; +class WebResourceLoadStatisticsStore; +enum class WebsiteDataFetchOption; +enum class WebsiteDataType; +struct WebsiteDataRecord; + +#if ENABLE(NETSCAPE_PLUGIN_API) +struct PluginModuleInfo; +#endif + +class WebsiteDataStore : public RefCounted<WebsiteDataStore>, public WebProcessLifetimeObserver { +public: + struct Configuration { + String networkCacheDirectory; + String applicationCacheDirectory; + String applicationCacheFlatFileSubdirectoryName; + + String mediaCacheDirectory; + String webSQLDatabaseDirectory; + String localStorageDirectory; + String mediaKeysStorageDirectory; + String resourceLoadStatisticsDirectory; + }; + static Ref<WebsiteDataStore> createNonPersistent(); + static Ref<WebsiteDataStore> create(Configuration); + virtual ~WebsiteDataStore(); + + uint64_t identifier() const { return m_identifier; } + + bool isPersistent() const { return !m_sessionID.isEphemeral(); } + WebCore::SessionID sessionID() const { return m_sessionID; } + + bool resourceLoadStatisticsEnabled() const; + void setResourceLoadStatisticsEnabled(bool); + void registerSharedResourceLoadObserver(); + + static void cloneSessionData(WebPageProxy& sourcePage, WebPageProxy& newPage); + + void fetchData(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, std::function<void (Vector<WebsiteDataRecord>)> completionHandler); + void fetchDataForTopPrivatelyOwnedDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<String>& topPrivatelyOwnedDomains, std::function<void(Vector<WebsiteDataRecord>)> completionHandler); + void removeData(OptionSet<WebsiteDataType>, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler); + void removeData(OptionSet<WebsiteDataType>, const Vector<WebsiteDataRecord>&, std::function<void ()> completionHandler); + void removeDataForTopPrivatelyOwnedDomains(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, const Vector<String>& topPrivatelyOwnedDomains, std::function<void()> completionHandler); + + StorageManager* storageManager() { return m_storageManager.get(); } + +private: + explicit WebsiteDataStore(WebCore::SessionID); + explicit WebsiteDataStore(Configuration); + + // WebProcessLifetimeObserver. + void webPageWasAdded(WebPageProxy&) override; + void webPageWasRemoved(WebPageProxy&) override; + void webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) override; + void webPageWillOpenConnection(WebPageProxy&, IPC::Connection&) override; + void webPageDidCloseConnection(WebPageProxy&, IPC::Connection&) override; + void webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) override; + + void platformInitialize(); + void platformDestroy(); + static void platformRemoveRecentSearches(std::chrono::system_clock::time_point); + + HashSet<RefPtr<WebProcessPool>> processPools() const; + +#if ENABLE(NETSCAPE_PLUGIN_API) + Vector<PluginModuleInfo> plugins() const; +#endif + + static Vector<WebCore::SecurityOriginData> mediaKeyOrigins(const String& mediaKeysStorageDirectory); + static void removeMediaKeys(const String& mediaKeysStorageDirectory, std::chrono::system_clock::time_point modifiedSince); + static void removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>&); + + const uint64_t m_identifier; + const WebCore::SessionID m_sessionID; + + const Configuration m_configuration; + + const RefPtr<StorageManager> m_storageManager; + const RefPtr<WebResourceLoadStatisticsStore> m_resourceLoadStatistics; + + Ref<WorkQueue> m_queue; +}; + +} diff --git a/Source/WebKit2/UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp b/Source/WebKit2/UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp new file mode 100644 index 000000000..76956fd75 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebsiteData/unix/WebsiteDataStoreUnix.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 University of Szeged. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebsiteDataStore.h" + +namespace WebKit { + +void WebsiteDataStore::platformInitialize() +{ +} + +void WebsiteDataStore::platformDestroy() +{ +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/ProcessModel.h b/Source/WebKit2/UIProcess/_WKWebViewPrintFormatter.h index 6c18da0a2..befdcc78b 100644 --- a/Source/WebKit2/UIProcess/ProcessModel.h +++ b/Source/WebKit2/UIProcess/_WKWebViewPrintFormatter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,16 +23,16 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ProcessModel_h -#define ProcessModel_h +#if TARGET_OS_IPHONE -namespace WebKit { +#import <UIKit/UIPrintFormatter.h> -enum ProcessModel { - ProcessModelSharedSecondaryProcess, - ProcessModelMultipleSecondaryProcesses -}; +@class _WKFrameHandle; -} // namespace WebKit +@interface _WKWebViewPrintFormatter : UIViewPrintFormatter -#endif // ProcessModel_h +@property (nonatomic, strong) _WKFrameHandle *frameToPrint; + +@end + +#endif diff --git a/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h b/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h new file mode 100644 index 000000000..451a0d504 --- /dev/null +++ b/Source/WebKit2/UIProcess/_WKWebViewPrintFormatterInternal.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "_WKWebViewPrintFormatter.h" + +#if PLATFORM(IOS) + +@interface UIPrintFormatter () +- (CGRect)_pageContentRect:(BOOL)firstPage; +@end + +@protocol _WKWebViewPrintProvider <NSObject> +- (NSUInteger)_wk_pageCountForPrintFormatter:(_WKWebViewPrintFormatter *)printFormatter; +@property (nonatomic, readonly) CGPDFDocumentRef _wk_printedDocument; +@end + +#endif // PLATFORM(IOS) diff --git a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp index 89968ae59..bde479419 100644 --- a/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp +++ b/Source/WebKit2/UIProcess/cairo/BackingStoreCairo.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Apple Inc. All rights reserved. - * Copyright (C) 2011 Igalia S.L. + * Copyright (C) 2011,2014 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,64 +30,88 @@ #include "ShareableBitmap.h" #include "UpdateInfo.h" #include "WebPageProxy.h" +#include <WebCore/BackingStoreBackendCairoImpl.h> +#include <WebCore/CairoUtilities.h> #include <WebCore/GraphicsContext.h> -#include <WebCore/WidgetBackingStoreCairo.h> +#include <WebCore/RefPtrCairo.h> #include <cairo.h> -#if PLATFORM(GTK) && PLATFORM(X11) && defined(GDK_WINDOWING_X11) -#include <WebCore/WidgetBackingStoreGtkX11.h> -#include <gdk/gdkx.h> +#if PLATFORM(GTK) +#include <gtk/gtk.h> #endif -#if PLATFORM(EFL) -#include "EwkView.h" +#if PLATFORM(GTK) && PLATFORM(X11) && defined(GDK_WINDOWING_X11) +#include <WebCore/BackingStoreBackendCairoX11.h> +#include <WebCore/PlatformDisplayX11.h> +#include <gdk/gdkx.h> #endif using namespace WebCore; namespace WebKit { -#if PLATFORM(GTK) -static OwnPtr<WidgetBackingStore> createBackingStoreForGTK(GtkWidget* widget, const IntSize& size, float deviceScaleFactor) +std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend() { -#if PLATFORM(X11) && defined(GDK_WINDOWING_X11) - GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get()); - if (GDK_IS_X11_DISPLAY(display)) - return WebCore::WidgetBackingStoreGtkX11::create(widget, size, deviceScaleFactor); +#if PLATFORM(GTK) && PLATFORM(X11) && defined(GDK_WINDOWING_X11) + const auto& sharedDisplay = PlatformDisplay::sharedDisplay(); + if (is<PlatformDisplayX11>(sharedDisplay)) { + GdkVisual* visual = gtk_widget_get_visual(m_webPageProxy.viewWidget()); + GdkScreen* screen = gdk_visual_get_screen(visual); + ASSERT(downcast<PlatformDisplayX11>(sharedDisplay).native() == GDK_SCREEN_XDISPLAY(screen)); + return std::make_unique<BackingStoreBackendCairoX11>(GDK_WINDOW_XID(gdk_screen_get_root_window(screen)), + GDK_VISUAL_XVISUAL(visual), gdk_visual_get_depth(visual), m_size, m_deviceScaleFactor); + } #endif - return WebCore::WidgetBackingStoreCairo::create(widget, size, deviceScaleFactor); -} + + IntSize scaledSize = m_size; + scaledSize.scale(m_deviceScaleFactor); + +#if PLATFORM(GTK) + RefPtr<cairo_surface_t> surface = adoptRef(gdk_window_create_similar_surface(gtk_widget_get_window(m_webPageProxy.viewWidget()), + CAIRO_CONTENT_COLOR_ALPHA, scaledSize.width(), scaledSize.height())); +#else + RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height())); #endif + cairoSurfaceSetDeviceScale(surface.get(), m_deviceScaleFactor, m_deviceScaleFactor); + return std::make_unique<BackingStoreBackendCairoImpl>(surface.get(), m_size); +} + void BackingStore::paint(cairo_t* context, const IntRect& rect) { - ASSERT(m_backingStore); + ASSERT(m_backend); + cairo_save(context); cairo_set_operator(context, CAIRO_OPERATOR_SOURCE); - cairo_set_source_surface(context, m_backingStore->cairoSurface(), 0, 0); + cairo_set_source_surface(context, m_backend->surface(), 0, 0); cairo_rectangle(context, rect.x(), rect.y(), rect.width(), rect.height()); cairo_fill(context); + cairo_restore(context); } void BackingStore::incorporateUpdate(ShareableBitmap* bitmap, const UpdateInfo& updateInfo) { - if (!m_backingStore) -#if PLATFORM(EFL) - m_backingStore = WidgetBackingStoreCairo::create(EwkView::toEvasObject(toAPI(m_webPageProxy)), size(), deviceScaleFactor()); -#else - m_backingStore = createBackingStoreForGTK(m_webPageProxy->viewWidget(), size(), deviceScaleFactor()); -#endif + if (!m_backend) + m_backend = createBackend(); scroll(updateInfo.scrollRect, updateInfo.scrollOffset); // Paint all update rects. IntPoint updateRectLocation = updateInfo.updateRectBounds.location(); - RefPtr<cairo_t> context(adoptRef(cairo_create(m_backingStore->cairoSurface()))); + RefPtr<cairo_t> context = adoptRef(cairo_create(m_backend->surface())); GraphicsContext graphicsContext(context.get()); - for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) { - IntRect updateRect = updateInfo.updateRects[i]; + for (const auto& updateRect : updateInfo.updateRects) { IntRect srcRect = updateRect; srcRect.move(-updateRectLocation.x(), -updateRectLocation.y()); +#if PLATFORM(GTK) + if (!m_webPageProxy.drawsBackground()) { + const WebCore::Color color = m_webPageProxy.backgroundColor(); + if (!color.isOpaque()) + graphicsContext.clearRect(srcRect); + if (color.isVisible()) + graphicsContext.fillRect(srcRect, color); + } +#endif bitmap->paint(graphicsContext, deviceScaleFactor(), updateRect.location(), srcRect); } } @@ -97,8 +121,8 @@ void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset if (scrollOffset.isZero()) return; - ASSERT(m_backingStore); - m_backingStore->scroll(scrollRect, scrollOffset); + ASSERT(m_backend); + m_backend->scroll(scrollRect, scrollOffset); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.cpp b/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.cpp new file mode 100644 index 000000000..11d759e1c --- /dev/null +++ b/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "InstallMissingMediaPluginsPermissionRequest.h" + +#if ENABLE(VIDEO) && USE(GSTREAMER) +#include "WebPageMessages.h" +#include "WebPageProxy.h" +#include <wtf/text/CString.h> + +namespace WebKit { + +InstallMissingMediaPluginsPermissionRequest::InstallMissingMediaPluginsPermissionRequest(WebPageProxy& page, const String& details, const String& description) + : m_page(&page) + , m_details(details) + , m_description(description) +{ +} + +InstallMissingMediaPluginsPermissionRequest::~InstallMissingMediaPluginsPermissionRequest() +{ +} + +void InstallMissingMediaPluginsPermissionRequest::allow(GUniquePtr<GstInstallPluginsContext>&& context) +{ + if (!m_page->isValid()) + return; + + CString detail = m_details.utf8(); + const char* detailArray[2] = { detail.data(), nullptr }; + ref(); + GstInstallPluginsReturn result = gst_install_plugins_async(detailArray, context.get(), [](GstInstallPluginsReturn result, gpointer userData) { + RefPtr<InstallMissingMediaPluginsPermissionRequest> request = adoptRef(static_cast<InstallMissingMediaPluginsPermissionRequest*>(userData)); + request->didEndRequestInstallMissingMediaPlugins(static_cast<uint32_t>(result)); + }, this); + + if (result != GST_INSTALL_PLUGINS_STARTED_OK) { + // If the installer didn't start, the callback will not be called, so remove the ref manually. + deref(); + didEndRequestInstallMissingMediaPlugins(static_cast<uint32_t>(result)); + WTFLogAlways("Missing GStreamer Plugin: %s\n", detail.data()); + } +} + +void InstallMissingMediaPluginsPermissionRequest::deny() +{ + didEndRequestInstallMissingMediaPlugins(static_cast<uint32_t>(GST_INSTALL_PLUGINS_USER_ABORT)); +} + +void InstallMissingMediaPluginsPermissionRequest::didEndRequestInstallMissingMediaPlugins(uint32_t result) +{ + if (!m_page->isValid()) + return; + + m_page->send(Messages::WebPage::DidEndRequestInstallMissingMediaPlugins(result)); +} + +} // namespace WebKit + +#endif // ENABLE(VIDEO) && USE(GSTREAMER) diff --git a/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.h b/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.h new file mode 100644 index 000000000..5416014cb --- /dev/null +++ b/Source/WebKit2/UIProcess/gstreamer/InstallMissingMediaPluginsPermissionRequest.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef InstallMissingMediaPluginsPermissionRequest_h +#define InstallMissingMediaPluginsPermissionRequest_h + +#if ENABLE(VIDEO) && USE(GSTREAMER) +#include <WebCore/GUniquePtrGStreamer.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +class WebPageProxy; + +class InstallMissingMediaPluginsPermissionRequest : public RefCounted<InstallMissingMediaPluginsPermissionRequest> { +public: + static Ref<InstallMissingMediaPluginsPermissionRequest> create(WebPageProxy& page, const String& details, const String& description) + { + return adoptRef(*new InstallMissingMediaPluginsPermissionRequest(page, details, description)); + } + ~InstallMissingMediaPluginsPermissionRequest(); + + void allow(GUniquePtr<GstInstallPluginsContext>&& = nullptr); + void deny(); + + WebPageProxy& page() const { return *m_page; } + const String& details() const { return m_details; } + const String& description() const { return m_description; } + +private: + InstallMissingMediaPluginsPermissionRequest(WebPageProxy&, const String& details, const String& description); + + void didEndRequestInstallMissingMediaPlugins(uint32_t result); + + RefPtr<WebPageProxy> m_page; + String m_details; + String m_description; +}; + +} // namespace WebKit + +#else + +namespace WebKit { +class InstallMissingMediaPluginsPermissionRequest; +} // namespace WebKit + +#endif // ENABLE(VIDEO) && USE(GSTREAMER) +#endif // InstallMissingMediaPluginsPermissionRequest_h diff --git a/Source/WebKit2/UIProcess/WebColorPickerResultListenerProxy.cpp b/Source/WebKit2/UIProcess/gstreamer/WebPageProxyGStreamer.cpp index c0c2c2221..2ed9c34cf 100644 --- a/Source/WebKit2/UIProcess/WebColorPickerResultListenerProxy.cpp +++ b/Source/WebKit2/UIProcess/gstreamer/WebPageProxyGStreamer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Samsung Electronics. All rights reserved. + * Copyright (C) 2015 Igalia S.L. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,7 +10,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS @@ -24,37 +24,23 @@ */ #include "config.h" -#include "WebColorPickerResultListenerProxy.h" - -#if ENABLE(INPUT_TYPE_COLOR) - #include "WebPageProxy.h" -namespace WebKit { - -WebColorPickerResultListenerProxy::WebColorPickerResultListenerProxy(WebPageProxy* page) - : m_page(page) -{ -} - -WebColorPickerResultListenerProxy::~WebColorPickerResultListenerProxy() -{ -} +#if ENABLE(VIDEO) && USE(GSTREAMER) +#include "InstallMissingMediaPluginsPermissionRequest.h" +#include "PageClient.h" -void WebColorPickerResultListenerProxy::invalidate() -{ - m_page = 0; -} +namespace WebKit { -void WebColorPickerResultListenerProxy::setColor(const String& color) +void WebPageProxy::requestInstallMissingMediaPlugins(const String& details, const String& description) { - if (!m_page) + RefPtr<InstallMissingMediaPluginsPermissionRequest> request = InstallMissingMediaPluginsPermissionRequest::create(*this, details, description); + if (m_pageClient.decidePolicyForInstallMissingMediaPluginsPermissionRequest(*request)) return; - m_page->setColorPickerColor(WebCore::Color(color)); - m_page->endColorPicker(); + request->deny(); } } // namespace WebKit -#endif // ENABLE(INPUT_TYPE_COLOR) +#endif // ENABLE(VIDEO) && USE(GSTREAMER) diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.cpp b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.cpp new file mode 100644 index 000000000..7618dffe0 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AcceleratedBackingStore.h" + +#include "WebPageProxy.h" +#include <WebCore/CairoUtilities.h> +#include <WebCore/PlatformDisplay.h> + +#if PLATFORM(WAYLAND) +#include "AcceleratedBackingStoreWayland.h" +#endif + +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) +#include "AcceleratedBackingStoreX11.h" +#endif + +using namespace WebCore; + +namespace WebKit { + +std::unique_ptr<AcceleratedBackingStore> AcceleratedBackingStore::create(WebPageProxy& webPage) +{ +#if PLATFORM(WAYLAND) && USE(EGL) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland) + return AcceleratedBackingStoreWayland::create(webPage); +#endif +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) + return AcceleratedBackingStoreX11::create(webPage); +#endif + return nullptr; +} + +AcceleratedBackingStore::AcceleratedBackingStore(WebPageProxy& webPage) + : m_webPage(webPage) +{ +} + +bool AcceleratedBackingStore::paint(cairo_t* cr, const IntRect& clipRect) +{ + if (m_webPage.drawsBackground()) + return true; + + const WebCore::Color& color = m_webPage.backgroundColor(); + if (!color.isOpaque()) { + cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_fill(cr); + } + + if (color.isVisible()) { + setSourceRGBAFromColor(cr, color); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); + cairo_fill(cr); + } + + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.h b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.h new file mode 100644 index 000000000..3de3b5dfa --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStore.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <wtf/Noncopyable.h> + +typedef struct _cairo cairo_t; + +namespace WebCore { +class IntRect; +} + +namespace WebKit { + +class LayerTreeContext; +class WebPageProxy; + +class AcceleratedBackingStore { + WTF_MAKE_NONCOPYABLE(AcceleratedBackingStore); WTF_MAKE_FAST_ALLOCATED; +public: + static std::unique_ptr<AcceleratedBackingStore> create(WebPageProxy&); + virtual ~AcceleratedBackingStore() = default; + + virtual void update(const LayerTreeContext&) { } + virtual bool paint(cairo_t*, const WebCore::IntRect&); + +protected: + AcceleratedBackingStore(WebPageProxy&); + + WebPageProxy& m_webPage; +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp new file mode 100644 index 000000000..12e03c43f --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AcceleratedBackingStoreWayland.h" + +#if PLATFORM(WAYLAND) && USE(EGL) + +#include "WaylandCompositor.h" +#include "WebPageProxy.h" +#include <WebCore/CairoUtilities.h> +#include <WebCore/RefPtrCairo.h> + +#if USE(OPENGL_ES_2) +#include <GLES2/gl2.h> +#else +#include <WebCore/OpenGLShims.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +std::unique_ptr<AcceleratedBackingStoreWayland> AcceleratedBackingStoreWayland::create(WebPageProxy& webPage) +{ + if (!WaylandCompositor::singleton().isRunning()) + return nullptr; + return std::unique_ptr<AcceleratedBackingStoreWayland>(new AcceleratedBackingStoreWayland(webPage)); +} + +AcceleratedBackingStoreWayland::AcceleratedBackingStoreWayland(WebPageProxy& webPage) + : AcceleratedBackingStore(webPage) +{ + WaylandCompositor::singleton().registerWebPage(m_webPage); +} + +AcceleratedBackingStoreWayland::~AcceleratedBackingStoreWayland() +{ + WaylandCompositor::singleton().unregisterWebPage(m_webPage); +} + +#if GTK_CHECK_VERSION(3, 16, 0) +bool AcceleratedBackingStoreWayland::canGdkUseGL() const +{ + static bool initialized = false; + static bool canCreateGLContext = false; + + if (initialized) + return canCreateGLContext; + + initialized = true; + + GUniqueOutPtr<GError> error; + GdkWindow* gdkWindow = gtk_widget_get_window(m_webPage.viewWidget()); + GRefPtr<GdkGLContext> gdkContext(gdk_window_create_gl_context(gdkWindow, &error.outPtr())); + if (!gdkContext) { + g_warning("GDK is not able to create a GL context, falling back to glReadPixels (slow!): %s", error->message); + return false; + } + + canCreateGLContext = true; + + return true; +} +#endif + +bool AcceleratedBackingStoreWayland::paint(cairo_t* cr, const IntRect& clipRect) +{ + GLuint texture; + IntSize textureSize; + if (!WaylandCompositor::singleton().getTexture(m_webPage, texture, textureSize)) + return false; + + cairo_save(cr); + AcceleratedBackingStore::paint(cr, clipRect); + +#if GTK_CHECK_VERSION(3, 16, 0) + if (canGdkUseGL()) { + gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(m_webPage.viewWidget()), texture, GL_TEXTURE, m_webPage.deviceScaleFactor(), 0, 0, textureSize.width(), textureSize.height()); + cairo_restore(cr); + return true; + } +#endif + + if (!m_surface || cairo_image_surface_get_width(m_surface.get()) != textureSize.width() || cairo_image_surface_get_height(m_surface.get()) != textureSize.height()) + m_surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, textureSize.width(), textureSize.height())); + + cairoSurfaceSetDeviceScale(m_surface.get(), m_webPage.deviceScaleFactor(), m_webPage.deviceScaleFactor()); + + GLuint fb; + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + glPixelStorei(GL_PACK_ALIGNMENT, 4); + +#if USE(OPENGL_ES_2) + unsigned char* data = cairo_image_surface_get_data(m_surface.get()); + if (cairo_image_surface_get_stride(m_surface.get()) == textureSize.width() * 4) + glReadPixels(0, 0, textureSize.width(), textureSize.height(), GL_RGBA, GL_UNSIGNED_BYTE, data); + else { + int strideBytes = cairo_image_surface_get_stride(m_surface.get()); + for (int i = 0; i < textureSize.height(); i++) { + unsigned char* dataOffset = data + i * strideBytes; + glReadPixels(0, i, textureSize.width(), 1, GL_RGBA, GL_UNSIGNED_BYTE, dataOffset); + } + } + + // Convert to BGRA. + int totalBytes = textureSize.width() * textureSize.height() * 4; + for (int i = 0; i < totalBytes; i += 4) + std::swap(data[i], data[i + 2]); +#else + glPixelStorei(GL_PACK_ROW_LENGTH, cairo_image_surface_get_stride(m_surface.get()) / 4); + glReadPixels(0, 0, textureSize.width(), textureSize.height(), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, cairo_image_surface_get_data(m_surface.get())); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); +#endif + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fb); + + // The surface can be modified by the web process at any time, so we mark it + // as dirty to ensure we always render the updated contents as soon as possible. + cairo_surface_mark_dirty(m_surface.get()); + + // The compositor renders the texture flipped for gdk_cairo_draw_from_gl, fix that here. + cairo_matrix_t transform; + cairo_matrix_init(&transform, 1, 0, 0, -1, 0, textureSize.height() / m_webPage.deviceScaleFactor()); + cairo_transform(cr, &transform); + + cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); + cairo_set_source_surface(cr, m_surface.get(), 0, 0); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_fill(cr); + + cairo_restore(cr); + + return true; +} + +} // namespace WebKit + +#endif // PLATFORM(WAYLAND) && USE(EGL) diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.h b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.h new file mode 100644 index 000000000..de6048aef --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreWayland.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "AcceleratedBackingStore.h" + +#if PLATFORM(WAYLAND) + +#include <WebCore/RefPtrCairo.h> +#include <gtk/gtk.h> + +namespace WebKit { + +class WebPageProxy; + +class AcceleratedBackingStoreWayland final : public AcceleratedBackingStore { + WTF_MAKE_NONCOPYABLE(AcceleratedBackingStoreWayland); WTF_MAKE_FAST_ALLOCATED; +public: + static std::unique_ptr<AcceleratedBackingStoreWayland> create(WebPageProxy&); + ~AcceleratedBackingStoreWayland(); + +#if GTK_CHECK_VERSION(3, 16, 0) + bool canGdkUseGL() const; +#endif + +private: + AcceleratedBackingStoreWayland(WebPageProxy&); + + bool paint(cairo_t*, const WebCore::IntRect&) override; + + RefPtr<cairo_surface_t> m_surface; +}; + +} // namespace WebKit + +#endif // PLATFORM(WAYLAND) diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.cpp b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.cpp new file mode 100644 index 000000000..d24a0238f --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AcceleratedBackingStoreX11.h" + +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) + +#include "DrawingAreaProxyImpl.h" +#include "LayerTreeContext.h" +#include "WebPageProxy.h" +#include <WebCore/CairoUtilities.h> +#include <WebCore/PlatformDisplayX11.h> +#include <WebCore/XErrorTrapper.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xdamage.h> +#include <cairo-xlib.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> + +using namespace WebCore; + +namespace WebKit { + +static std::optional<int> s_damageEventBase; +static std::optional<int> s_damageErrorBase; + +class XDamageNotifier { + WTF_MAKE_NONCOPYABLE(XDamageNotifier); + friend class NeverDestroyed<XDamageNotifier>; +public: + static XDamageNotifier& singleton() + { + static NeverDestroyed<XDamageNotifier> notifier; + return notifier; + } + + void add(Damage damage, std::function<void()>&& notifyFunction) + { + if (m_notifyFunctions.isEmpty()) + gdk_window_add_filter(nullptr, reinterpret_cast<GdkFilterFunc>(&filterXDamageEvent), this); + m_notifyFunctions.add(damage, WTFMove(notifyFunction)); + } + + void remove(Damage damage) + { + m_notifyFunctions.remove(damage); + if (m_notifyFunctions.isEmpty()) + gdk_window_remove_filter(nullptr, reinterpret_cast<GdkFilterFunc>(&filterXDamageEvent), this); + } + +private: + XDamageNotifier() = default; + + static GdkFilterReturn filterXDamageEvent(GdkXEvent* event, GdkEvent*, XDamageNotifier* notifier) + { + auto* xEvent = static_cast<XEvent*>(event); + if (xEvent->type != s_damageEventBase.value() + XDamageNotify) + return GDK_FILTER_CONTINUE; + + auto* damageEvent = reinterpret_cast<XDamageNotifyEvent*>(xEvent); + if (notifier->notify(damageEvent->damage)) { + XDamageSubtract(xEvent->xany.display, damageEvent->damage, None, None); + return GDK_FILTER_REMOVE; + } + + return GDK_FILTER_CONTINUE; + } + + bool notify(Damage damage) const + { + if (const auto& notifyFunction = m_notifyFunctions.get(damage)) { + notifyFunction(); + return true; + } + return false; + } + + HashMap<Damage, std::function<void()>> m_notifyFunctions; +}; + +std::unique_ptr<AcceleratedBackingStoreX11> AcceleratedBackingStoreX11::create(WebPageProxy& webPage) +{ + auto& display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()); + if (!display.supportsXComposite() || !display.supportsXDamage(s_damageEventBase, s_damageErrorBase)) + return nullptr; + return std::unique_ptr<AcceleratedBackingStoreX11>(new AcceleratedBackingStoreX11(webPage)); +} + +AcceleratedBackingStoreX11::AcceleratedBackingStoreX11(WebPageProxy& webPage) + : AcceleratedBackingStore(webPage) +{ +} + +static inline unsigned char xDamageErrorCode(unsigned char errorCode) +{ + ASSERT(s_damageErrorBase); + return static_cast<unsigned>(s_damageErrorBase.value()) + errorCode; +} + +AcceleratedBackingStoreX11::~AcceleratedBackingStoreX11() +{ + if (!m_surface && !m_damage) + return; + + Display* display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(); + XErrorTrapper trapper(display, XErrorTrapper::Policy::Crash, { BadDrawable, xDamageErrorCode(BadDamage) }); + if (m_damage) { + XDamageNotifier::singleton().remove(m_damage.get()); + m_damage.reset(); + XSync(display, False); + } +} + +void AcceleratedBackingStoreX11::update(const LayerTreeContext& layerTreeContext) +{ + Pixmap pixmap = layerTreeContext.contextID; + if (m_surface && cairo_xlib_surface_get_drawable(m_surface.get()) == pixmap) + return; + + Display* display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(); + + if (m_surface) { + XErrorTrapper trapper(display, XErrorTrapper::Policy::Crash, { BadDrawable, xDamageErrorCode(BadDamage) }); + if (m_damage) { + XDamageNotifier::singleton().remove(m_damage.get()); + m_damage.reset(); + XSync(display, False); + } + m_surface = nullptr; + } + + if (!pixmap) + return; + + DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(m_webPage.drawingArea()); + if (!drawingArea) + return; + + IntSize size = drawingArea->size(); + float deviceScaleFactor = m_webPage.deviceScaleFactor(); + size.scale(deviceScaleFactor); + + XErrorTrapper trapper(display, XErrorTrapper::Policy::Crash, { BadDrawable, xDamageErrorCode(BadDamage) }); + ASSERT(downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native() == GDK_DISPLAY_XDISPLAY(gdk_display_get_default())); + GdkVisual* visual = gdk_screen_get_rgba_visual(gdk_screen_get_default()); + if (!visual) + visual = gdk_screen_get_system_visual(gdk_screen_get_default()); + m_surface = adoptRef(cairo_xlib_surface_create(display, pixmap, GDK_VISUAL_XVISUAL(visual), size.width(), size.height())); + cairoSurfaceSetDeviceScale(m_surface.get(), deviceScaleFactor, deviceScaleFactor); + m_damage = XDamageCreate(display, pixmap, XDamageReportNonEmpty); + XDamageNotifier::singleton().add(m_damage.get(), [this] { + if (m_webPage.isViewVisible()) + gtk_widget_queue_draw(m_webPage.viewWidget()); + }); + XSync(display, False); +} + +bool AcceleratedBackingStoreX11::paint(cairo_t* cr, const IntRect& clipRect) +{ + if (!m_surface) + return false; + + cairo_save(cr); + AcceleratedBackingStore::paint(cr, clipRect); + + // The surface can be modified by the web process at any time, so we mark it + // as dirty to ensure we always render the updated contents as soon as possible. + cairo_surface_mark_dirty(m_surface.get()); + cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); + cairo_set_source_surface(cr, m_surface.get(), 0, 0); + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); + cairo_fill(cr); + + cairo_restore(cr); + + return true; +} + +} // namespace WebKit + +#endif // USE(REDIRECTED_XCOMPOSITE_WINDOW) diff --git a/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.h b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.h new file mode 100644 index 000000000..d9a7c2f3a --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/AcceleratedBackingStoreX11.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "AcceleratedBackingStore.h" + +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) + +#include <WebCore/RefPtrCairo.h> +#include <WebCore/XUniqueResource.h> + +namespace WebKit { + +class WebPageProxy; + +class AcceleratedBackingStoreX11 final : public AcceleratedBackingStore { + WTF_MAKE_NONCOPYABLE(AcceleratedBackingStoreX11); WTF_MAKE_FAST_ALLOCATED; +public: + static std::unique_ptr<AcceleratedBackingStoreX11> create(WebPageProxy&); + ~AcceleratedBackingStoreX11(); + +private: + AcceleratedBackingStoreX11(WebPageProxy&); + + void update(const LayerTreeContext&) override; + bool paint(cairo_t*, const WebCore::IntRect&) override; + + RefPtr<cairo_surface_t> m_surface; + WebCore::XUniqueDamage m_damage; +}; + +} // namespace WebKit + +#endif // USE(REDIRECTED_XCOMPOSITE_WINDOW) diff --git a/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.cpp b/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.cpp new file mode 100644 index 000000000..73fb54d37 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.cpp @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DragAndDropHandler.h" + +#if ENABLE(DRAG_SUPPORT) + +#include "WebPageProxy.h" +#include <WebCore/DragData.h> +#include <WebCore/GRefPtrGtk.h> +#include <WebCore/GtkUtilities.h> +#include <WebCore/PasteboardHelper.h> +#include <wtf/RunLoop.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebCore; + +namespace WebKit { + +DragAndDropHandler::DragAndDropHandler(WebPageProxy& page) + : m_page(page) +{ +} + +DragAndDropHandler::DroppingContext::DroppingContext(GdkDragContext* gdkContext, const IntPoint& position) + : gdkContext(gdkContext) + , lastMotionPosition(position) + , selectionData(SelectionData::create()) +{ +} + +static inline GdkDragAction dragOperationToGdkDragActions(DragOperation coreAction) +{ + GdkDragAction gdkAction = static_cast<GdkDragAction>(0); + if (coreAction == DragOperationNone) + return gdkAction; + + if (coreAction & DragOperationCopy) + gdkAction = static_cast<GdkDragAction>(GDK_ACTION_COPY | gdkAction); + if (coreAction & DragOperationMove) + gdkAction = static_cast<GdkDragAction>(GDK_ACTION_MOVE | gdkAction); + if (coreAction & DragOperationLink) + gdkAction = static_cast<GdkDragAction>(GDK_ACTION_LINK | gdkAction); + if (coreAction & DragOperationPrivate) + gdkAction = static_cast<GdkDragAction>(GDK_ACTION_PRIVATE | gdkAction); + + return gdkAction; +} + +static inline GdkDragAction dragOperationToSingleGdkDragAction(DragOperation coreAction) +{ + if (coreAction == DragOperationEvery || coreAction & DragOperationCopy) + return GDK_ACTION_COPY; + if (coreAction & DragOperationMove) + return GDK_ACTION_MOVE; + if (coreAction & DragOperationLink) + return GDK_ACTION_LINK; + if (coreAction & DragOperationPrivate) + return GDK_ACTION_PRIVATE; + return static_cast<GdkDragAction>(0); +} + +static inline DragOperation gdkDragActionToDragOperation(GdkDragAction gdkAction) +{ + // We have no good way to detect DragOperationEvery other than + // to use it when all applicable flags are on. + if (gdkAction & GDK_ACTION_COPY + && gdkAction & GDK_ACTION_MOVE + && gdkAction & GDK_ACTION_LINK + && gdkAction & GDK_ACTION_PRIVATE) + return DragOperationEvery; + + unsigned action = DragOperationNone; + if (gdkAction & GDK_ACTION_COPY) + action |= DragOperationCopy; + if (gdkAction & GDK_ACTION_MOVE) + action |= DragOperationMove; + if (gdkAction & GDK_ACTION_LINK) + action |= DragOperationLink; + if (gdkAction & GDK_ACTION_PRIVATE) + action |= DragOperationPrivate; + return static_cast<DragOperation>(action); +} + +void DragAndDropHandler::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage) +{ +#if GTK_CHECK_VERSION(3, 16, 0) + m_draggingSelectionData = WTFMove(selection); + GRefPtr<GtkTargetList> targetList = PasteboardHelper::singleton().targetListForSelectionData(*m_draggingSelectionData); +#else + RefPtr<SelectionData> selectionData = WTFMove(selection); + GRefPtr<GtkTargetList> targetList = PasteboardHelper::singleton().targetListForSelectionData(*selectionData); +#endif + + GUniquePtr<GdkEvent> currentEvent(gtk_get_current_event()); + GdkDragContext* context = gtk_drag_begin(m_page.viewWidget(), targetList.get(), dragOperationToGdkDragActions(dragOperation), + GDK_BUTTON_PRIMARY, currentEvent.get()); + +#if GTK_CHECK_VERSION(3, 16, 0) + // WebCore::EventHandler does not support more than one DnD operation at the same time for + // a given page, so we should cancel any previous operation whose context we might have + // stored, should we receive a new startDrag event before finishing a previous DnD operation. + if (m_dragContext) + gtk_drag_cancel(m_dragContext.get()); + m_dragContext = context; +#else + // We don't have gtk_drag_cancel() in GTK+ < 3.16, so we use the old code. + // See https://bugs.webkit.org/show_bug.cgi?id=138468 + m_draggingSelectionDataMap.set(context, WTFMove(selectionData)); +#endif + + if (dragImage) { + RefPtr<cairo_surface_t> image(dragImage->createCairoSurface()); + // Use the center of the drag image as hotspot. + cairo_surface_set_device_offset(image.get(), -cairo_image_surface_get_width(image.get()) / 2, -cairo_image_surface_get_height(image.get()) / 2); + gtk_drag_set_icon_surface(context, image.get()); + } else + gtk_drag_set_icon_default(context); +} + +void DragAndDropHandler::fillDragData(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info) +{ +#if GTK_CHECK_VERSION(3, 16, 0) + // This can happen when attempting to call finish drag from webkitWebViewBaseDragDataGet() + // for a obsolete DnD operation that got previously cancelled in startDrag(). + if (m_dragContext.get() != context) + return; + + ASSERT(m_draggingSelectionData); + PasteboardHelper::singleton().fillSelectionData(*m_draggingSelectionData, info, selectionData); +#else + if (auto* selection = m_draggingSelectionDataMap.get(context)) + PasteboardHelper::singleton().fillSelectionData(*selection, info, selectionData); +#endif +} + +void DragAndDropHandler::finishDrag(GdkDragContext* context) +{ +#if GTK_CHECK_VERSION(3, 16, 0) + // This can happen when attempting to call finish drag from webkitWebViewBaseDragEnd() + // for a obsolete DnD operation that got previously cancelled in startDrag(). + if (m_dragContext.get() != context) + return; + + if (!m_draggingSelectionData) + return; + + m_dragContext = nullptr; + m_draggingSelectionData = nullptr; +#else + if (!m_draggingSelectionDataMap.remove(context)) + return; +#endif + + GdkDevice* device = gdk_drag_context_get_device(context); + int x = 0, y = 0; + gdk_device_get_window_at_position(device, &x, &y); + int xRoot = 0, yRoot = 0; + gdk_device_get_position(device, nullptr, &xRoot, &yRoot); + m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context))); +} + +SelectionData* DragAndDropHandler::dropDataSelection(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info, IntPoint& position) +{ + DroppingContext* droppingContext = m_droppingContexts.get(context); + if (!droppingContext) + return nullptr; + + droppingContext->pendingDataRequests--; + PasteboardHelper::singleton().fillSelectionData(selectionData, info, droppingContext->selectionData); + if (droppingContext->pendingDataRequests) + return nullptr; + + // The coordinates passed to drag-data-received signal are sometimes + // inaccurate in WTR, so use the coordinates of the last motion event. + position = droppingContext->lastMotionPosition; + + // If there are no more pending requests, start sending dragging data to WebCore. + return droppingContext->selectionData.ptr(); +} + +void DragAndDropHandler::dragEntered(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info, unsigned time) +{ + IntPoint position; + auto* selection = dropDataSelection(context, selectionData, info, position); + if (!selection) + return; + + DragData dragData(selection, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); + m_page.resetCurrentDragInformation(); + m_page.dragEntered(dragData); + DragOperation operation = m_page.currentDragOperation(); + gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); +} + +SelectionData* DragAndDropHandler::dragDataSelection(GdkDragContext* context, const IntPoint& position, unsigned time) +{ + std::unique_ptr<DroppingContext>& droppingContext = m_droppingContexts.add(context, nullptr).iterator->value; + if (!droppingContext) { + GtkWidget* widget = m_page.viewWidget(); + droppingContext = std::make_unique<DroppingContext>(context, position); + Vector<GdkAtom> acceptableTargets(PasteboardHelper::singleton().dropAtomsForContext(widget, droppingContext->gdkContext)); + droppingContext->pendingDataRequests = acceptableTargets.size(); + for (auto& target : acceptableTargets) + gtk_drag_get_data(widget, droppingContext->gdkContext, target, time); + } else + droppingContext->lastMotionPosition = position; + + // Don't send any drag information to WebCore until we've retrieved all the data for this drag operation. + // Otherwise we'd have to block to wait for the drag's data. + if (droppingContext->pendingDataRequests > 0) + return nullptr; + + return droppingContext->selectionData.ptr(); +} + +void DragAndDropHandler::dragMotion(GdkDragContext* context, const IntPoint& position, unsigned time) +{ + auto* selection = dragDataSelection(context, position, time); + if (!selection) + return; + + DragData dragData(selection, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))); + m_page.dragUpdated(dragData); + DragOperation operation = m_page.currentDragOperation(); + gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time); +} + +void DragAndDropHandler::dragLeave(GdkDragContext* context) +{ + DroppingContext* droppingContext = m_droppingContexts.get(context); + if (!droppingContext) + return; + + // During a drop GTK+ will fire a drag-leave signal right before firing + // the drag-drop signal. We want the actions for drag-leave to happen after + // those for drag-drop, so schedule them to happen asynchronously here. + RunLoop::main().dispatch([this, droppingContext]() { + auto it = m_droppingContexts.find(droppingContext->gdkContext); + if (it == m_droppingContexts.end()) + return; + + // If the view doesn't know about the drag yet (there are still pending data requests), + // don't update it with information about the drag. + if (droppingContext->pendingDataRequests) + return; + + if (!droppingContext->dropHappened) { + // Don't call dragExited if we have just received a drag-drop signal. This + // happens in the case of a successful drop onto the view. + const IntPoint& position = droppingContext->lastMotionPosition; + DragData dragData(droppingContext->selectionData.ptr(), position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), DragOperationNone); + m_page.dragExited(dragData); + m_page.resetCurrentDragInformation(); + } + + m_droppingContexts.remove(it); + }); +} + +bool DragAndDropHandler::drop(GdkDragContext* context, const IntPoint& position, unsigned time) +{ + DroppingContext* droppingContext = m_droppingContexts.get(context); + if (!droppingContext) + return false; + + droppingContext->dropHappened = true; + + uint32_t flags = 0; + if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_COPY) + flags |= WebCore::DragApplicationIsCopyKeyDown; + DragData dragData(droppingContext->selectionData.ptr(), position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)), static_cast<WebCore::DragApplicationFlags>(flags)); + SandboxExtension::Handle handle; + SandboxExtension::HandleArray sandboxExtensionForUpload; + m_page.performDragOperation(dragData, String(), handle, sandboxExtensionForUpload); + gtk_drag_finish(context, TRUE, FALSE, time); + return true; +} + +} // namespace WebKit + +#endif // ENABLE(DRAG_SUPPORT) diff --git a/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.h b/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.h new file mode 100644 index 000000000..1c1ea3a93 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/DragAndDropHandler.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(DRAG_SUPPORT) + +#include <WebCore/DragActions.h> +#include <WebCore/IntPoint.h> +#include <WebCore/SelectionData.h> +#include <gtk/gtk.h> +#include <wtf/HashMap.h> +#include <wtf/Noncopyable.h> +#include <wtf/glib/GRefPtr.h> + +typedef struct _GdkDragContext GdkDragContext; +typedef struct _GtkSelectionData GtkSelectionData; + +namespace WebCore { +class DragData; +class SelectionData; +} + +namespace WebKit { + +class ShareableBitmap; +class WebPageProxy; + +class DragAndDropHandler { + WTF_MAKE_NONCOPYABLE(DragAndDropHandler); +public: + DragAndDropHandler(WebPageProxy&); + + void startDrag(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&& dragImage); + void fillDragData(GdkDragContext*, GtkSelectionData*, unsigned info); + void finishDrag(GdkDragContext*); + + void dragEntered(GdkDragContext*, GtkSelectionData*, unsigned info, unsigned time); + void dragMotion(GdkDragContext*, const WebCore::IntPoint& position, unsigned time); + void dragLeave(GdkDragContext*); + bool drop(GdkDragContext*, const WebCore::IntPoint& position, unsigned time); + +private: + struct DroppingContext { + DroppingContext(GdkDragContext*, const WebCore::IntPoint& position); + + GdkDragContext* gdkContext { nullptr }; + WebCore::IntPoint lastMotionPosition; + Ref<WebCore::SelectionData> selectionData; + unsigned pendingDataRequests { 0 }; + bool dropHappened { false }; + }; + + WebCore::SelectionData* dropDataSelection(GdkDragContext*, GtkSelectionData*, unsigned info, WebCore::IntPoint& position); + WebCore::SelectionData* dragDataSelection(GdkDragContext*, const WebCore::IntPoint& position, unsigned time); + + WebPageProxy& m_page; + HashMap<GdkDragContext*, std::unique_ptr<DroppingContext>> m_droppingContexts; + +#if GTK_CHECK_VERSION(3, 16, 0) + GRefPtr<GdkDragContext> m_dragContext; + RefPtr<WebCore::SelectionData> m_draggingSelectionData; +#else + // We don't have gtk_drag_cancel() in GTK+ < 3.16, so we use the old code. + // See https://bugs.webkit.org/show_bug.cgi?id=138468 + HashMap<GdkDragContext*, RefPtr<WebCore::SelectionData>> m_draggingSelectionDataMap; +#endif +}; + +} // namespace WebKit + +#endif // ENABLE(DRAG_SUPPORT) diff --git a/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.cpp b/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.cpp deleted file mode 100644 index 1b69302ac..000000000 --- a/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013, Opera Software ASA. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Opera Software ASA nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ExperimentalFeatures.h" - -namespace WebKit { - -struct Setting { - ExperimentalFeatures::Feature feature; - const char* featureName; - bool enabled; -}; - -static Setting settings[] = { - { ExperimentalFeatures::CSSGridLayout, "CSS_GRID_LAYOUT", false }, - { ExperimentalFeatures::RegionBasedColumns, "REGION_BASED_COLUMNS", false } -}; - -ExperimentalFeatures::ExperimentalFeatures() -{ - parseEnvironment(); -} - -bool ExperimentalFeatures::isEnabled(Feature feature) -{ - return settings[feature].enabled; -} - -void ExperimentalFeatures::setEnableByName(const String& key, bool enable) -{ - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(settings); i++) { - if (key == settings[i].featureName) { - settings[i].enabled = enable; - break; - } - } -} - -void ExperimentalFeatures::parseEnvironment() -{ - const char* data = getenv("WEBKITGTK_EXPERIMENTAL_FEATURES"); - if (!data) - return; - if (!strcmp(data, "all")) { - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(settings); i++) - settings[i].enabled = true; - } else { - Vector<String> variables; - String(data).split(',', false, variables); - for (unsigned i = 0; i < variables.size(); i++) { - Vector<String> keyAndValue; - variables[i].split('=', false, keyAndValue); - if (keyAndValue.size() != 2) - continue; - setEnableByName(keyAndValue[0], keyAndValue[1][0] - '0'); - } - } -} - -} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.h b/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.h deleted file mode 100644 index 59603cbf8..000000000 --- a/Source/WebKit2/UIProcess/gtk/ExperimentalFeatures.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013, Opera Software ASA. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Opera Software ASA nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ExperimentalFeatures_h -#define ExperimentalFeatures_h - -#include <wtf/text/WTFString.h> - -namespace WebKit { - -class ExperimentalFeatures { -public: - enum Feature { - CSSGridLayout, - RegionBasedColumns - }; - - ExperimentalFeatures(); - - bool isEnabled(Feature); - -private: - void setEnableByName(const String& key, bool enable); - void parseEnvironment(); -}; - -} // namespace WebKit - -#endif // ExperimentalFeatures_h diff --git a/Source/WebKit2/UIProcess/gtk/GestureController.cpp b/Source/WebKit2/UIProcess/gtk/GestureController.cpp new file mode 100644 index 000000000..7e1577cba --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/GestureController.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GestureController.h" + +#if HAVE(GTK_GESTURES) + +#include "NativeWebMouseEvent.h" +#include "NativeWebWheelEvent.h" +#include "WebPageProxy.h" +#include <WebCore/FloatPoint.h> +#include <WebCore/Scrollbar.h> +#include <gtk/gtk.h> + +using namespace WebCore; + +namespace WebKit { + +GestureController::GestureController(WebPageProxy& page) + : m_dragGesture(page) + , m_zoomGesture(page) +{ +} + +bool GestureController::handleEvent(const GdkEvent* event) +{ + bool wasProcessingGestures = isProcessingGestures(); + m_dragGesture.handleEvent(event); + m_zoomGesture.handleEvent(event); + return event->type == GDK_TOUCH_END ? wasProcessingGestures : isProcessingGestures(); +} + +bool GestureController::isProcessingGestures() const +{ + return m_dragGesture.isActive() || m_zoomGesture.isActive(); +} + +GestureController::Gesture::Gesture(GtkGesture* gesture, WebPageProxy& page) + : m_gesture(adoptGRef(gesture)) + , m_page(page) +{ + gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(m_gesture.get()), GTK_PHASE_NONE); +} + +bool GestureController::Gesture::isActive() const +{ + return gtk_gesture_is_active(m_gesture.get()); +} + +void GestureController::Gesture::handleEvent(const GdkEvent* event) +{ + gtk_event_controller_handle_event(GTK_EVENT_CONTROLLER(m_gesture.get()), event); +} + +void GestureController::DragGesture::handleDrag(const GdkEvent* event, double x, double y) +{ + ASSERT(m_inDrag); + GUniquePtr<GdkEvent> scrollEvent(gdk_event_new(GDK_SCROLL)); + scrollEvent->scroll.time = event->touch.time; + scrollEvent->scroll.x = m_start.x(); + scrollEvent->scroll.y = m_start.y(); + scrollEvent->scroll.x_root = event->touch.x_root; + scrollEvent->scroll.y_root = event->touch.y_root; + scrollEvent->scroll.direction = GDK_SCROLL_SMOOTH; + scrollEvent->scroll.delta_x = (m_offset.x() - x) / Scrollbar::pixelsPerLineStep(); + scrollEvent->scroll.delta_y = (m_offset.y() - y) / Scrollbar::pixelsPerLineStep(); + scrollEvent->scroll.state = event->touch.state; + m_page.handleWheelEvent(NativeWebWheelEvent(scrollEvent.get())); +} + +void GestureController::DragGesture::handleTap(const GdkEvent* event) +{ + ASSERT(!m_inDrag); + GUniquePtr<GdkEvent> pointerEvent(gdk_event_new(GDK_MOTION_NOTIFY)); + pointerEvent->motion.time = event->touch.time; + pointerEvent->motion.x = event->touch.x; + pointerEvent->motion.y = event->touch.y; + pointerEvent->motion.x_root = event->touch.x_root; + pointerEvent->motion.y_root = event->touch.y_root; + pointerEvent->motion.state = event->touch.state; + m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 0)); + + pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS)); + pointerEvent->button.button = 1; + pointerEvent->button.time = event->touch.time; + pointerEvent->button.x = event->touch.x; + pointerEvent->button.y = event->touch.y; + pointerEvent->button.x_root = event->touch.x_root; + pointerEvent->button.y_root = event->touch.y_root; + m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 1)); + + pointerEvent->type = GDK_BUTTON_RELEASE; + m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 0)); +} + +void GestureController::DragGesture::begin(DragGesture* dragGesture, double x, double y, GtkGesture* gesture) +{ + GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); + gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED); + dragGesture->m_inDrag = false; + dragGesture->m_start.set(x, y); + dragGesture->m_offset.set(0, 0); + + GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)); + unsigned delay; + g_object_get(gtk_widget_get_settings(widget), "gtk-long-press-time", &delay, nullptr); + dragGesture->m_longPressTimeout.startOneShot(delay / 1000.0); +} + +void GestureController::DragGesture::update(DragGesture* dragGesture, double x, double y, GtkGesture* gesture) +{ + GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); + gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED); + + GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture)); + if (!dragGesture->m_inDrag && gtk_drag_check_threshold(widget, dragGesture->m_start.x(), dragGesture->m_start.y(), dragGesture->m_start.x() + x, dragGesture->m_start.y() + y)) { + dragGesture->m_inDrag = true; + dragGesture->m_longPressTimeout.stop(); + } + + if (dragGesture->m_inDrag) + dragGesture->handleDrag(gtk_gesture_get_last_event(gesture, sequence), x, y); + dragGesture->m_offset.set(x, y); +} + +void GestureController::DragGesture::end(DragGesture* dragGesture, GdkEventSequence* sequence, GtkGesture* gesture) +{ + dragGesture->m_longPressTimeout.stop(); + if (!dragGesture->m_inDrag) { + dragGesture->handleTap(gtk_gesture_get_last_event(gesture, sequence)); + gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_DENIED); + } else if (!gtk_gesture_handles_sequence(gesture, sequence)) + gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_DENIED); +} + +void GestureController::DragGesture::longPressFired() +{ + m_inDrag = true; +} + +GestureController::DragGesture::DragGesture(WebPageProxy& page) + : Gesture(gtk_gesture_drag_new(page.viewWidget()), page) + , m_longPressTimeout(RunLoop::main(), this, &GestureController::DragGesture::longPressFired) + , m_inDrag(false) +{ + gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE); + g_signal_connect_swapped(m_gesture.get(), "drag-begin", G_CALLBACK(begin), this); + g_signal_connect_swapped(m_gesture.get(), "drag-update", G_CALLBACK(update), this); + g_signal_connect_swapped(m_gesture.get(), "end", G_CALLBACK(end), this); +} + +IntPoint GestureController::ZoomGesture::center() const +{ + double x, y; + gtk_gesture_get_bounding_box_center(m_gesture.get(), &x, &y); + return IntPoint(x, y); +} + +void GestureController::ZoomGesture::begin(ZoomGesture* zoomGesture, GdkEventSequence*, GtkGesture* gesture) +{ + gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED); + + zoomGesture->m_initialScale = zoomGesture->m_page.pageScaleFactor(); + zoomGesture->m_page.getCenterForZoomGesture(zoomGesture->center(), zoomGesture->m_initialPoint); +} + +void GestureController::ZoomGesture::handleZoom() +{ + IntPoint scaledOriginOffset = m_viewPoint; + scaledOriginOffset.scale(1 / m_scale, 1 / m_scale); + + IntPoint newOrigin = m_initialPoint; + newOrigin.moveBy(-scaledOriginOffset); + newOrigin.scale(m_scale, m_scale); + + m_page.scalePage(m_scale, newOrigin); +} + +void GestureController::ZoomGesture::scaleChanged(ZoomGesture* zoomGesture, double scale, GtkGesture*) +{ + zoomGesture->m_scale = zoomGesture->m_initialScale * scale; + zoomGesture->m_viewPoint = zoomGesture->center(); + if (zoomGesture->m_idle.isActive()) + return; + + zoomGesture->m_idle.startOneShot(0); +} + +GestureController::ZoomGesture::ZoomGesture(WebPageProxy& page) + : Gesture(gtk_gesture_zoom_new(page.viewWidget()), page) + , m_initialScale(0) + , m_scale(0) + , m_idle(RunLoop::main(), this, &GestureController::ZoomGesture::handleZoom) +{ + g_signal_connect_swapped(m_gesture.get(), "begin", G_CALLBACK(begin), this); + g_signal_connect_swapped(m_gesture.get(), "scale-changed", G_CALLBACK(scaleChanged), this); +} + +} // namespace WebKit + +#endif // HAVE(GTK_GESTURES) diff --git a/Source/WebKit2/UIProcess/gtk/GestureController.h b/Source/WebKit2/UIProcess/gtk/GestureController.h new file mode 100644 index 000000000..86792df42 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/GestureController.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GestureController_h +#define GestureController_h + +#if HAVE(GTK_GESTURES) + +#include <WebCore/FloatPoint.h> +#include <wtf/Noncopyable.h> +#include <wtf/RunLoop.h> +#include <wtf/glib/GRefPtr.h> + +typedef union _GdkEvent GdkEvent; +typedef struct _GdkEventSequence GdkEventSequence; +typedef struct _GtkGesture GtkGesture; + +namespace WebKit { +class WebPageProxy; + +class GestureController { + WTF_MAKE_NONCOPYABLE(GestureController); + +public: + GestureController(WebPageProxy&); + + bool isProcessingGestures() const; + bool handleEvent(const GdkEvent*); + +private: + class Gesture { + public: + bool isActive() const; + void handleEvent(const GdkEvent*); + + protected: + Gesture(GtkGesture*, WebPageProxy&); + + GRefPtr<GtkGesture> m_gesture; + WebPageProxy& m_page; + }; + + class DragGesture final : public Gesture { + public: + DragGesture(WebPageProxy&); + + private: + void handleDrag(const GdkEvent*, double x, double y); + void handleTap(const GdkEvent*); + void longPressFired(); + + static void begin(DragGesture*, double x, double y, GtkGesture*); + static void update(DragGesture*, double x, double y, GtkGesture*); + static void end(DragGesture*, GdkEventSequence*, GtkGesture*); + + WebCore::FloatPoint m_start; + WebCore::FloatPoint m_offset; + RunLoop::Timer<DragGesture> m_longPressTimeout; + GRefPtr<GtkGesture> m_longPress; + bool m_inDrag; + }; + + class ZoomGesture final : public Gesture { + public: + ZoomGesture(WebPageProxy&); + + private: + WebCore::IntPoint center() const; + void handleZoom(); + + static void begin(ZoomGesture*, GdkEventSequence*, GtkGesture*); + static void scaleChanged(ZoomGesture*, double scale, GtkGesture*); + + gdouble m_initialScale; + gdouble m_scale; + WebCore::IntPoint m_initialPoint; + WebCore::IntPoint m_viewPoint; + RunLoop::Timer<ZoomGesture> m_idle; + }; + + DragGesture m_dragGesture; + ZoomGesture m_zoomGesture; +}; + +} // namespace WebKit + +#endif // HAVE(GTK_GESTURES) + +#endif // GestureController_h diff --git a/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.cpp b/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.cpp new file mode 100644 index 000000000..e06e629a4 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "HardwareAccelerationManager.h" + +#include "WaylandCompositor.h" +#include <WebCore/NotImplemented.h> +#include <WebCore/PlatformDisplay.h> + +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) +#include <WebCore/PlatformDisplayX11.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +HardwareAccelerationManager& HardwareAccelerationManager::singleton() +{ + static NeverDestroyed<HardwareAccelerationManager> manager; + return manager; +} + +HardwareAccelerationManager::HardwareAccelerationManager() + : m_canUseHardwareAcceleration(true) + , m_forceHardwareAcceleration(false) +{ +#if !ENABLE(OPENGL) + m_canUseHardwareAcceleration = false; + return; +#endif + + const char* disableCompositing = getenv("WEBKIT_DISABLE_COMPOSITING_MODE"); + if (disableCompositing && strcmp(disableCompositing, "0")) { + m_canUseHardwareAcceleration = false; + return; + } + +#if USE(REDIRECTED_XCOMPOSITE_WINDOW) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + auto& display = downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()); + std::optional<int> damageBase, errorBase; + if (!display.supportsXComposite() || !display.supportsXDamage(damageBase, errorBase)) { + m_canUseHardwareAcceleration = false; + return; + } + } +#endif + +#if PLATFORM(WAYLAND) && USE(EGL) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland) { + if (!WaylandCompositor::singleton().isRunning()) { + m_canUseHardwareAcceleration = false; + return; + } + } +#endif + + const char* forceCompositing = getenv("WEBKIT_FORCE_COMPOSITING_MODE"); + if (forceCompositing && strcmp(forceCompositing, "0")) + m_forceHardwareAcceleration = true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.h b/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.h new file mode 100644 index 000000000..4fa233b5a --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/HardwareAccelerationManager.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <wtf/NeverDestroyed.h> + +namespace WebKit { + +class HardwareAccelerationManager { + WTF_MAKE_NONCOPYABLE(HardwareAccelerationManager); + friend class NeverDestroyed<HardwareAccelerationManager>; +public: + static HardwareAccelerationManager& singleton(); + + bool canUseHardwareAcceleration() const { return m_canUseHardwareAcceleration; } + bool forceHardwareAcceleration() const { return m_forceHardwareAcceleration; } + +private: + HardwareAccelerationManager(); + + bool m_canUseHardwareAcceleration : 1; + bool m_forceHardwareAcceleration : 1; +}; + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/InputMethodFilter.cpp b/Source/WebKit2/UIProcess/gtk/InputMethodFilter.cpp new file mode 100644 index 000000000..fc098ac67 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/InputMethodFilter.cpp @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2012, 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "InputMethodFilter.h" + +#include "NativeWebKeyboardEvent.h" +#include "WebPageProxy.h" +#include <WebCore/Color.h> +#include <WebCore/CompositionResults.h> +#include <WebCore/Editor.h> +#include <WebCore/GUniquePtrGtk.h> +#include <WebCore/IntRect.h> +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> +#include <wtf/Vector.h> +#include <wtf/glib/GUniquePtr.h> + +using namespace WebCore; + +namespace WebKit { + +void InputMethodFilter::handleCommitCallback(InputMethodFilter* filter, const char* compositionString) +{ + filter->handleCommit(compositionString); +} + +void InputMethodFilter::handlePreeditStartCallback(InputMethodFilter* filter) +{ + filter->handlePreeditStart(); +} + +void InputMethodFilter::handlePreeditChangedCallback(InputMethodFilter* filter) +{ + filter->handlePreeditChanged(); +} + +void InputMethodFilter::handlePreeditEndCallback(InputMethodFilter* filter) +{ + filter->handlePreeditEnd(); +} + +InputMethodFilter::InputMethodFilter() + : m_context(adoptGRef(gtk_im_multicontext_new())) + , m_page(nullptr) + , m_enabled(false) + , m_composingTextCurrently(false) + , m_filteringKeyEvent(false) + , m_preeditChanged(false) + , m_preventNextCommit(false) + , m_justSentFakeKeyUp(false) + , m_cursorOffset(0) + , m_lastFilteredKeyPressCodeWithNoResults(GDK_KEY_VoidSymbol) +#if ENABLE(API_TESTS) + , m_testingMode(false) +#endif +{ + g_signal_connect_swapped(m_context.get(), "commit", G_CALLBACK(handleCommitCallback), this); + g_signal_connect_swapped(m_context.get(), "preedit-start", G_CALLBACK(handlePreeditStartCallback), this); + g_signal_connect_swapped(m_context.get(), "preedit-changed", G_CALLBACK(handlePreeditChangedCallback), this); + g_signal_connect_swapped(m_context.get(), "preedit-end", G_CALLBACK(handlePreeditEndCallback), this); +} + +InputMethodFilter::~InputMethodFilter() +{ + g_signal_handlers_disconnect_matched(m_context.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); +} + +void InputMethodFilter::setEnabled(bool enabled) +{ + ASSERT(m_page); + + // Notify focus out before changing the m_enabled. + if (!enabled) + notifyFocusedOut(); + m_enabled = enabled; + if (enabled) + notifyFocusedIn(); +} + +void InputMethodFilter::setCursorRect(const IntRect& cursorRect) +{ + ASSERT(m_page); + + if (!m_enabled) + return; + + // Don't move the window unless the cursor actually moves more than 10 + // pixels. This prevents us from making the window flash during minor + // cursor adjustments. + static const int windowMovementThreshold = 10 * 10; + if (cursorRect.location().distanceSquaredToPoint(m_lastCareLocation) < windowMovementThreshold) + return; + + m_lastCareLocation = cursorRect.location(); + IntRect translatedRect = cursorRect; + + GtkAllocation allocation; + gtk_widget_get_allocation(m_page->viewWidget(), &allocation); + translatedRect.move(allocation.x, allocation.y); + + GdkRectangle gdkCursorRect = translatedRect; + gtk_im_context_set_cursor_location(m_context.get(), &gdkCursorRect); +} + +void InputMethodFilter::handleKeyboardEvent(GdkEventKey* event, const String& simpleString, EventFakedForComposition faked) +{ +#if ENABLE(API_TESTS) + if (m_testingMode) { + logHandleKeyboardEventForTesting(event, simpleString, faked); + return; + } +#endif + + if (m_filterKeyEventCompletionHandler) { + m_filterKeyEventCompletionHandler(CompositionResults(simpleString), faked); + m_filterKeyEventCompletionHandler = nullptr; + } else + m_page->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), CompositionResults(simpleString), faked, Vector<String>())); +} + +void InputMethodFilter::handleKeyboardEventWithCompositionResults(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) +{ +#if ENABLE(API_TESTS) + if (m_testingMode) { + logHandleKeyboardEventWithCompositionResultsForTesting(event, resultsToSend, faked); + return; + } +#endif + + if (m_filterKeyEventCompletionHandler) { + m_filterKeyEventCompletionHandler(CompositionResults(CompositionResults::WillSendCompositionResultsSoon), faked); + m_filterKeyEventCompletionHandler = nullptr; + } else + m_page->handleKeyboardEvent(NativeWebKeyboardEvent(reinterpret_cast<GdkEvent*>(event), CompositionResults(CompositionResults::WillSendCompositionResultsSoon), faked, Vector<String>())); + if (resultsToSend & Composition && !m_confirmedComposition.isNull()) + m_page->confirmComposition(m_confirmedComposition, -1, 0); + + if (resultsToSend & Preedit && !m_preedit.isNull()) { + m_page->setComposition(m_preedit, Vector<CompositionUnderline>{ CompositionUnderline(0, m_preedit.length(), Color(1, 1, 1), false) }, + m_cursorOffset, m_cursorOffset, 0 /* replacement start */, 0 /* replacement end */); + } +} + +void InputMethodFilter::filterKeyEvent(GdkEventKey* event, FilterKeyEventCompletionHandler&& completionHandler) +{ +#if ENABLE(API_TESTS) + ASSERT(m_page || m_testingMode); +#else + ASSERT(m_page); +#endif + m_filterKeyEventCompletionHandler = WTFMove(completionHandler); + if (!m_enabled) { + handleKeyboardEvent(event); + return; + } + + m_preeditChanged = false; + m_filteringKeyEvent = true; + + unsigned lastFilteredKeyPressCodeWithNoResults = m_lastFilteredKeyPressCodeWithNoResults; + m_lastFilteredKeyPressCodeWithNoResults = GDK_KEY_VoidSymbol; + + bool filtered = gtk_im_context_filter_keypress(m_context.get(), event); + m_filteringKeyEvent = false; + + bool justSentFakeKeyUp = m_justSentFakeKeyUp; + m_justSentFakeKeyUp = false; + if (justSentFakeKeyUp && event->type == GDK_KEY_RELEASE) + return; + + // Simple input methods work such that even normal keystrokes fire the + // commit signal. We detect those situations and treat them as normal + // key events, supplying the commit string as the key character. + if (filtered && !m_composingTextCurrently && !m_preeditChanged && m_confirmedComposition.length() == 1) { + handleKeyboardEvent(event, m_confirmedComposition); + m_confirmedComposition = String(); + return; + } + + if (filtered && event->type == GDK_KEY_PRESS) { + if (!m_preeditChanged && m_confirmedComposition.isNull()) { + m_composingTextCurrently = true; + m_lastFilteredKeyPressCodeWithNoResults = event->keyval; + return; + } + + handleKeyboardEventWithCompositionResults(event); + if (!m_confirmedComposition.isEmpty()) { + m_composingTextCurrently = false; + m_confirmedComposition = String(); + } + return; + } + + // If we previously filtered a key press event and it yielded no results. Suppress + // the corresponding key release event to avoid confusing the web content. + if (event->type == GDK_KEY_RELEASE && lastFilteredKeyPressCodeWithNoResults == event->keyval) + return; + + // At this point a keystroke was either: + // 1. Unfiltered + // 2. A filtered keyup event. As the IME code in EditorClient.h doesn't + // ever look at keyup events, we send any composition results before + // the key event. + // Both might have composition results or not. + // + // It's important to send the composition results before the event + // because some IM modules operate that way. For example (taken from + // the Chromium source), the latin-post input method gives this sequence + // when you press 'a' and then backspace: + // 1. keydown 'a' (filtered) + // 2. preedit changed to "a" + // 3. keyup 'a' (unfiltered) + // 4. keydown Backspace (unfiltered) + // 5. commit "a" + // 6. preedit end + if (!m_confirmedComposition.isEmpty()) + confirmComposition(); + if (m_preeditChanged) + updatePreedit(); + handleKeyboardEvent(event); +} + +void InputMethodFilter::confirmComposition() +{ +#if ENABLE(API_TESTS) + if (m_testingMode) { + logConfirmCompositionForTesting(); + m_confirmedComposition = String(); + return; + } +#endif + m_page->confirmComposition(m_confirmedComposition, -1, 0); + m_confirmedComposition = String(); +} + +void InputMethodFilter::updatePreedit() +{ +#if ENABLE(API_TESTS) + if (m_testingMode) { + logSetPreeditForTesting(); + return; + } +#endif + // FIXME: We should parse the PangoAttrList that we get from the IM context here. + m_page->setComposition(m_preedit, Vector<CompositionUnderline>{ CompositionUnderline(0, m_preedit.length(), Color(1, 1, 1), false) }, + m_cursorOffset, m_cursorOffset, 0 /* replacement start */, 0 /* replacement end */); + m_preeditChanged = false; +} + +void InputMethodFilter::notifyFocusedIn() +{ +#if ENABLE(API_TESTS) + ASSERT(m_page || m_testingMode); +#else + ASSERT(m_page); +#endif + if (!m_enabled) + return; + + gtk_im_context_focus_in(m_context.get()); +} + +void InputMethodFilter::notifyFocusedOut() +{ +#if ENABLE(API_TESTS) + ASSERT(m_page || m_testingMode); +#else + ASSERT(m_page); +#endif + if (!m_enabled) + return; + + confirmCurrentComposition(); + cancelContextComposition(); + gtk_im_context_focus_out(m_context.get()); +} + +void InputMethodFilter::notifyMouseButtonPress() +{ +#if ENABLE(API_TESTS) + ASSERT(m_page || m_testingMode); +#else + ASSERT(m_page); +#endif + + // Confirming the composition may trigger a selection change, which + // might trigger further unwanted actions on the context, so we prevent + // that by setting m_composingTextCurrently to false. + confirmCurrentComposition(); + cancelContextComposition(); +} + +void InputMethodFilter::confirmCurrentComposition() +{ + if (!m_composingTextCurrently) + return; + m_page->confirmComposition(String(), -1, 0); + m_composingTextCurrently = false; +} + +void InputMethodFilter::cancelContextComposition() +{ + m_preventNextCommit = !m_preedit.isEmpty(); + + gtk_im_context_reset(m_context.get()); + + m_composingTextCurrently = false; + m_justSentFakeKeyUp = false; + m_preedit = String(); + m_confirmedComposition = String(); +} + +void InputMethodFilter::sendCompositionAndPreeditWithFakeKeyEvents(ResultsToSend resultsToSend) +{ + // The Windows composition key event code is 299 or VK_PROCESSKEY. We need to + // emit this code for web compatibility reasons when key events trigger + // composition results. GDK doesn't have an equivalent, so we send VoidSymbol + // here to WebCore. PlatformKeyEvent knows to convert this code into + // VK_PROCESSKEY. + static const int compositionEventKeyCode = GDK_KEY_VoidSymbol; + + GUniquePtr<GdkEvent> event(gdk_event_new(GDK_KEY_PRESS)); + event->key.time = GDK_CURRENT_TIME; + event->key.keyval = compositionEventKeyCode; + handleKeyboardEventWithCompositionResults(&event->key, resultsToSend, EventFaked); + + m_confirmedComposition = String(); + if (resultsToSend & Composition) + m_composingTextCurrently = false; + + event->type = GDK_KEY_RELEASE; + handleKeyboardEvent(&event->key, String(), EventFaked); + m_justSentFakeKeyUp = true; +} + +void InputMethodFilter::handleCommit(const char* compositionString) +{ + if (m_preventNextCommit) { + m_preventNextCommit = false; + return; + } + + if (!m_enabled) + return; + + m_confirmedComposition.append(String::fromUTF8(compositionString)); + + // If the commit was triggered outside of a key event, just send + // the IME event now. If we are handling a key event, we'll decide + // later how to handle this. + if (!m_filteringKeyEvent) + sendCompositionAndPreeditWithFakeKeyEvents(Composition); +} + +void InputMethodFilter::handlePreeditStart() +{ + if (m_preventNextCommit || !m_enabled) + return; + m_preeditChanged = true; + m_preedit = emptyString(); +} + +void InputMethodFilter::handlePreeditChanged() +{ + if (!m_enabled) + return; + + GUniqueOutPtr<gchar> newPreedit; + gtk_im_context_get_preedit_string(m_context.get(), &newPreedit.outPtr(), nullptr, &m_cursorOffset); + + if (m_preventNextCommit) { + if (strlen(newPreedit.get()) > 0) + m_preventNextCommit = false; + else + return; + } + + m_preedit = String::fromUTF8(newPreedit.get()); + m_cursorOffset = std::min(std::max(m_cursorOffset, 0), static_cast<int>(m_preedit.length())); + + m_composingTextCurrently = !m_preedit.isEmpty(); + m_preeditChanged = true; + + if (!m_filteringKeyEvent) + sendCompositionAndPreeditWithFakeKeyEvents(Preedit); +} + +void InputMethodFilter::handlePreeditEnd() +{ + if (m_preventNextCommit || !m_enabled) + return; + + m_preedit = String(); + m_cursorOffset = 0; + m_preeditChanged = true; + + if (!m_filteringKeyEvent) + updatePreedit(); +} + +#if ENABLE(API_TESTS) +void InputMethodFilter::logHandleKeyboardEventForTesting(GdkEventKey* event, const String& eventString, EventFakedForComposition faked) +{ + const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; + const char* fakedString = faked == EventFaked ? " (faked)" : ""; + if (!eventString.isNull()) + m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x text='%s'%s", eventType, event->keyval, eventString.utf8().data(), fakedString)); + else + m_events.append(String::format("sendSimpleKeyEvent type=%s keycode=%x%s", eventType, event->keyval, fakedString)); +} + +void InputMethodFilter::logHandleKeyboardEventWithCompositionResultsForTesting(GdkEventKey* event, ResultsToSend resultsToSend, EventFakedForComposition faked) +{ + const char* eventType = event->type == GDK_KEY_RELEASE ? "release" : "press"; + const char* fakedString = faked == EventFaked ? " (faked)" : ""; + m_events.append(String::format("sendKeyEventWithCompositionResults type=%s keycode=%u%s", eventType, event->keyval, fakedString)); + + if (resultsToSend & Composition && !m_confirmedComposition.isNull()) + logConfirmCompositionForTesting(); + if (resultsToSend & Preedit && !m_preedit.isNull()) + logSetPreeditForTesting(); +} + +void InputMethodFilter::logConfirmCompositionForTesting() +{ + if (m_confirmedComposition.isEmpty()) + m_events.append(String("confirmCurrentcomposition")); + else + m_events.append(String::format("confirmComposition '%s'", m_confirmedComposition.utf8().data())); +} + +void InputMethodFilter::logSetPreeditForTesting() +{ + m_events.append(String::format("setPreedit text='%s' cursorOffset=%i", m_preedit.utf8().data(), m_cursorOffset)); +} +#endif // ENABLE(API_TESTS) + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/InputMethodFilter.h b/Source/WebKit2/UIProcess/gtk/InputMethodFilter.h new file mode 100644 index 000000000..f6d66eb5a --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/InputMethodFilter.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2012, 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef InputMethodFilter_h +#define InputMethodFilter_h + +#include <WebCore/IntPoint.h> +#include <wtf/Function.h> +#include <wtf/Noncopyable.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/WTFString.h> + +typedef struct _GdkEventKey GdkEventKey; +typedef struct _GtkIMContext GtkIMContext; + +namespace WebCore { +struct CompositionResults; +class IntRect; +} + +namespace WebKit { + +class WebPageProxy; + +class InputMethodFilter { + WTF_MAKE_NONCOPYABLE(InputMethodFilter); +public: + enum EventFakedForComposition { + EventFaked, + EventNotFaked + }; + + InputMethodFilter(); + ~InputMethodFilter(); + + GtkIMContext* context() const { return m_context.get(); } + + void setPage(WebPageProxy* page) { m_page = page; } + + void setEnabled(bool); + void setCursorRect(const WebCore::IntRect&); + + using FilterKeyEventCompletionHandler = Function<void(const WebCore::CompositionResults&, InputMethodFilter::EventFakedForComposition)>; + void filterKeyEvent(GdkEventKey*, FilterKeyEventCompletionHandler&& = nullptr); + void notifyFocusedIn(); + void notifyFocusedOut(); + void notifyMouseButtonPress(); + +#if ENABLE(API_TESTS) + void setTestingMode(bool enable) { m_testingMode = enable; } + const Vector<String>& events() const { return m_events; } +#endif + +private: + enum ResultsToSend { + Preedit = 1 << 1, + Composition = 1 << 2, + PreeditAndComposition = Preedit | Composition + }; + + static void handleCommitCallback(InputMethodFilter*, const char* compositionString); + static void handlePreeditStartCallback(InputMethodFilter*); + static void handlePreeditChangedCallback(InputMethodFilter*); + static void handlePreeditEndCallback(InputMethodFilter*); + + void handleCommit(const char* compositionString); + void handlePreeditChanged(); + void handlePreeditStart(); + void handlePreeditEnd(); + + void handleKeyboardEvent(GdkEventKey*, const String& eventString = String(), EventFakedForComposition = EventNotFaked); + void handleKeyboardEventWithCompositionResults(GdkEventKey*, ResultsToSend = PreeditAndComposition, EventFakedForComposition = EventNotFaked); + + void sendCompositionAndPreeditWithFakeKeyEvents(ResultsToSend); + void confirmComposition(); + void updatePreedit(); + void confirmCurrentComposition(); + void cancelContextComposition(); + +#if ENABLE(API_TESTS) + void logHandleKeyboardEventForTesting(GdkEventKey*, const String&, EventFakedForComposition); + void logHandleKeyboardEventWithCompositionResultsForTesting(GdkEventKey*, ResultsToSend, EventFakedForComposition); + void logConfirmCompositionForTesting(); + void logSetPreeditForTesting(); +#endif + + GRefPtr<GtkIMContext> m_context; + WebPageProxy* m_page; + unsigned m_enabled : 1; + unsigned m_composingTextCurrently : 1; + unsigned m_filteringKeyEvent : 1; + unsigned m_preeditChanged : 1; + unsigned m_preventNextCommit : 1; + unsigned m_justSentFakeKeyUp : 1; + int m_cursorOffset; + unsigned m_lastFilteredKeyPressCodeWithNoResults; + WebCore::IntPoint m_lastCareLocation; + String m_confirmedComposition; + String m_preedit; + + FilterKeyEventCompletionHandler m_filterKeyEventCompletionHandler; + +#if ENABLE(API_TESTS) + bool m_testingMode; + Vector<String> m_events; +#endif +}; + +} // namespace WebKit + +#endif // InputMethodFilter_h diff --git a/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.cpp b/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.cpp new file mode 100644 index 000000000..f179f16f0 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2010, 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "KeyBindingTranslator.h" + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +namespace WebKit { + +static void backspaceCallback(GtkWidget* widget, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "backspace"); + translator->addPendingEditorCommand("DeleteBackward"); +} + +static void selectAllCallback(GtkWidget* widget, gboolean select, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "select-all"); + translator->addPendingEditorCommand(select ? "SelectAll" : "Unselect"); +} + +static void cutClipboardCallback(GtkWidget* widget, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "cut-clipboard"); + translator->addPendingEditorCommand("Cut"); +} + +static void copyClipboardCallback(GtkWidget* widget, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "copy-clipboard"); + translator->addPendingEditorCommand("Copy"); +} + +static void pasteClipboardCallback(GtkWidget* widget, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "paste-clipboard"); + translator->addPendingEditorCommand("Paste"); +} + +static void toggleOverwriteCallback(GtkWidget* widget, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "toggle-overwrite"); + translator->addPendingEditorCommand("OverWrite"); +} + +// GTK+ will still send these signals to the web view. So we can safely stop signal +// emission without breaking accessibility. +static void popupMenuCallback(GtkWidget* widget, KeyBindingTranslator*) +{ + g_signal_stop_emission_by_name(widget, "popup-menu"); +} + +static void showHelpCallback(GtkWidget* widget, KeyBindingTranslator*) +{ + g_signal_stop_emission_by_name(widget, "show-help"); +} + +static const char* const gtkDeleteCommands[][2] = { + { "DeleteBackward", "DeleteForward" }, // Characters + { "DeleteWordBackward", "DeleteWordForward" }, // Word ends + { "DeleteWordBackward", "DeleteWordForward" }, // Words + { "DeleteToBeginningOfLine", "DeleteToEndOfLine" }, // Lines + { "DeleteToBeginningOfLine", "DeleteToEndOfLine" }, // Line ends + { "DeleteToBeginningOfParagraph", "DeleteToEndOfParagraph" }, // Paragraph ends + { "DeleteToBeginningOfParagraph", "DeleteToEndOfParagraph" }, // Paragraphs + { 0, 0 } // Whitespace (M-\ in Emacs) +}; + +static void deleteFromCursorCallback(GtkWidget* widget, GtkDeleteType deleteType, gint count, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "delete-from-cursor"); + int direction = count > 0 ? 1 : 0; + + // Ensuring that deleteType <= G_N_ELEMENTS here results in a compiler warning + // that the condition is always true. + + if (deleteType == GTK_DELETE_WORDS) { + if (!direction) { + translator->addPendingEditorCommand("MoveWordForward"); + translator->addPendingEditorCommand("MoveWordBackward"); + } else { + translator->addPendingEditorCommand("MoveWordBackward"); + translator->addPendingEditorCommand("MoveWordForward"); + } + } else if (deleteType == GTK_DELETE_DISPLAY_LINES) { + if (!direction) + translator->addPendingEditorCommand("MoveToBeginningOfLine"); + else + translator->addPendingEditorCommand("MoveToEndOfLine"); + } else if (deleteType == GTK_DELETE_PARAGRAPHS) { + if (!direction) + translator->addPendingEditorCommand("MoveToBeginningOfParagraph"); + else + translator->addPendingEditorCommand("MoveToEndOfParagraph"); + } + + const char* rawCommand = gtkDeleteCommands[deleteType][direction]; + if (!rawCommand) + return; + + for (int i = 0; i < abs(count); i++) + translator->addPendingEditorCommand(rawCommand); +} + +static const char* const gtkMoveCommands[][4] = { + { "MoveBackward", "MoveForward", + "MoveBackwardAndModifySelection", "MoveForwardAndModifySelection" }, // Forward/backward grapheme + { "MoveLeft", "MoveRight", + "MoveBackwardAndModifySelection", "MoveForwardAndModifySelection" }, // Left/right grapheme + { "MoveWordBackward", "MoveWordForward", + "MoveWordBackwardAndModifySelection", "MoveWordForwardAndModifySelection" }, // Forward/backward word + { "MoveUp", "MoveDown", + "MoveUpAndModifySelection", "MoveDownAndModifySelection" }, // Up/down line + { "MoveToBeginningOfLine", "MoveToEndOfLine", + "MoveToBeginningOfLineAndModifySelection", "MoveToEndOfLineAndModifySelection" }, // Up/down line ends + { 0, 0, + "MoveParagraphBackwardAndModifySelection", "MoveParagraphForwardAndModifySelection" }, // Up/down paragraphs + { "MoveToBeginningOfParagraph", "MoveToEndOfParagraph", + "MoveToBeginningOfParagraphAndModifySelection", "MoveToEndOfParagraphAndModifySelection" }, // Up/down paragraph ends. + { "MovePageUp", "MovePageDown", + "MovePageUpAndModifySelection", "MovePageDownAndModifySelection" }, // Up/down page + { "MoveToBeginningOfDocument", "MoveToEndOfDocument", + "MoveToBeginningOfDocumentAndModifySelection", "MoveToEndOfDocumentAndModifySelection" }, // Begin/end of buffer + { 0, 0, + 0, 0 } // Horizontal page movement +}; + +static void moveCursorCallback(GtkWidget* widget, GtkMovementStep step, gint count, gboolean extendSelection, KeyBindingTranslator* translator) +{ + g_signal_stop_emission_by_name(widget, "move-cursor"); + int direction = count > 0 ? 1 : 0; + if (extendSelection) + direction += 2; + + if (static_cast<unsigned>(step) >= G_N_ELEMENTS(gtkMoveCommands)) + return; + + const char* rawCommand = gtkMoveCommands[step][direction]; + if (!rawCommand) + return; + + for (int i = 0; i < abs(count); i++) + translator->addPendingEditorCommand(rawCommand); +} + +KeyBindingTranslator::KeyBindingTranslator() + : m_nativeWidget(gtk_text_view_new()) +{ + g_signal_connect(m_nativeWidget.get(), "backspace", G_CALLBACK(backspaceCallback), this); + g_signal_connect(m_nativeWidget.get(), "cut-clipboard", G_CALLBACK(cutClipboardCallback), this); + g_signal_connect(m_nativeWidget.get(), "copy-clipboard", G_CALLBACK(copyClipboardCallback), this); + g_signal_connect(m_nativeWidget.get(), "paste-clipboard", G_CALLBACK(pasteClipboardCallback), this); + g_signal_connect(m_nativeWidget.get(), "select-all", G_CALLBACK(selectAllCallback), this); + g_signal_connect(m_nativeWidget.get(), "move-cursor", G_CALLBACK(moveCursorCallback), this); + g_signal_connect(m_nativeWidget.get(), "delete-from-cursor", G_CALLBACK(deleteFromCursorCallback), this); + g_signal_connect(m_nativeWidget.get(), "toggle-overwrite", G_CALLBACK(toggleOverwriteCallback), this); + g_signal_connect(m_nativeWidget.get(), "popup-menu", G_CALLBACK(popupMenuCallback), this); + g_signal_connect(m_nativeWidget.get(), "show-help", G_CALLBACK(showHelpCallback), this); +} + +struct KeyCombinationEntry { + unsigned gdkKeyCode; + unsigned state; + const char* name; +}; + +static const KeyCombinationEntry customKeyBindings[] = { + { GDK_KEY_b, GDK_CONTROL_MASK, "ToggleBold" }, + { GDK_KEY_i, GDK_CONTROL_MASK, "ToggleItalic" }, + { GDK_KEY_Escape, 0, "Cancel" }, + { GDK_KEY_greater, GDK_CONTROL_MASK, "Cancel" }, + { GDK_KEY_Tab, 0, "InsertTab" }, + { GDK_KEY_Tab, GDK_SHIFT_MASK, "InsertBacktab" }, +}; + +Vector<String> KeyBindingTranslator::commandsForKeyEvent(GdkEventKey* event) +{ + ASSERT(m_pendingEditorCommands.isEmpty()); + + gtk_bindings_activate_event(G_OBJECT(m_nativeWidget.get()), event); + if (!m_pendingEditorCommands.isEmpty()) + return WTFMove(m_pendingEditorCommands); + + // Special-case enter keys for we want them to work regardless of modifier. + if ((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter || event->keyval == GDK_KEY_ISO_Enter)) + return { "InsertNewLine" }; + + // For keypress events, we want charCode(), but keyCode() does that. + unsigned mapKey = event->state << 16 | event->keyval; + if (!mapKey) + return { }; + + for (unsigned i = 0; i < G_N_ELEMENTS(customKeyBindings); ++i) { + if (mapKey == (customKeyBindings[i].state << 16 | customKeyBindings[i].gdkKeyCode)) + return { customKeyBindings[i].name }; + } + + return { }; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.h b/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.h new file mode 100644 index 000000000..b2ded5de6 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/KeyBindingTranslator.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010, 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef KeyBindingTranslator_h +#define KeyBindingTranslator_h + +#include <WebCore/GRefPtrGtk.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +typedef struct _GdkEventKey GdkEventKey; + +namespace WebKit { + +class KeyBindingTranslator { +public: + KeyBindingTranslator(); + + Vector<String> commandsForKeyEvent(GdkEventKey*); + void addPendingEditorCommand(const char* command) { m_pendingEditorCommands.append(command); } + +private: + GRefPtr<GtkWidget> m_nativeWidget; + Vector<String> m_pendingEditorCommands; +}; + +} // namespace WebKit + +#endif + + diff --git a/Source/WebKit2/UIProcess/gtk/TextCheckerGtk.cpp b/Source/WebKit2/UIProcess/gtk/TextCheckerGtk.cpp index 6bc419079..2513cbd69 100644 --- a/Source/WebKit2/UIProcess/gtk/TextCheckerGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/TextCheckerGtk.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2010 Apple Inc. All rights reserved. * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011-2013 Samsung Electronics * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,119 +29,290 @@ #include "TextChecker.h" #include "TextCheckerState.h" -#include "WebTextChecker.h" +#include "WebProcessPool.h" #include <WebCore/NotImplemented.h> +#include <WebCore/TextCheckerEnchant.h> +#include <unicode/ubrk.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/text/TextBreakIterator.h> using namespace WebCore; - + namespace WebKit { -static TextCheckerState textCheckerState; +#if ENABLE(SPELLCHECK) +static WebCore::TextCheckerEnchant& enchantTextChecker() +{ + static NeverDestroyed<WebCore::TextCheckerEnchant> checker; + return checker; +} +#endif -const TextCheckerState& TextChecker::state() +TextCheckerState& checkerState() { - static bool didInitializeState = false; - if (didInitializeState) - return textCheckerState; + static TextCheckerState textCheckerState; + static std::once_flag onceFlag; + std::call_once(onceFlag, [] { + textCheckerState.isContinuousSpellCheckingEnabled = false; + textCheckerState.isGrammarCheckingEnabled = false; + }); + + return textCheckerState; +} - WebTextCheckerClient& client = WebTextChecker::shared()->client(); - textCheckerState.isContinuousSpellCheckingEnabled = client.continuousSpellCheckingEnabled(); - textCheckerState.isGrammarCheckingEnabled = client.grammarCheckingEnabled(); +const TextCheckerState& TextChecker::state() +{ + return checkerState(); +} + +static bool testingModeEnabled = false; + +void TextChecker::setTestingMode(bool enabled) +{ + testingModeEnabled = enabled; +} - didInitializeState = true; +bool TextChecker::isTestingMode() +{ + return testingModeEnabled; +} - return textCheckerState; +#if ENABLE(SPELLCHECK) +static void updateStateForAllProcessPools() +{ + for (const auto& processPool : WebProcessPool::allProcessPools()) + processPool->textCheckerStateChanged(); } - +#endif + bool TextChecker::isContinuousSpellCheckingAllowed() { - return WebTextChecker::shared()->client().continuousSpellCheckingAllowed(); +#if ENABLE(SPELLCHECK) + return true; +#else + return false; +#endif } void TextChecker::setContinuousSpellCheckingEnabled(bool isContinuousSpellCheckingEnabled) { - if (state().isContinuousSpellCheckingEnabled == isContinuousSpellCheckingEnabled) +#if ENABLE(SPELLCHECK) + if (checkerState().isContinuousSpellCheckingEnabled == isContinuousSpellCheckingEnabled) return; - textCheckerState.isContinuousSpellCheckingEnabled = isContinuousSpellCheckingEnabled; - WebTextChecker::shared()->client().setContinuousSpellCheckingEnabled(isContinuousSpellCheckingEnabled); + checkerState().isContinuousSpellCheckingEnabled = isContinuousSpellCheckingEnabled; + updateStateForAllProcessPools(); +#else + UNUSED_PARAM(isContinuousSpellCheckingEnabled); +#endif } void TextChecker::setGrammarCheckingEnabled(bool isGrammarCheckingEnabled) { - if (state().isGrammarCheckingEnabled == isGrammarCheckingEnabled) +#if ENABLE(SPELLCHECK) + if (checkerState().isGrammarCheckingEnabled == isGrammarCheckingEnabled) return; - textCheckerState.isGrammarCheckingEnabled = isGrammarCheckingEnabled; - WebTextChecker::shared()->client().setGrammarCheckingEnabled(isGrammarCheckingEnabled); + checkerState().isGrammarCheckingEnabled = isGrammarCheckingEnabled; + updateStateForAllProcessPools(); +#else + UNUSED_PARAM(isGrammarCheckingEnabled); +#endif } void TextChecker::continuousSpellCheckingEnabledStateChanged(bool enabled) { - textCheckerState.isContinuousSpellCheckingEnabled = enabled; +#if ENABLE(SPELLCHECK) + checkerState().isContinuousSpellCheckingEnabled = enabled; +#else + UNUSED_PARAM(enabled); +#endif } void TextChecker::grammarCheckingEnabledStateChanged(bool enabled) { - textCheckerState.isGrammarCheckingEnabled = enabled; +#if ENABLE(SPELLCHECK) + checkerState().isGrammarCheckingEnabled = enabled; +#else + UNUSED_PARAM(enabled); +#endif } -int64_t TextChecker::uniqueSpellDocumentTag(WebPageProxy* page) +int64_t TextChecker::uniqueSpellDocumentTag(WebPageProxy*) { - return WebTextChecker::shared()->client().uniqueSpellDocumentTag(page); + return 0; } -void TextChecker::closeSpellDocumentWithTag(int64_t tag) +void TextChecker::closeSpellDocumentWithTag(int64_t /* tag */) { - WebTextChecker::shared()->client().closeSpellDocumentWithTag(tag); } -void TextChecker::checkSpellingOfString(int64_t spellDocumentTag, const UChar* text, uint32_t length, int32_t& misspellingLocation, int32_t& misspellingLength) +void TextChecker::checkSpellingOfString(int64_t /* spellDocumentTag */, StringView text, int32_t& misspellingLocation, int32_t& misspellingLength) { - WebTextChecker::shared()->client().checkSpellingOfString(spellDocumentTag, String(text, length), misspellingLocation, misspellingLength); +#if ENABLE(SPELLCHECK) + misspellingLocation = -1; + misspellingLength = 0; + enchantTextChecker().checkSpellingOfString(text.toStringWithoutCopying(), misspellingLocation, misspellingLength); +#else + UNUSED_PARAM(text); + UNUSED_PARAM(misspellingLocation); + UNUSED_PARAM(misspellingLength); +#endif } -void TextChecker::checkGrammarOfString(int64_t spellDocumentTag, const UChar* text, uint32_t length, Vector<WebCore::GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength) +void TextChecker::checkGrammarOfString(int64_t /* spellDocumentTag */, StringView /* text */, Vector<WebCore::GrammarDetail>& /* grammarDetails */, int32_t& /* badGrammarLocation */, int32_t& /* badGrammarLength */) { - WebTextChecker::shared()->client().checkGrammarOfString(spellDocumentTag, String(text, length), grammarDetails, badGrammarLocation, badGrammarLength); } bool TextChecker::spellingUIIsShowing() { - return WebTextChecker::shared()->client().spellingUIIsShowing(); + return false; } void TextChecker::toggleSpellingUIIsShowing() { - WebTextChecker::shared()->client().toggleSpellingUIIsShowing(); } -void TextChecker::updateSpellingUIWithMisspelledWord(int64_t spellDocumentTag, const String& misspelledWord) +void TextChecker::updateSpellingUIWithMisspelledWord(int64_t /* spellDocumentTag */, const String& /* misspelledWord */) +{ +} + +void TextChecker::updateSpellingUIWithGrammarString(int64_t /* spellDocumentTag */, const String& /* badGrammarPhrase */, const GrammarDetail& /* grammarDetail */) { - WebTextChecker::shared()->client().updateSpellingUIWithMisspelledWord(spellDocumentTag, misspelledWord); } -void TextChecker::updateSpellingUIWithGrammarString(int64_t spellDocumentTag, const String& badGrammarPhrase, const GrammarDetail& grammarDetail) +void TextChecker::getGuessesForWord(int64_t /* spellDocumentTag */, const String& word, const String& /* context */, int32_t /* insertionPoint */, Vector<String>& guesses, bool) { - WebTextChecker::shared()->client().updateSpellingUIWithGrammarString(spellDocumentTag, badGrammarPhrase, grammarDetail); +#if ENABLE(SPELLCHECK) + guesses = enchantTextChecker().getGuessesForWord(word); +#else + UNUSED_PARAM(word); + UNUSED_PARAM(guesses); +#endif } -void TextChecker::getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, Vector<String>& guesses) +void TextChecker::learnWord(int64_t /* spellDocumentTag */, const String& word) { - WebTextChecker::shared()->client().guessesForWord(spellDocumentTag, word, guesses); +#if ENABLE(SPELLCHECK) + enchantTextChecker().learnWord(word); +#else + UNUSED_PARAM(word); +#endif } -void TextChecker::learnWord(int64_t spellDocumentTag, const String& word) +void TextChecker::ignoreWord(int64_t /* spellDocumentTag */, const String& word) { - WebTextChecker::shared()->client().learnWord(spellDocumentTag, word); +#if ENABLE(SPELLCHECK) + enchantTextChecker().ignoreWord(word); +#else + UNUSED_PARAM(word); +#endif +} + +void TextChecker::requestCheckingOfString(PassRefPtr<TextCheckerCompletion> completion, int32_t insertionPoint) +{ +#if ENABLE(SPELLCHECK) + if (!completion) + return; + + TextCheckingRequestData request = completion->textCheckingRequestData(); + ASSERT(request.sequence() != unrequestedTextCheckingSequence); + ASSERT(request.mask() != TextCheckingTypeNone); + + completion->didFinishCheckingText(checkTextOfParagraph(completion->spellDocumentTag(), request.text(), insertionPoint, request.mask(), false)); +#else + UNUSED_PARAM(completion); +#endif +} + +#if USE(UNIFIED_TEXT_CHECKING) && ENABLE(SPELLCHECK) +static unsigned nextWordOffset(StringView text, unsigned currentOffset) +{ + // FIXME: avoid creating textIterator object here, it could be passed as a parameter. + // ubrk_isBoundary() leaves the iterator pointing to the first boundary position at + // or after "offset" (ubrk_isBoundary side effect). + // For many word separators, the method doesn't properly determine the boundaries + // without resetting the iterator. + UBreakIterator* textIterator = wordBreakIterator(text); + if (!textIterator) + return currentOffset; + + unsigned wordOffset = currentOffset; + while (wordOffset < text.length() && ubrk_isBoundary(textIterator, wordOffset)) + ++wordOffset; + + // Do not treat the word's boundary as a separator. + if (!currentOffset && wordOffset == 1) + return currentOffset; + + // Omit multiple separators. + if ((wordOffset - currentOffset) > 1) + --wordOffset; + + return wordOffset; +} +#endif + +#if USE(UNIFIED_TEXT_CHECKING) +Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t spellDocumentTag, StringView text, int32_t insertionPoint, uint64_t checkingTypes, bool) +{ + UNUSED_PARAM(insertionPoint); +#if ENABLE(SPELLCHECK) + if (!(checkingTypes & TextCheckingTypeSpelling)) + return Vector<TextCheckingResult>(); + + UBreakIterator* textIterator = wordBreakIterator(text); + if (!textIterator) + return Vector<TextCheckingResult>(); + + // Omit the word separators at the beginning/end of the text to don't unnecessarily + // involve the client to check spelling for them. + unsigned offset = nextWordOffset(text, 0); + unsigned lengthStrip = text.length(); + while (lengthStrip > 0 && ubrk_isBoundary(textIterator, lengthStrip - 1)) + --lengthStrip; + + Vector<TextCheckingResult> paragraphCheckingResult; + while (offset < lengthStrip) { + int32_t misspellingLocation = -1; + int32_t misspellingLength = 0; + checkSpellingOfString(spellDocumentTag, text.substring(offset, lengthStrip - offset), misspellingLocation, misspellingLength); + if (!misspellingLength) + break; + + TextCheckingResult misspellingResult; + misspellingResult.type = TextCheckingTypeSpelling; + misspellingResult.location = offset + misspellingLocation; + misspellingResult.length = misspellingLength; + paragraphCheckingResult.append(misspellingResult); + offset += misspellingLocation + misspellingLength; + // Generally, we end up checking at the word separator, move to the adjacent word. + offset = nextWordOffset(text.substring(0, lengthStrip), offset); + } + return paragraphCheckingResult; +#else + UNUSED_PARAM(spellDocumentTag); + UNUSED_PARAM(text); + UNUSED_PARAM(checkingTypes); + return Vector<TextCheckingResult>(); +#endif // ENABLE(SPELLCHECK) } +#endif // USE(UNIFIED_TEXT_CHECKING) -void TextChecker::ignoreWord(int64_t spellDocumentTag, const String& word) +void TextChecker::setSpellCheckingLanguages(const Vector<String>& languages) { - WebTextChecker::shared()->client().ignoreWord(spellDocumentTag, word); +#if ENABLE(SPELLCHECK) + enchantTextChecker().updateSpellCheckingLanguages(languages); +#else + UNUSED_PARAM(languages); +#endif } -void TextChecker::requestCheckingOfString(PassRefPtr<TextCheckerCompletion>) +Vector<String> TextChecker::loadedSpellCheckingLanguages() { - notImplemented(); +#if ENABLE(SPELLCHECK) + return enchantTextChecker().loadedSpellCheckingLanguages(); +#else + return Vector<String>(); +#endif } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/WaylandCompositor.cpp b/Source/WebKit2/UIProcess/gtk/WaylandCompositor.cpp new file mode 100644 index 000000000..99e1588b4 --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/WaylandCompositor.cpp @@ -0,0 +1,521 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WaylandCompositor.h" + +#if PLATFORM(WAYLAND) && USE(EGL) + +#include "WebKit2WaylandServerProtocol.h" +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <WebCore/GLContext.h> +#include <WebCore/PlatformDisplayWayland.h> +#include <WebCore/Region.h> +#include <WebCore/UUID.h> +#include <wayland-server-protocol.h> + +#if USE(OPENGL_ES_2) +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#else +#include <WebCore/OpenGLShims.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +#if !defined(PFNEGLBINDWAYLANDDISPLAYWL) +typedef EGLBoolean (*PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay, struct wl_display*); +#endif + +#if !defined(PFNEGLUNBINDWAYLANDDISPLAYWL) +typedef EGLBoolean (*PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay, struct wl_display*); +#endif + +#if !defined(PFNEGLQUERYWAYLANDBUFFERWL) +typedef EGLBoolean (*PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay, struct wl_resource*, EGLint attribute, EGLint* value); +#endif + +#if !defined(PFNEGLCREATEIMAGEKHRPROC) +typedef EGLImageKHR (*PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay, EGLContext, EGLenum target, EGLClientBuffer, const EGLint* attribList); +#endif + +#if !defined(PFNEGLDESTROYIMAGEKHRPROC) +typedef EGLBoolean (*PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay, EGLImageKHR); +#endif + +#if !defined(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) +typedef void (*PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES); +#endif + +static PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplay; +static PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplay; +static PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBuffer; +static PFNEGLCREATEIMAGEKHRPROC eglCreateImage; +static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImage; +static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glImageTargetTexture2D; + +WaylandCompositor& WaylandCompositor::singleton() +{ + static NeverDestroyed<WaylandCompositor> waylandCompositor; + return waylandCompositor; +} + +WaylandCompositor::Buffer* WaylandCompositor::Buffer::getOrCreate(struct wl_resource* resource) +{ + if (struct wl_listener* listener = wl_resource_get_destroy_listener(resource, destroyListenerCallback)) { + WaylandCompositor::Buffer* buffer; + return wl_container_of(listener, buffer, m_destroyListener); + } + + return new WaylandCompositor::Buffer(resource); +} + +WaylandCompositor::Buffer::Buffer(struct wl_resource* resource) + : m_resource(resource) + , m_weakPtrFactory(this) +{ + wl_list_init(&m_destroyListener.link); + m_destroyListener.notify = destroyListenerCallback; + wl_resource_add_destroy_listener(m_resource, &m_destroyListener); +} + +WaylandCompositor::Buffer::~Buffer() +{ + wl_list_remove(&m_destroyListener.link); +} + +void WaylandCompositor::Buffer::destroyListenerCallback(struct wl_listener* listener, void*) +{ + WaylandCompositor::Buffer* buffer; + buffer = wl_container_of(listener, buffer, m_destroyListener); + delete buffer; +} + +void WaylandCompositor::Buffer::use() +{ + m_busyCount++; +} + +void WaylandCompositor::Buffer::unuse() +{ + m_busyCount--; + if (!m_busyCount) + wl_resource_queue_event(m_resource, WL_BUFFER_RELEASE); +} + +EGLImageKHR WaylandCompositor::Buffer::createImage() const +{ + return static_cast<EGLImageKHR*>(eglCreateImage(PlatformDisplay::sharedDisplay().eglDisplay(), EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, m_resource, nullptr)); +} + +IntSize WaylandCompositor::Buffer::size() const +{ + EGLDisplay eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay(); + int width, height; + eglQueryWaylandBuffer(eglDisplay, m_resource, EGL_WIDTH, &width); + eglQueryWaylandBuffer(eglDisplay, m_resource, EGL_HEIGHT, &height); + + return { width, height }; +} + +WaylandCompositor::Surface::Surface() + : m_image(EGL_NO_IMAGE_KHR) +{ + glGenTextures(1, &m_texture); + glBindTexture(GL_TEXTURE_2D, m_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + +WaylandCompositor::Surface::~Surface() +{ + // Destroy pending frame callbacks. + auto list = WTFMove(m_frameCallbackList); + for (auto* resource : list) + wl_resource_destroy(resource); + + if (m_buffer) + m_buffer->unuse(); + + if (m_image != EGL_NO_IMAGE_KHR) + eglDestroyImage(PlatformDisplay::sharedDisplay().eglDisplay(), m_image); + + glDeleteTextures(1, &m_texture); +} + +void WaylandCompositor::Surface::makePendingBufferCurrent() +{ + if (m_pendingBuffer == m_buffer) + return; + + if (m_buffer) + m_buffer->unuse(); + + if (m_pendingBuffer) + m_pendingBuffer->use(); + + m_buffer = m_pendingBuffer; +} + +void WaylandCompositor::Surface::attachBuffer(struct wl_resource* buffer) +{ + if (m_pendingBuffer) + m_pendingBuffer = nullptr; + + if (buffer) { + auto* compositorBuffer = WaylandCompositor::Buffer::getOrCreate(buffer); + m_pendingBuffer = compositorBuffer->createWeakPtr(); + } +} + +void WaylandCompositor::Surface::requestFrame(struct wl_resource* resource) +{ + wl_resource_set_implementation(resource, nullptr, this, [](struct wl_resource* resource) { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(resource)); + if (size_t item = surface->m_frameCallbackList.find(resource) != notFound) + surface->m_frameCallbackList.remove(item); + }); + m_frameCallbackList.append(resource); +} + +bool WaylandCompositor::Surface::prepareTextureForPainting(unsigned& texture, IntSize& textureSize) +{ + if (m_image == EGL_NO_IMAGE_KHR) + return false; + + glBindTexture(GL_TEXTURE_2D, m_texture); + glImageTargetTexture2D(GL_TEXTURE_2D, m_image); + + texture = m_texture; + textureSize = m_imageSize; + return true; +} + +void WaylandCompositor::Surface::commit() +{ + EGLDisplay eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay(); + if (m_image != EGL_NO_IMAGE_KHR) + eglDestroyImage(eglDisplay, m_image); + m_image = m_pendingBuffer->createImage(); + if (m_image == EGL_NO_IMAGE_KHR) + return; + + m_imageSize = m_pendingBuffer->size(); + + makePendingBufferCurrent(); + if (m_webPage) + m_webPage->setViewNeedsDisplay(IntRect(IntPoint::zero(), m_webPage->viewSize())); + + // From a Wayland point-of-view frame callbacks should be fired where the + // compositor knows it has *used* the committed contents, so firing them here + // can be surprising but we don't need them as a throttling mechanism because + // rendering synchronization is handled elsewhere by WebKit. + auto list = WTFMove(m_frameCallbackList); + for (auto* resource : list) { + wl_callback_send_done(resource, 0); + wl_resource_destroy(resource); + } +} + +static const struct wl_surface_interface surfaceInterface = { + // destroyCallback + [](struct wl_client*, struct wl_resource* resource) + { + wl_resource_destroy(resource); + }, + // attachCallback + [](struct wl_client* client, struct wl_resource* resource, struct wl_resource* buffer, int32_t sx, int32_t sy) + { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(resource)); + if (!surface) + return; + + EGLint format; + if (!eglQueryWaylandBuffer(PlatformDisplay::sharedDisplay().eglDisplay(), buffer, EGL_TEXTURE_FORMAT, &format) + || (format != EGL_TEXTURE_RGB && format != EGL_TEXTURE_RGBA)) + return; + + surface->attachBuffer(buffer); + }, + // damageCallback + [](struct wl_client*, struct wl_resource*, int32_t, int32_t, int32_t, int32_t) { }, + // frameCallback + [](struct wl_client* client, struct wl_resource* resource, uint32_t id) + { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(resource)); + if (!surface) + return; + + if (struct wl_resource* callbackResource = wl_resource_create(client, &wl_callback_interface, 1, id)) + surface->requestFrame(callbackResource); + else + wl_client_post_no_memory(client); + }, + // setOpaqueRegionCallback + [](struct wl_client*, struct wl_resource*, struct wl_resource*) { }, + // setInputRegionCallback + [](struct wl_client*, struct wl_resource*, struct wl_resource*) { }, + // commitCallback + [](struct wl_client* client, struct wl_resource* resource) + { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(resource)); + if (!surface) + return; + surface->commit(); + }, + // setBufferTransformCallback + [](struct wl_client*, struct wl_resource*, int32_t) { }, + // setBufferScaleCallback + [](struct wl_client*, struct wl_resource*, int32_t) { }, +#if WAYLAND_VERSION_MAJOR > 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR >= 10) + // damageBufferCallback + [](struct wl_client*, struct wl_resource*, int32_t, int32_t, int32_t, int32_t) { }, +#endif +}; + +static const struct wl_compositor_interface compositorInterface = { + // createSurfaceCallback + [](struct wl_client* client, struct wl_resource* resource, uint32_t id) + { + if (struct wl_resource* surfaceResource = wl_resource_create(client, &wl_surface_interface, 1, id)) { + wl_resource_set_implementation(surfaceResource, &surfaceInterface, new WaylandCompositor::Surface(), + [](struct wl_resource* resource) { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(resource)); + delete surface; + }); + } else + wl_client_post_no_memory(client); + }, + // createRegionCallback + [](struct wl_client*, struct wl_resource*, uint32_t) { } +}; + +static const struct wl_webkitgtk_interface webkitgtkInterface = { + // bindSurfaceToPageCallback + [](struct wl_client*, struct wl_resource* resource, struct wl_resource* surfaceResource, uint32_t pageID) + { + auto* surface = static_cast<WaylandCompositor::Surface*>(wl_resource_get_user_data(surfaceResource)); + if (!surface) + return; + + auto* compositor = static_cast<WaylandCompositor*>(wl_resource_get_user_data(resource)); + compositor->bindSurfaceToWebPage(surface, pageID); + } +}; + +bool WaylandCompositor::initializeEGL() +{ + if (PlatformDisplay::sharedDisplay().eglCheckVersion(1, 5)) { + eglCreateImage = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImage")); + eglDestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImage")); + } else { + const char* extensions = eglQueryString(PlatformDisplay::sharedDisplay().eglDisplay(), EGL_EXTENSIONS); + if (GLContext::isExtensionSupported(extensions, "EGL_KHR_image_base")) { + eglCreateImage = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + eglDestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + } + } + if (!eglCreateImage || !eglDestroyImage) { + WTFLogAlways("WaylandCompositor requires eglCreateImage and eglDestroyImage."); + return false; + } + + glImageTargetTexture2D = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES")); + if (!glImageTargetTexture2D) { + WTFLogAlways("WaylandCompositor requires glEGLImageTargetTexture2D."); + return false; + } + + eglQueryWaylandBuffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL>(eglGetProcAddress("eglQueryWaylandBufferWL")); + if (!eglQueryWaylandBuffer) { + WTFLogAlways("WaylandCompositor requires eglQueryWaylandBuffer."); + return false; + } + + eglBindWaylandDisplay = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); + eglUnbindWaylandDisplay = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); + if (!eglBindWaylandDisplay || !eglUnbindWaylandDisplay) { + WTFLogAlways("WaylandCompositor requires eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL."); + return false; + } + + m_eglContext = GLContext::createOffscreenContext(); + if (!m_eglContext) + return false; + + if (!m_eglContext->makeContextCurrent()) + return false; + + return true; +} + +typedef struct { + GSource source; + gpointer fdTag; + struct wl_display* display; +} WaylandLoopSource; + +static const unsigned waylandLoopSourceCondition = G_IO_IN | G_IO_HUP | G_IO_ERR; + +static GSourceFuncs waylandLoopSourceFunctions = { + // prepare + [](GSource *source, int *timeout) -> gboolean + { + *timeout = -1; + auto* wlLoopSource = reinterpret_cast<WaylandLoopSource*>(source); + wl_display_flush_clients(wlLoopSource->display); + return FALSE; + }, + nullptr, // check + // dispatch + [](GSource* source, GSourceFunc callback, gpointer userData) -> gboolean + { + auto* wlLoopSource = reinterpret_cast<WaylandLoopSource*>(source); + unsigned events = g_source_query_unix_fd(source, wlLoopSource->fdTag) & waylandLoopSourceCondition; + if (events & G_IO_HUP || events & G_IO_ERR) { + WTFLogAlways("Wayland Display Event Source: lost connection to nested Wayland compositor"); + return G_SOURCE_REMOVE; + } + + if (events & G_IO_IN) + wl_event_loop_dispatch(wl_display_get_event_loop(wlLoopSource->display), 0); + return G_SOURCE_CONTINUE; + }, + nullptr, // finalize + nullptr, // closure_callback + nullptr, // closure_marshall +}; + +static GRefPtr<GSource> createWaylandLoopSource(struct wl_display* display) +{ + GRefPtr<GSource> source = adoptGRef(g_source_new(&waylandLoopSourceFunctions, sizeof(WaylandLoopSource))); + g_source_set_name(source.get(), "Nested Wayland compositor display event source"); + g_source_set_priority(source.get(), G_PRIORITY_DEFAULT + 1); + + auto* wlLoopSource = reinterpret_cast<WaylandLoopSource*>(source.get()); + wlLoopSource->display = display; + wlLoopSource->fdTag = g_source_add_unix_fd(source.get(), wl_event_loop_get_fd(wl_display_get_event_loop(display)), static_cast<GIOCondition>(waylandLoopSourceCondition)); + g_source_attach(source.get(), nullptr); + + return source; +} + +WaylandCompositor::WaylandCompositor() +{ + WlUniquePtr<struct wl_display> display(wl_display_create()); + if (!display) { + WTFLogAlways("Nested Wayland compositor could not create display object"); + return; + } + + String displayName = "webkitgtk-wayland-compositor-" + createCanonicalUUIDString(); + if (wl_display_add_socket(display.get(), displayName.utf8().data()) == -1) { + WTFLogAlways("Nested Wayland compositor could not create display socket"); + return; + } + + WlUniquePtr<struct wl_global> compositorGlobal(wl_global_create(display.get(), &wl_compositor_interface, wl_compositor_interface.version, this, + [](struct wl_client* client, void* data, uint32_t version, uint32_t id) { + if (struct wl_resource* resource = wl_resource_create(client, &wl_compositor_interface, std::min(static_cast<int>(version), 3), id)) + wl_resource_set_implementation(resource, &compositorInterface, static_cast<WaylandCompositor*>(data), nullptr); + else + wl_client_post_no_memory(client); + })); + if (!compositorGlobal) { + WTFLogAlways("Nested Wayland compositor could not register compositor global"); + return; + } + + WlUniquePtr<struct wl_global> webkitgtkGlobal(wl_global_create(display.get(), &wl_webkitgtk_interface, 1, this, + [](struct wl_client* client, void* data, uint32_t version, uint32_t id) { + if (struct wl_resource* resource = wl_resource_create(client, &wl_webkitgtk_interface, 1, id)) + wl_resource_set_implementation(resource, &webkitgtkInterface, static_cast<WaylandCompositor*>(data), nullptr); + else + wl_client_post_no_memory(client); + })); + if (!webkitgtkGlobal) { + WTFLogAlways("Nested Wayland compositor could not register webkitgtk global"); + return; + } + + if (!initializeEGL()) { + WTFLogAlways("Nested Wayland compositor could not initialize EGL"); + return; + } + + if (!eglBindWaylandDisplay(PlatformDisplay::sharedDisplay().eglDisplay(), display.get())) { + WTFLogAlways("Nested Wayland compositor could not bind nested display"); + return; + } + + m_displayName = WTFMove(displayName); + m_display = WTFMove(display); + m_compositorGlobal = WTFMove(compositorGlobal); + m_webkitgtkGlobal = WTFMove(webkitgtkGlobal); + m_eventSource = createWaylandLoopSource(m_display.get()); +} + +bool WaylandCompositor::getTexture(WebPageProxy& webPage, unsigned& texture, IntSize& textureSize) +{ + if (auto* surface = m_pageMap.get(&webPage)) + return surface->prepareTextureForPainting(texture, textureSize); + return false; +} + +void WaylandCompositor::bindSurfaceToWebPage(WaylandCompositor::Surface* surface, uint64_t pageID) +{ + WebPageProxy* webPage = nullptr; + for (auto* page : m_pageMap.keys()) { + if (page->pageID() == pageID) { + webPage = page; + break; + } + } + if (!webPage) + return; + + surface->setWebPage(webPage); + m_pageMap.set(webPage, surface); +} + +void WaylandCompositor::registerWebPage(WebPageProxy& webPage) +{ + m_pageMap.add(&webPage, nullptr); +} + +void WaylandCompositor::unregisterWebPage(WebPageProxy& webPage) +{ + if (auto* surface = m_pageMap.take(&webPage)) + surface->setWebPage(nullptr); +} + +} // namespace WebKit + +#endif // PLATFORM(WAYLAND) && USE(EGL) diff --git a/Source/WebKit2/UIProcess/gtk/WaylandCompositor.h b/Source/WebKit2/UIProcess/gtk/WaylandCompositor.h new file mode 100644 index 000000000..14b9a836d --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/WaylandCompositor.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if PLATFORM(WAYLAND) && USE(EGL) + +#include "WebPageProxy.h" +#include <WebCore/RefPtrCairo.h> +#include <WebCore/WlUniquePtr.h> +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/Noncopyable.h> +#include <wtf/WeakPtr.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/WTFString.h> + +typedef void *EGLImageKHR; + +namespace WebCore { +class GLContext; +} + +namespace WebKit { + +class WebPageProxy; + +class WaylandCompositor { + WTF_MAKE_NONCOPYABLE(WaylandCompositor); + friend class NeverDestroyed<WaylandCompositor>; +public: + static WaylandCompositor& singleton(); + + class Buffer { + WTF_MAKE_NONCOPYABLE(Buffer); WTF_MAKE_FAST_ALLOCATED; + public: + static Buffer* getOrCreate(struct wl_resource*); + ~Buffer(); + + void use(); + void unuse(); + + EGLImageKHR createImage() const; + WebCore::IntSize size() const; + + WeakPtr<Buffer> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); } + + private: + Buffer(struct wl_resource*); + static void destroyListenerCallback(struct wl_listener*, void*); + + struct wl_resource* m_resource { nullptr }; + struct wl_listener m_destroyListener; + uint32_t m_busyCount { 0 }; + WeakPtrFactory<Buffer> m_weakPtrFactory; + }; + + class Surface { + WTF_MAKE_NONCOPYABLE(Surface); WTF_MAKE_FAST_ALLOCATED; + public: + Surface(); + ~Surface(); + + void attachBuffer(struct wl_resource*); + void requestFrame(struct wl_resource*); + void commit(); + + void setWebPage(WebPageProxy* webPage) { m_webPage = webPage; } + bool prepareTextureForPainting(unsigned&, WebCore::IntSize&); + + private: + void makePendingBufferCurrent(); + + WeakPtr<Buffer> m_buffer; + WeakPtr<Buffer> m_pendingBuffer; + unsigned m_texture; + EGLImageKHR m_image; + WebCore::IntSize m_imageSize; + Vector<wl_resource*> m_frameCallbackList; + WebPageProxy* m_webPage { nullptr }; + }; + + bool isRunning() const { return !!m_display; } + String displayName() const { return m_displayName; } + + void bindSurfaceToWebPage(Surface*, uint64_t pageID); + void registerWebPage(WebPageProxy&); + void unregisterWebPage(WebPageProxy&); + + bool getTexture(WebPageProxy&, unsigned&, WebCore::IntSize&); + +private: + WaylandCompositor(); + + bool initializeEGL(); + + String m_displayName; + WebCore::WlUniquePtr<struct wl_display> m_display; + WebCore::WlUniquePtr<struct wl_global> m_compositorGlobal; + WebCore::WlUniquePtr<struct wl_global> m_webkitgtkGlobal; + GRefPtr<GSource> m_eventSource; + std::unique_ptr<WebCore::GLContext> m_eglContext; + HashMap<WebPageProxy*, Surface*> m_pageMap; +}; + +} // namespace WebKit + +#endif // PLATFORM(WAYLAND) && USE(EGL) diff --git a/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.cpp new file mode 100644 index 000000000..32dfe82ec --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebColorPickerGtk.h" + +#if ENABLE(INPUT_TYPE_COLOR) + +#include "WebPageProxy.h" +#include <WebCore/GtkUtilities.h> +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> + +using namespace WebCore; + +namespace WebKit { + +Ref<WebColorPickerGtk> WebColorPickerGtk::create(WebPageProxy& page, const Color& initialColor, const IntRect& rect) +{ + return adoptRef(*new WebColorPickerGtk(page, initialColor, rect)); +} + +WebColorPickerGtk::WebColorPickerGtk(WebPageProxy& page, const Color& initialColor, const IntRect&) + : WebColorPicker(&page) + , m_initialColor(initialColor) + , m_webView(page.viewWidget()) + , m_colorChooser(nullptr) +{ +} + +WebColorPickerGtk::~WebColorPickerGtk() +{ + endPicker(); +} + +void WebColorPickerGtk::cancel() +{ + setSelectedColor(m_initialColor); +} + +void WebColorPickerGtk::endPicker() +{ + if (!m_colorChooser) + return; + + gtk_widget_destroy(m_colorChooser); + m_colorChooser = nullptr; +} + +void WebColorPickerGtk::didChooseColor(const Color& color) +{ + if (!m_client) + return; + + m_client->didChooseColor(color); +} + +void WebColorPickerGtk::colorChooserDialogRGBAChangedCallback(GtkColorChooser* colorChooser, GParamSpec*, WebColorPickerGtk* colorPicker) +{ + GdkRGBA rgba; + gtk_color_chooser_get_rgba(colorChooser, &rgba); + colorPicker->didChooseColor(rgba); +} + +void WebColorPickerGtk::colorChooserDialogResponseCallback(GtkColorChooser*, int responseID, WebColorPickerGtk* colorPicker) +{ + if (responseID != GTK_RESPONSE_OK) + colorPicker->cancel(); + colorPicker->endPicker(); +} + +void WebColorPickerGtk::showColorPicker(const Color& color) +{ + if (!m_client) + return; + + m_initialColor = color; + + if (!m_colorChooser) { + GtkWidget* toplevel = gtk_widget_get_toplevel(m_webView); + m_colorChooser = gtk_color_chooser_dialog_new(_("Select Color"), WebCore::widgetIsOnscreenToplevelWindow(toplevel) ? GTK_WINDOW(toplevel) : nullptr); + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(m_colorChooser), &m_initialColor); + g_signal_connect(m_colorChooser, "notify::rgba", G_CALLBACK(WebColorPickerGtk::colorChooserDialogRGBAChangedCallback), this); + g_signal_connect(m_colorChooser, "response", G_CALLBACK(WebColorPickerGtk::colorChooserDialogResponseCallback), this); + } else + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(m_colorChooser), &m_initialColor); + + gtk_widget_show(m_colorChooser); +} + +} // namespace WebKit + +#endif // ENABLE(INPUT_TYPE_COLOR) diff --git a/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.h b/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.h new file mode 100644 index 000000000..0bb96a5dd --- /dev/null +++ b/Source/WebKit2/UIProcess/gtk/WebColorPickerGtk.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebColorPickerGtk_h +#define WebColorPickerGtk_h + +#if ENABLE(INPUT_TYPE_COLOR) + +#include "WebColorPicker.h" +#include <gdk/gdk.h> + +typedef struct _GtkColorChooser GtkColorChooser; + +namespace WebCore { +class Color; +class IntRect; +} + +namespace WebKit { + +class WebColorPickerGtk : public WebColorPicker { +public: + static Ref<WebColorPickerGtk> create(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + virtual ~WebColorPickerGtk(); + + void endPicker() override; + void showColorPicker(const WebCore::Color&) override; + + void cancel(); + + const GdkRGBA* initialColor() const { return &m_initialColor; } + +protected: + WebColorPickerGtk(WebPageProxy&, const WebCore::Color&, const WebCore::IntRect&); + + void didChooseColor(const WebCore::Color&); + + GdkRGBA m_initialColor; + GtkWidget* m_webView; + +private: + static void colorChooserDialogRGBAChangedCallback(GtkColorChooser*, GParamSpec*, WebColorPickerGtk*); + static void colorChooserDialogResponseCallback(GtkColorChooser*, int /*responseID*/, WebColorPickerGtk*); + + GtkWidget* m_colorChooser; +}; + +} // namespace WebKit + +#endif // ENABLE(INPUT_TYPE_COLOR) +#endif // WebColorPickerGtk_h diff --git a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp index cc25e644b..5c6a8a08e 100644 --- a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.cpp @@ -28,152 +28,180 @@ #if ENABLE(CONTEXT_MENUS) +#include "APIContextMenuClient.h" #include "NativeWebMouseEvent.h" +#include "WebContextMenuItem.h" #include "WebContextMenuItemData.h" #include "WebKitWebViewBasePrivate.h" #include "WebPageProxy.h" +#include "WebProcessProxy.h" #include <WebCore/GtkUtilities.h> +#include <gio/gio.h> #include <gtk/gtk.h> #include <wtf/text/CString.h> - static const char* gContextMenuActionId = "webkit-context-menu-action"; +static const char* gContextMenuTitle = "webkit-context-menu-title"; +static const char* gContextMenuItemGroup = "webkitContextMenu"; using namespace WebCore; namespace WebKit { -static void contextMenuItemActivatedCallback(GtkAction* action, WebPageProxy* page) +static void contextMenuItemActivatedCallback(GAction* action, GVariant*, WebPageProxy* page) { - gboolean isToggle = GTK_IS_TOGGLE_ACTION(action); - WebKit::WebContextMenuItemData item(isToggle ? WebCore::CheckableActionType : WebCore::ActionType, - static_cast<WebCore::ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), gContextMenuActionId))), - String::fromUTF8(gtk_action_get_label(action)), gtk_action_get_sensitive(action), - isToggle ? gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)) : false); + auto* stateType = g_action_get_state_type(action); + gboolean isToggle = stateType && g_variant_type_equal(stateType, G_VARIANT_TYPE_BOOLEAN); + GRefPtr<GVariant> state = isToggle ? adoptGRef(g_action_get_state(action)) : nullptr; + WebContextMenuItemData item(isToggle ? CheckableActionType : ActionType, + static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), gContextMenuActionId))), + String::fromUTF8(static_cast<const char*>(g_object_get_data(G_OBJECT(action), gContextMenuTitle))), g_action_get_enabled(action), + state ? g_variant_get_boolean(state.get()) : false); page->contextMenuItemSelected(item); } -static void contextMenuItemVisibilityChanged(GtkAction* action, GParamSpec*, WebContextMenuProxyGtk* contextMenuProxy) +void WebContextMenuProxyGtk::append(GMenu* menu, const WebContextMenuItemGtk& menuItem) { - GtkMenu* menu = contextMenuProxy->gtkMenu(); - if (!menu) - return; - - GUniquePtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu))); - bool previousVisibleItemIsNotASeparator = false; - GtkWidget* lastItemVisibleSeparator = 0; - for (GList* iter = items.get(); iter; iter = g_list_next(iter)) { - GtkWidget* widget = GTK_WIDGET(iter->data); - - if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) { - if (previousVisibleItemIsNotASeparator) { - gtk_widget_show(widget); - lastItemVisibleSeparator = widget; - previousVisibleItemIsNotASeparator = false; - } else - gtk_widget_hide(widget); - } else if (gtk_widget_get_visible(widget)) { - lastItemVisibleSeparator = 0; - previousVisibleItemIsNotASeparator = true; - } + unsigned long signalHandlerId; + GRefPtr<GMenuItem> gMenuItem; + GAction* action = menuItem.gAction(); + ASSERT(action); +#if GTK_CHECK_VERSION(3, 16, 0) + g_action_map_add_action(G_ACTION_MAP(gtk_widget_get_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup)), action); +#else + g_action_map_add_action(G_ACTION_MAP(g_object_get_data(G_OBJECT(m_menu), gContextMenuItemGroup)), action); +#endif + + switch (menuItem.type()) { + case ActionType: + case CheckableActionType: { + GUniquePtr<char> actionName(g_strdup_printf("%s.%s", gContextMenuItemGroup, g_action_get_name(action))); + gMenuItem = adoptGRef(g_menu_item_new(menuItem.title().utf8().data(), nullptr)); + g_menu_item_set_action_and_target_value(gMenuItem.get(), actionName.get(), nullptr); + + g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action())); + g_object_set_data_full(G_OBJECT(action), gContextMenuTitle, g_strdup(menuItem.title().utf8().data()), g_free); + signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page); + m_signalHandlers.set(signalHandlerId, action); + break; + } + case SubmenuType: { + GRefPtr<GMenu> submenu = buildMenu(menuItem.submenuItems()); + gMenuItem = adoptGRef(g_menu_item_new_submenu(menuItem.title().utf8().data(), G_MENU_MODEL(submenu.get()))); + break; + } + case SeparatorType: + ASSERT_NOT_REACHED(); + break; } - if (lastItemVisibleSeparator) - gtk_widget_hide(lastItemVisibleSeparator); + g_menu_append_item(menu, gMenuItem.get()); } -void WebContextMenuProxyGtk::append(ContextMenuItem& menuItem) +GRefPtr<GMenu> WebContextMenuProxyGtk::buildMenu(const Vector<WebContextMenuItemGtk>& items) { - unsigned long signalHandlerId; - GtkAction* action = menuItem.gtkAction(); - if (action) { - switch (menuItem.type()) { - case ActionType: - case CheckableActionType: - g_object_set_data(G_OBJECT(action), gContextMenuActionId, GINT_TO_POINTER(menuItem.action())); - signalHandlerId = g_signal_connect(action, "activate", G_CALLBACK(contextMenuItemActivatedCallback), m_page); - m_signalHandlers.set(signalHandlerId, action); - // Fall through. - case SubmenuType: - signalHandlerId = g_signal_connect(action, "notify::visible", G_CALLBACK(contextMenuItemVisibilityChanged), this); - m_signalHandlers.set(signalHandlerId, action); - break; - case SeparatorType: - break; - } + GRefPtr<GMenu> menu = adoptGRef(g_menu_new()); + GMenu* sectionMenu = menu.get(); + for (const auto& item : items) { + if (item.type() == SeparatorType) { + GRefPtr<GMenu> section = adoptGRef(g_menu_new()); + g_menu_append_section(menu.get(), nullptr, G_MENU_MODEL(section.get())); + sectionMenu = section.get(); + } else + append(sectionMenu, item); } - m_menu.appendItem(menuItem); + return menu; } -// Populate the context menu ensuring that: -// - There aren't separators next to each other. -// - There aren't separators at the beginning of the menu. -// - There aren't separators at the end of the menu. -void WebContextMenuProxyGtk::populate(Vector<ContextMenuItem>& items) +void WebContextMenuProxyGtk::populate(const Vector<WebContextMenuItemGtk>& items) { - bool previousIsSeparator = false; - bool isEmpty = true; - for (size_t i = 0; i < items.size(); i++) { - ContextMenuItem& menuItem = items.at(i); - if (menuItem.type() == SeparatorType) { - previousIsSeparator = true; - continue; - } - - if (previousIsSeparator && !isEmpty) - append(items.at(i - 1)); - previousIsSeparator = false; - - append(menuItem); - isEmpty = false; - } + GRefPtr<GMenu> menu = buildMenu(items); + gtk_menu_shell_bind_model(GTK_MENU_SHELL(m_menu), G_MENU_MODEL(menu.get()), nullptr, TRUE); } -void WebContextMenuProxyGtk::populate(const Vector<WebContextMenuItemData>& items) +void WebContextMenuProxyGtk::populate(const Vector<RefPtr<WebContextMenuItem>>& items) { - for (size_t i = 0; i < items.size(); i++) { - ContextMenuItem menuitem = items.at(i).core(); - append(menuitem); + GRefPtr<GMenu> menu = adoptGRef(g_menu_new()); + GMenu* sectionMenu = menu.get(); + for (const auto& item : items) { + if (item->data().type() == SeparatorType) { + GRefPtr<GMenu> section = adoptGRef(g_menu_new()); + g_menu_append_section(menu.get(), nullptr, G_MENU_MODEL(section.get())); + sectionMenu = section.get(); + } else { + WebContextMenuItemGtk menuitem(item->data()); + append(sectionMenu, menuitem); + } } + gtk_menu_shell_bind_model(GTK_MENU_SHELL(m_menu), G_MENU_MODEL(menu.get()), nullptr, TRUE); } -void WebContextMenuProxyGtk::showContextMenu(const WebCore::IntPoint& position, const Vector<WebContextMenuItemData>& items) +void WebContextMenuProxyGtk::show() { + Vector<RefPtr<WebContextMenuItem>> proposedAPIItems; + for (auto& item : m_context.menuItems()) { + if (item.action() != ContextMenuItemTagShareMenu) + proposedAPIItems.append(WebContextMenuItem::create(item)); + } + + Vector<RefPtr<WebContextMenuItem>> clientItems; + bool useProposedItems = true; + + if (m_page->contextMenuClient().getContextMenuFromProposedMenu(*m_page, proposedAPIItems, clientItems, m_context.webHitTestResultData(), m_page->process().transformHandlesToObjects(m_userData.object()).get())) + useProposedItems = false; + + const Vector<RefPtr<WebContextMenuItem>>& items = useProposedItems ? proposedAPIItems : clientItems; + if (!items.isEmpty()) populate(items); - if (!m_menu.itemCount()) + unsigned childCount = 0; + gtk_container_foreach(GTK_CONTAINER(m_menu), [](GtkWidget*, gpointer data) { (*static_cast<unsigned*>(data))++; }, &childCount); + if (!childCount) return; - m_popupPosition = convertWidgetPointToScreenPoint(m_webView, position); + m_popupPosition = convertWidgetPointToScreenPoint(m_webView, m_context.menuLocation()); // Display menu initiated by right click (mouse button pressed = 3). NativeWebMouseEvent* mouseEvent = m_page->currentlyProcessedMouseDownEvent(); const GdkEvent* event = mouseEvent ? mouseEvent->nativeEvent() : 0; - gtk_menu_attach_to_widget(m_menu.platformDescription(), GTK_WIDGET(m_webView), 0); - gtk_menu_popup(m_menu.platformDescription(), 0, 0, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, + gtk_menu_attach_to_widget(m_menu, GTK_WIDGET(m_webView), nullptr); + gtk_menu_popup(m_menu, nullptr, nullptr, reinterpret_cast<GtkMenuPositionFunc>(menuPositionFunction), this, event ? event->button.button : 3, event ? event->button.time : GDK_CURRENT_TIME); } -void WebContextMenuProxyGtk::hideContextMenu() +void WebContextMenuProxyGtk::showContextMenuWithItems(const Vector<WebContextMenuItemData>& items) { - gtk_menu_popdown(m_menu.platformDescription()); } -WebContextMenuProxyGtk::WebContextMenuProxyGtk(GtkWidget* webView, WebPageProxy* page) - : m_webView(webView) - , m_page(page) +WebContextMenuProxyGtk::WebContextMenuProxyGtk(GtkWidget* webView, WebPageProxy& page, const ContextMenuContextData& context, const UserData& userData) + : WebContextMenuProxy(context, userData) + , m_webView(webView) + , m_page(&page) + , m_menu(GTK_MENU(gtk_menu_new())) { + GRefPtr<GSimpleActionGroup> group = adoptGRef(g_simple_action_group_new()); + gtk_widget_insert_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup, G_ACTION_GROUP(group.get())); +#if !GTK_CHECK_VERSION(3, 16, 0) + g_object_set_data(G_OBJECT(m_menu), gContextMenuItemGroup, group.get()); +#endif webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), this); } WebContextMenuProxyGtk::~WebContextMenuProxyGtk() { - for (auto iter = m_signalHandlers.begin(); iter != m_signalHandlers.end(); ++iter) - g_signal_handler_disconnect(iter->value, iter->key); + gtk_menu_popdown(m_menu); + + for (auto& handler : m_signalHandlers) + g_signal_handler_disconnect(handler.value, handler.key); + m_signalHandlers.clear(); - webkitWebViewBaseSetActiveContextMenuProxy(WEBKIT_WEB_VIEW_BASE(m_webView), 0); + gtk_widget_insert_action_group(GTK_WIDGET(m_menu), gContextMenuItemGroup, nullptr); +#if !GTK_CHECK_VERSION(3, 16, 0) + g_object_set_data(G_OBJECT(m_menu), gContextMenuItemGroup, nullptr); +#endif + gtk_widget_destroy(GTK_WIDGET(m_menu)); } void WebContextMenuProxyGtk::menuPositionFunction(GtkMenu* menu, gint* x, gint* y, gboolean* pushIn, WebContextMenuProxyGtk* popupMenu) diff --git a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h index ded4b7a84..144be9829 100644 --- a/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h +++ b/Source/WebKit2/UIProcess/gtk/WebContextMenuProxyGtk.h @@ -28,42 +28,41 @@ #if ENABLE(CONTEXT_MENUS) +#include "WebContextMenuItemGtk.h" #include "WebContextMenuProxy.h" -#include <WebCore/ContextMenu.h> #include <WebCore/IntPoint.h> #include <wtf/HashMap.h> +#include <wtf/glib/GRefPtr.h> + +typedef struct _GMenu GMenu; namespace WebKit { +class WebContextMenuItem; class WebContextMenuItemData; class WebPageProxy; class WebContextMenuProxyGtk : public WebContextMenuProxy { public: - static PassRefPtr<WebContextMenuProxyGtk> create(GtkWidget* webView, WebPageProxy* page) - { - return adoptRef(new WebContextMenuProxyGtk(webView, page)); - } + WebContextMenuProxyGtk(GtkWidget*, WebPageProxy&, const ContextMenuContextData&, const UserData&); ~WebContextMenuProxyGtk(); - virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&); - virtual void hideContextMenu(); - - void populate(Vector<WebCore::ContextMenuItem>&); - GtkMenu* gtkMenu() const { return m_menu.platformDescription(); } + void populate(const Vector<WebContextMenuItemGtk>&); + GtkMenu* gtkMenu() const { return m_menu; } private: - WebContextMenuProxyGtk(GtkWidget*, WebPageProxy*); - - void append(WebCore::ContextMenuItem&); - void populate(const Vector<WebContextMenuItemData>&); + void show() override; + void showContextMenuWithItems(const Vector<WebContextMenuItemData>&) override; + void append(GMenu*, const WebContextMenuItemGtk&); + GRefPtr<GMenu> buildMenu(const Vector<WebContextMenuItemGtk>&); + void populate(const Vector<RefPtr<WebContextMenuItem>>&); static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, WebContextMenuProxyGtk*); GtkWidget* m_webView; WebPageProxy* m_page; - WebCore::ContextMenu m_menu; + GtkMenu* m_menu; WebCore::IntPoint m_popupPosition; - HashMap<unsigned long, GtkAction*> m_signalHandlers; + HashMap<unsigned long, void*> m_signalHandlers; }; diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp index 5884c32ad..f42473345 100644 --- a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.cpp @@ -27,7 +27,7 @@ #include "WebInspectorClientGtk.h" #include "WKAPICast.h" -#include "WKSharedAPICast.h" +#include "WebInspectorProxy.h" #include <wtf/text/WTFString.h> namespace WebKit { @@ -88,4 +88,11 @@ void WebInspectorClientGtk::didChangeAttachedWidth(WebInspectorProxy* inspector, m_client.didChangeAttachedWidth(toAPI(inspector), width, m_client.base.clientInfo); } +void WebInspectorClientGtk::didChangeAttachAvailability(WebInspectorProxy* inspector, bool available) +{ + if (!m_client.didChangeAttachAvailability) + return; + m_client.didChangeAttachAvailability(toAPI(inspector), available, m_client.base.clientInfo); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h index 9d7b0eb68..2d4f6193f 100644 --- a/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h +++ b/Source/WebKit2/UIProcess/gtk/WebInspectorClientGtk.h @@ -23,12 +23,10 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WebInspectorClientGtk_h -#define WebInspectorClientGtk_h +#pragma once #include "APIClient.h" #include "WKInspectorClientGtk.h" - #include <wtf/text/WTFString.h> namespace API { @@ -53,8 +51,7 @@ public: bool detach(WebInspectorProxy*); void didChangeAttachedHeight(WebInspectorProxy*, unsigned height); void didChangeAttachedWidth(WebInspectorProxy*, unsigned width); + void didChangeAttachAvailability(WebInspectorProxy*, bool available); }; } // namespace WebKit - -#endif // WebInspectorClientGtk_h diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp index 231bc4ffb..b46d114a4 100644 --- a/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebInspectorProxyGtk.cpp @@ -29,16 +29,16 @@ #include "config.h" #include "WebInspectorProxy.h" -#if ENABLE(INSPECTOR) - #include "WebKitWebViewBasePrivate.h" +#include "WebPageGroup.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" #include <WebCore/FileSystem.h> #include <WebCore/GtkUtilities.h> #include <WebCore/NotImplemented.h> #include <glib/gi18n-lib.h> #include <gtk/gtk.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> @@ -53,6 +53,11 @@ static void inspectorViewDestroyed(GtkWidget*, gpointer userData) inspectorProxy->close(); } +static unsigned long long exceededDatabaseQuota(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKStringRef, WKStringRef, unsigned long long, unsigned long long, unsigned long long currentDatabaseUsage, unsigned long long expectedUsage, const void*) +{ + return std::max<unsigned long long>(expectedUsage, currentDatabaseUsage * 1.25); +} + void WebInspectorProxy::initializeInspectorClientGtk(const WKInspectorClientGtkBase* inspectorClient) { m_client.initialize(inspectorClient); @@ -60,11 +65,81 @@ void WebInspectorProxy::initializeInspectorClientGtk(const WKInspectorClientGtkB WebPageProxy* WebInspectorProxy::platformCreateInspectorPage() { - ASSERT(m_page); + ASSERT(inspectedPage()); ASSERT(!m_inspectorView); - m_inspectorView = GTK_WIDGET(webkitWebViewBaseCreate(&page()->process().context(), inspectorPageGroup(), m_page)); + + RefPtr<WebPreferences> preferences = WebPreferences::create(String(), "WebKit2.", "WebKit2."); +#if ENABLE(DEVELOPER_MODE) + // Allow developers to inspect the Web Inspector in debug builds without changing settings. + preferences->setDeveloperExtrasEnabled(true); + preferences->setLogsPageMessagesToSystemConsoleEnabled(true); +#endif + preferences->setJavaScriptRuntimeFlags({ + }); + RefPtr<WebPageGroup> pageGroup = WebPageGroup::create(inspectorPageGroupIdentifierForPage(inspectedPage()), false, false); + + auto pageConfiguration = API::PageConfiguration::create(); + pageConfiguration->setProcessPool(&inspectorProcessPool(inspectionLevel())); + pageConfiguration->setPreferences(preferences.get()); + pageConfiguration->setPageGroup(pageGroup.get()); + m_inspectorView = GTK_WIDGET(webkitWebViewBaseCreate(*pageConfiguration.ptr())); g_object_add_weak_pointer(G_OBJECT(m_inspectorView), reinterpret_cast<void**>(&m_inspectorView)); - return webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_inspectorView)); + + WKPageUIClientV2 uiClient = { + { 2, this }, + nullptr, // createNewPage_deprecatedForUseWithV0 + nullptr, // showPage + nullptr, // closePage + nullptr, // takeFocus + nullptr, // focus + nullptr, // unfocus + nullptr, // runJavaScriptAlert + nullptr, // runJavaScriptConfirm + nullptr, // runJavaScriptPrompt + nullptr, // setStatusText + nullptr, // mouseDidMoveOverElement_deprecatedForUseWithV0 + nullptr, // missingPluginButtonClicked_deprecatedForUseWithV0 + nullptr, // didNotHandleKeyEvent + nullptr, // didNotHandleWheelEvent + nullptr, // areToolbarsVisible + nullptr, // setToolbarsVisible + nullptr, // isMenuBarVisible + nullptr, // setMenuBarVisible + nullptr, // isStatusBarVisible + nullptr, // setStatusBarVisible + nullptr, // isResizable + nullptr, // setResizable + nullptr, // getWindowFrame, + nullptr, // setWindowFrame, + nullptr, // runBeforeUnloadConfirmPanel + nullptr, // didDraw + nullptr, // pageDidScroll + exceededDatabaseQuota, + nullptr, // runOpenPanel, + nullptr, // decidePolicyForGeolocationPermissionRequest + nullptr, // headerHeight + nullptr, // footerHeight + nullptr, // drawHeader + nullptr, // drawFooter + nullptr, // printFrame + nullptr, // runModal + nullptr, // unused + nullptr, // saveDataToFileInDownloadsFolder + nullptr, // shouldInterruptJavaScript + nullptr, // createPage + nullptr, // mouseDidMoveOverElement + nullptr, // decidePolicyForNotificationPermissionRequest + nullptr, // unavailablePluginButtonClicked_deprecatedForUseWithV1 + nullptr, // showColorPicker + nullptr, // hideColorPicker + nullptr, // unavailablePluginButtonClicked + }; + + WebPageProxy* inspectorPage = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_inspectorView)); + ASSERT(inspectorPage); + WKPageSetPageUIClient(toAPI(inspectorPage), &uiClient.base); + + return inspectorPage; } void WebInspectorProxy::createInspectorWindow() @@ -75,11 +150,18 @@ void WebInspectorProxy::createInspectorWindow() ASSERT(!m_inspectorWindow); m_inspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); - GtkWidget* inspectedViewParent = gtk_widget_get_toplevel(m_page->viewWidget()); + GtkWidget* inspectedViewParent = gtk_widget_get_toplevel(inspectedPage()->viewWidget()); if (WebCore::widgetIsOnscreenToplevelWindow(inspectedViewParent)) gtk_window_set_transient_for(GTK_WINDOW(m_inspectorWindow), GTK_WINDOW(inspectedViewParent)); - gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), _("Web Inspector")); +#if GTK_CHECK_VERSION(3, 10, 0) + m_headerBar = gtk_header_bar_new(); + gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(m_headerBar), TRUE); + gtk_window_set_titlebar(GTK_WINDOW(m_inspectorWindow), m_headerBar); + gtk_widget_show(m_headerBar); +#endif + + updateInspectorWindowTitle(); gtk_window_set_default_size(GTK_WINDOW(m_inspectorWindow), initialWindowWidth, initialWindowHeight); gtk_container_add(GTK_CONTAINER(m_inspectorWindow), m_inspectorView); @@ -89,6 +171,23 @@ void WebInspectorProxy::createInspectorWindow() gtk_window_present(GTK_WINDOW(m_inspectorWindow)); } +void WebInspectorProxy::updateInspectorWindowTitle() const +{ + ASSERT(m_inspectorWindow); + if (m_inspectedURLString.isEmpty()) { + gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), _("Web Inspector")); + return; + } + +#if GTK_CHECK_VERSION(3, 10, 0) + gtk_header_bar_set_title(GTK_HEADER_BAR(m_headerBar), _("Web Inspector")); + gtk_header_bar_set_subtitle(GTK_HEADER_BAR(m_headerBar), m_inspectedURLString.utf8().data()); +#else + GUniquePtr<gchar> title(g_strdup_printf("%s - %s", _("Web Inspector"), m_inspectedURLString.utf8().data())); + gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), title.get()); +#endif +} + void WebInspectorProxy::platformOpen() { ASSERT(!m_inspectorWindow); @@ -115,6 +214,14 @@ void WebInspectorProxy::platformDidClose() m_inspectorView = 0; } +void WebInspectorProxy::platformDidCloseForCrash() +{ +} + +void WebInspectorProxy::platformInvalidate() +{ +} + void WebInspectorProxy::platformHide() { notImplemented(); @@ -130,6 +237,11 @@ void WebInspectorProxy::platformBringToFront() gtk_window_present(GTK_WINDOW(parent)); } +void WebInspectorProxy::platformBringInspectedPageToFront() +{ + notImplemented(); +} + bool WebInspectorProxy::platformIsFront() { GtkWidget* parent = gtk_widget_get_toplevel(m_inspectorView); @@ -140,32 +252,36 @@ bool WebInspectorProxy::platformIsFront() void WebInspectorProxy::platformInspectedURLChanged(const String& url) { + m_inspectedURLString = url; m_client.inspectedURLChanged(this, url); - if (!m_inspectorWindow) - return; - GUniquePtr<gchar> title(g_strdup_printf("%s - %s", _("Web Inspector"), url.utf8().data())); - gtk_window_set_title(GTK_WINDOW(m_inspectorWindow), title.get()); + if (m_inspectorWindow) + updateInspectorWindowTitle(); } -String WebInspectorProxy::inspectorPageURL() const +String WebInspectorProxy::inspectorPageURL() { return String("resource:///org/webkitgtk/inspector/UserInterface/Main.html"); } -String WebInspectorProxy::inspectorBaseURL() const +String WebInspectorProxy::inspectorTestPageURL() +{ + return String("resource:///org/webkitgtk/inspector/UserInterface/Test.html"); +} + +String WebInspectorProxy::inspectorBaseURL() { return String("resource:///org/webkitgtk/inspector/UserInterface/"); } unsigned WebInspectorProxy::platformInspectedWindowHeight() { - return gtk_widget_get_allocated_height(m_page->viewWidget()); + return gtk_widget_get_allocated_height(inspectedPage()->viewWidget()); } unsigned WebInspectorProxy::platformInspectedWindowWidth() { - return gtk_widget_get_allocated_width(m_page->viewWidget()); + return gtk_widget_get_allocated_width(inspectedPage()->viewWidget()); } void WebInspectorProxy::platformAttach() @@ -177,9 +293,12 @@ void WebInspectorProxy::platformAttach() m_inspectorWindow = 0; } - // Set a default attached size based on InspectorFrontendClientLocal. + // Set a default sizes based on InspectorFrontendClientLocal. static const unsigned defaultAttachedSize = 300; - if (m_attachmentSide == AttachmentSideBottom) { + static const unsigned minimumAttachedWidth = 750; + static const unsigned minimumAttachedHeight = 250; + + if (m_attachmentSide == AttachmentSide::Bottom) { unsigned maximumAttachedHeight = platformInspectedWindowHeight() * 3 / 4; platformSetAttachedWindowHeight(std::max(minimumAttachedHeight, std::min(defaultAttachedSize, maximumAttachedHeight))); } else { @@ -190,24 +309,33 @@ void WebInspectorProxy::platformAttach() if (m_client.attach(this)) return; - webkitWebViewBaseAddWebInspector(WEBKIT_WEB_VIEW_BASE(m_page->viewWidget()), m_inspectorView, m_attachmentSide); + webkitWebViewBaseAddWebInspector(WEBKIT_WEB_VIEW_BASE(inspectedPage()->viewWidget()), m_inspectorView, m_attachmentSide); gtk_widget_show(m_inspectorView); } void WebInspectorProxy::platformDetach() { - if (!m_page->isValid()) + if (!inspectedPage()->isValid()) return; GRefPtr<GtkWidget> inspectorView = m_inspectorView; if (!m_client.detach(this)) { - GtkWidget* parent = gtk_widget_get_parent(m_inspectorView); - ASSERT(parent); - gtk_container_remove(GTK_CONTAINER(parent), m_inspectorView); + // Detach is called when m_isAttached is true, but it could called before + // the inspector is opened if the inspector is shown/closed quickly. So, + // we might not have a parent yet. + if (GtkWidget* parent = gtk_widget_get_parent(m_inspectorView)) + gtk_container_remove(GTK_CONTAINER(parent), m_inspectorView); } - if (!m_isVisible) + // Return early if we are not visible. This means the inspector was closed while attached + // and we should not create and show the inspector window. + if (!m_isVisible) { + // The inspector view will be destroyed, but we don't need to notify the web process to close the + // inspector in this case, since it's already closed. + g_signal_handlers_disconnect_by_func(m_inspectorView, reinterpret_cast<void*>(inspectorViewDestroyed), this); + m_inspectorView = nullptr; return; + } createInspectorWindow(); } @@ -218,7 +346,7 @@ void WebInspectorProxy::platformSetAttachedWindowHeight(unsigned height) return; m_client.didChangeAttachedHeight(this, height); - webkitWebViewBaseSetInspectorViewSize(WEBKIT_WEB_VIEW_BASE(m_page->viewWidget()), height); + webkitWebViewBaseSetInspectorViewSize(WEBKIT_WEB_VIEW_BASE(inspectedPage()->viewWidget()), height); } void WebInspectorProxy::platformSetAttachedWindowWidth(unsigned width) @@ -227,10 +355,10 @@ void WebInspectorProxy::platformSetAttachedWindowWidth(unsigned width) return; m_client.didChangeAttachedWidth(this, width); - webkitWebViewBaseSetInspectorViewSize(WEBKIT_WEB_VIEW_BASE(m_page->viewWidget()), width); + webkitWebViewBaseSetInspectorViewSize(WEBKIT_WEB_VIEW_BASE(inspectedPage()->viewWidget()), width); } -void WebInspectorProxy::platformSetToolbarHeight(unsigned) +void WebInspectorProxy::platformStartWindowDrag() { notImplemented(); } @@ -245,11 +373,9 @@ void WebInspectorProxy::platformAppend(const String&, const String&) notImplemented(); } -void WebInspectorProxy::platformAttachAvailabilityChanged(bool) +void WebInspectorProxy::platformAttachAvailabilityChanged(bool available) { - notImplemented(); + m_client.didChangeAttachAvailability(this, available); } } // namespace WebKit - -#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp index ac5ba7352..ff8b4aa0b 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp @@ -27,14 +27,17 @@ #include "config.h" #include "WebPageProxy.h" -#include "NativeWebKeyboardEvent.h" #include "NotImplemented.h" #include "PageClientImpl.h" #include "WebKitWebViewBasePrivate.h" #include "WebPageMessages.h" +#include "WebPasteboardProxy.h" #include "WebProcessProxy.h" -#include <WebCore/UserAgentGtk.h> +#include "WebsiteDataStore.h" +#include <WebCore/PlatformDisplay.h> +#include <WebCore/UserAgent.h> #include <gtk/gtkx.h> +#include <wtf/NeverDestroyed.h> namespace WebKit { @@ -52,34 +55,42 @@ String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent return WebCore::standardUserAgent(applicationNameForUserAgent); } -void WebPageProxy::getEditorCommandsForKeyEvent(const AtomicString& eventType, Vector<WTF::String>& commandsList) +void WebPageProxy::bindAccessibilityTree(const String& plugID) { - // When the keyboard event is started in the WebProcess side (e.g. from the Inspector) - // it will arrive without a GdkEvent associated, so the keyEventQueue will be empty. - if (!m_keyEventQueue.isEmpty()) - m_pageClient.getEditorCommandsForKeyEvent(m_keyEventQueue.first(), eventType, commandsList); + m_accessibilityPlugID = plugID; } -void WebPageProxy::bindAccessibilityTree(const String& plugID) +void WebPageProxy::saveRecentSearches(const String&, const Vector<WebCore::RecentSearch>&) { - m_accessibilityPlugID = plugID; + notImplemented(); } -void WebPageProxy::saveRecentSearches(const String&, const Vector<String>&) +void WebPageProxy::loadRecentSearches(const String&, Vector<WebCore::RecentSearch>&) { notImplemented(); } -void WebPageProxy::loadRecentSearches(const String&, Vector<String>&) +void WebsiteDataStore::platformRemoveRecentSearches(std::chrono::system_clock::time_point oldestTimeToRemove) { notImplemented(); } +void WebPageProxy::editorStateChanged(const EditorState& editorState) +{ + m_editorState = editorState; + + if (editorState.shouldIgnoreCompositionSelectionChange) + return; + if (m_editorState.selectionIsRange) + WebPasteboardProxy::singleton().setPrimarySelectionOwner(focusedFrame()); + m_pageClient.selectionDidChange(); +} + #if PLUGIN_ARCHITECTURE(X11) typedef HashMap<uint64_t, GtkWidget* > PluginWindowMap; static PluginWindowMap& pluginWindowMap() { - DEFINE_STATIC_LOCAL(PluginWindowMap, map, ()); + static NeverDestroyed<PluginWindowMap> map; return map; } @@ -92,6 +103,7 @@ static gboolean pluginContainerPlugRemoved(GtkSocket* socket) void WebPageProxy::createPluginContainer(uint64_t& windowID) { + RELEASE_ASSERT(WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::X11); GtkWidget* socket = gtk_socket_new(); g_signal_connect(socket, "plug-removed", G_CALLBACK(pluginContainerPlugRemoved), 0); gtk_container_add(GTK_CONTAINER(viewWidget()), socket); @@ -134,10 +146,10 @@ void WebPageProxy::setInputMethodState(bool enabled) webkitWebViewBaseSetInputMethodState(WEBKIT_WEB_VIEW_BASE(viewWidget()), enabled); } -#if USE(TEXTURE_MAPPER_GL) -void WebPageProxy::setAcceleratedCompositingWindowId(uint64_t nativeWindowId) +#if HAVE(GTK_GESTURES) +void WebPageProxy::getCenterForZoomGesture(const WebCore::IntPoint& centerInViewCoordinates, WebCore::IntPoint& center) { - process().send(Messages::WebPage::SetAcceleratedCompositingWindowId(nativeWindowId), m_pageID); + process().sendSync(Messages::WebPage::GetCenterForZoomGesture(centerInViewCoordinates), Messages::WebPage::GetCenterForZoomGesture::Reply(center), m_pageID); } #endif diff --git a/Source/WebKit2/UIProcess/WebNetworkInfoProvider.cpp b/Source/WebKit2/UIProcess/gtk/WebPasteboardProxyGtk.cpp index fffdf0d35..1b15869bd 100644 --- a/Source/WebKit2/UIProcess/WebNetworkInfoProvider.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPasteboardProxyGtk.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Red Hat Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,49 +24,47 @@ */ #include "config.h" -#include "WebNetworkInfoProvider.h" +#include "WebPasteboardProxy.h" -#if ENABLE(NETWORK_INFO) +#include "WebFrameProxy.h" +#include "WebSelectionData.h" +#include <WebCore/PlatformPasteboard.h> +#include <wtf/SetForScope.h> -#include "WKAPICast.h" -#include "WebNetworkInfoManagerProxy.h" -#include <limits.h> +using namespace WebCore; namespace WebKit { -void WebNetworkInfoProvider::startUpdating(WebNetworkInfoManagerProxy* networkInfoManager) +void WebPasteboardProxy::writeToClipboard(const String& pasteboardName, const WebSelectionData& selection) { - if (!m_client.startUpdating) - return; - - m_client.startUpdating(toAPI(networkInfoManager), m_client.base.clientInfo); + SetForScope<WebFrameProxy*> frameWritingToClipboard(m_frameWritingToClipboard, m_primarySelectionOwner); + PlatformPasteboard(pasteboardName).writeToClipboard(selection.selectionData, [this] { + if (m_frameWritingToClipboard == m_primarySelectionOwner) + return; + setPrimarySelectionOwner(nullptr); + }); } -void WebNetworkInfoProvider::stopUpdating(WebNetworkInfoManagerProxy* networkInfoManager) +void WebPasteboardProxy::readFromClipboard(const String& pasteboardName, WebSelectionData& selection) { - if (!m_client.stopUpdating) - return; - - m_client.stopUpdating(toAPI(networkInfoManager), m_client.base.clientInfo); + selection = WebSelectionData(PlatformPasteboard(pasteboardName).readFromClipboard()); } -double WebNetworkInfoProvider::bandwidth(WebNetworkInfoManagerProxy* networkInfoManager) const +void WebPasteboardProxy::setPrimarySelectionOwner(WebFrameProxy* frame) { - // The spec indicates that we should return "infinity" if the bandwidth is unknown. - if (!m_client.bandwidth) - return std::numeric_limits<double>::infinity(); + if (m_primarySelectionOwner == frame) + return; + + if (m_primarySelectionOwner) + m_primarySelectionOwner->collapseSelection(); - return m_client.bandwidth(toAPI(networkInfoManager), m_client.base.clientInfo); + m_primarySelectionOwner = frame; } -bool WebNetworkInfoProvider::isMetered(WebNetworkInfoManagerProxy* networkInfoManager) const +void WebPasteboardProxy::didDestroyFrame(WebFrameProxy* frame) { - if (!m_client.isMetered) - return false; - - return m_client.isMetered(toAPI(networkInfoManager), m_client.base.clientInfo); + if (frame == m_primarySelectionOwner) + m_primarySelectionOwner = nullptr; } } // namespace WebKit - -#endif // ENABLE(NETWORK_INFO) diff --git a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp index 782730de7..2eb0ec488 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp @@ -29,27 +29,28 @@ #include "NativeWebMouseEvent.h" #include "WebPopupItem.h" #include <WebCore/GtkUtilities.h> +#include <WebCore/IntRect.h> #include <gtk/gtk.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> using namespace WebCore; namespace WebKit { -WebPopupMenuProxyGtk::WebPopupMenuProxyGtk(GtkWidget* webView, WebPopupMenuProxy::Client* client) +WebPopupMenuProxyGtk::WebPopupMenuProxyGtk(GtkWidget* webView, WebPopupMenuProxy::Client& client) : WebPopupMenuProxy(client) , m_webView(webView) - , m_activeItem(-1) + , m_popup(gtk_menu_new()) + , m_dismissMenuTimer(RunLoop::main(), this, &WebPopupMenuProxyGtk::dismissMenuTimerFired) { + g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this); + g_signal_connect(m_popup, "unmap", G_CALLBACK(menuUnmappedCallback), this); } WebPopupMenuProxyGtk::~WebPopupMenuProxyGtk() { - if (m_popup) { - g_signal_handlers_disconnect_matched(m_popup->platformMenu(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); - hidePopupMenu(); - } + cancelTracking(); } GtkAction* WebPopupMenuProxyGtk::createGtkActionForMenuItem(const WebPopupItem& item, int itemIndex) @@ -63,74 +64,222 @@ GtkAction* WebPopupMenuProxyGtk::createGtkActionForMenuItem(const WebPopupItem& return action; } -void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection textDirection, double pageScaleFactor, const Vector<WebPopupItem>& items, const PlatformPopupMenuData& data, int32_t selectedIndex) +void WebPopupMenuProxyGtk::populatePopupMenu(const Vector<WebPopupItem>& items) { - if (m_popup) - m_popup->clear(); - else - m_popup = GtkPopupMenu::create(); - - const int size = items.size(); - for (int i = 0; i < size; i++) { - if (items[i].m_type == WebPopupItem::Separator) - m_popup->appendSeparator(); - else { - GRefPtr<GtkAction> action = adoptGRef(createGtkActionForMenuItem(items[i], i)); - m_popup->appendItem(action.get()); + int itemIndex = 0; + for (const auto& item : items) { + if (item.m_type == WebPopupItem::Separator) { + GtkWidget* menuItem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(m_popup), menuItem); + gtk_widget_show(menuItem); + } else { + GRefPtr<GtkAction> action = adoptGRef(createGtkActionForMenuItem(item, itemIndex)); + GtkWidget* menuItem = gtk_action_create_menu_item(action.get()); + gtk_widget_set_tooltip_text(menuItem, gtk_action_get_tooltip(action.get())); + g_signal_connect(menuItem, "select", G_CALLBACK(selectItemCallback), this); + gtk_menu_shell_append(GTK_MENU_SHELL(m_popup), menuItem); + + if (gtk_action_is_visible(action.get())) + gtk_widget_show(menuItem); } + itemIndex++; } +} + +void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection, double /* pageScaleFactor */, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex) +{ + m_dismissMenuTimer.stop(); + + populatePopupMenu(items); + gtk_menu_set_active(GTK_MENU(m_popup), selectedIndex); + + resetTypeAheadFindState(); IntPoint menuPosition = convertWidgetPointToScreenPoint(m_webView, rect.location()); menuPosition.move(0, rect.height()); - gulong unmapHandler = g_signal_connect(m_popup->platformMenu(), "unmap", G_CALLBACK(menuUnmapped), this); - m_popup->popUp(rect.size(), menuPosition, size, selectedIndex, m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : 0); + // This approach follows the one in gtkcombobox.c. + GtkRequisition requisition; + gtk_widget_set_size_request(m_popup, -1, -1); + gtk_widget_get_preferred_size(m_popup, &requisition, nullptr); + gtk_widget_set_size_request(m_popup, std::max(rect.width(), requisition.width), -1); + + if (int itemCount = items.size()) { + GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(m_popup))); + int i; + GList* child; + for (i = 0, child = children.get(); i < itemCount; i++, child = g_list_next(child)) { + if (i > selectedIndex) + break; + + GtkWidget* item = GTK_WIDGET(child->data); + GtkRequisition itemRequisition; + gtk_widget_get_preferred_size(item, &itemRequisition, nullptr); + menuPosition.setY(menuPosition.y() - itemRequisition.height); + } + } else { + // Center vertically the empty popup in the combo box area. + menuPosition.setY(menuPosition.y() - rect.height() / 2); + } + + gtk_menu_attach_to_widget(GTK_MENU(m_popup), GTK_WIDGET(m_webView), nullptr); + + const GdkEvent* event = m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : nullptr; + gtk_menu_popup_for_device(GTK_MENU(m_popup), event ? gdk_event_get_device(event) : nullptr, nullptr, nullptr, + [](GtkMenu*, gint* x, gint* y, gboolean* pushIn, gpointer userData) { + // We can pass a pointer to the menuPosition local variable because the nested main loop ensures this is called in the function context. + IntPoint* menuPosition = static_cast<IntPoint*>(userData); + *x = menuPosition->x(); + *y = menuPosition->y(); + *pushIn = menuPosition->y() < 0; + }, &menuPosition, nullptr, event && event->type == GDK_BUTTON_PRESS ? event->button.button : 1, + event ? gdk_event_get_time(event) : GDK_CURRENT_TIME); + + // Now that the menu has a position, schedule a resize to make sure it's resized to fit vertically in the work area. + gtk_widget_queue_resize(m_popup); // PopupMenu can fail to open when there is no mouse grab. // Ensure WebCore does not go into some pesky state. - if (!gtk_widget_get_visible(m_popup->platformMenu())) { + if (!gtk_widget_get_visible(m_popup)) { m_client->failedToShowPopupMenu(); return; } - // WebPageProxy expects the menu to run in a nested run loop, since it invalidates the - // menu right after calling WebPopupMenuProxy::showPopupMenu(). - m_runLoop = adoptGRef(g_main_loop_new(0, FALSE)); - - gdk_threads_leave(); - g_main_loop_run(m_runLoop.get()); - gdk_threads_enter(); - - m_runLoop.clear(); + // This ensures that the active item gets selected after popping up the menu, and + // as it says in "gtkcombobox.c" (line ~1606): it's ugly, but gets the job done. + GtkWidget* activeChild = gtk_menu_get_active(GTK_MENU(m_popup)); + if (activeChild && gtk_widget_get_visible(activeChild)) + gtk_menu_shell_select_item(GTK_MENU_SHELL(m_popup), activeChild); +} - g_signal_handler_disconnect(m_popup->platformMenu(), unmapHandler); +void WebPopupMenuProxyGtk::hidePopupMenu() +{ + gtk_menu_popdown(GTK_MENU(m_popup)); + resetTypeAheadFindState(); +} - if (!m_client) +void WebPopupMenuProxyGtk::cancelTracking() +{ + if (!m_popup) return; - m_client->valueChangedForPopupMenu(this, m_activeItem); + m_dismissMenuTimer.stop(); + g_signal_handlers_disconnect_matched(m_popup, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this); + hidePopupMenu(); + gtk_widget_destroy(m_popup); + m_popup = nullptr; } -void WebPopupMenuProxyGtk::hidePopupMenu() +bool WebPopupMenuProxyGtk::typeAheadFind(GdkEventKey* event) { - m_popup->popDown(); + // If we were given a non-printable character just skip it. + gunichar unicodeCharacter = gdk_keyval_to_unicode(event->keyval); + if (!g_unichar_isprint(unicodeCharacter)) { + resetTypeAheadFindState(); + return false; + } + + glong charactersWritten; + GUniquePtr<gunichar2> utf16String(g_ucs4_to_utf16(&unicodeCharacter, 1, nullptr, &charactersWritten, nullptr)); + if (!utf16String) { + resetTypeAheadFindState(); + return false; + } + + // If the character is the same as the last character, the user is probably trying to + // cycle through the menulist entries. This matches the WebCore behavior for collapsed menulists. + static const uint32_t searchTimeoutMs = 1000; + bool repeatingCharacter = unicodeCharacter != m_previousKeyEventCharacter; + if (event->time - m_previousKeyEventTimestamp > searchTimeoutMs) + m_currentSearchString = String(reinterpret_cast<UChar*>(utf16String.get()), charactersWritten); + else if (repeatingCharacter) + m_currentSearchString.append(String(reinterpret_cast<UChar*>(utf16String.get()), charactersWritten)); + + m_previousKeyEventTimestamp = event->time; + m_previousKeyEventCharacter = unicodeCharacter; + + GUniquePtr<GList> children(gtk_container_get_children(GTK_CONTAINER(m_popup))); + if (!children) + return true; + + // We case fold before searching, because strncmp does not handle non-ASCII characters. + GUniquePtr<gchar> searchStringWithCaseFolded(g_utf8_casefold(m_currentSearchString.utf8().data(), -1)); + size_t prefixLength = strlen(searchStringWithCaseFolded.get()); + + // If a menu item has already been selected, start searching from the current + // item down the list. This will make multiple key presses of the same character + // advance the selection. + GList* currentChild = children.get(); + if (m_currentlySelectedMenuItem) { + currentChild = g_list_find(children.get(), m_currentlySelectedMenuItem); + if (!currentChild) { + m_currentlySelectedMenuItem = nullptr; + currentChild = children.get(); + } + + // Repeating characters should iterate. + if (repeatingCharacter) { + if (GList* nextChild = g_list_next(currentChild)) + currentChild = nextChild; + } + } + + GList* firstChild = currentChild; + do { + currentChild = g_list_next(currentChild); + if (!currentChild) + currentChild = children.get(); + + GUniquePtr<gchar> itemText(g_utf8_casefold(gtk_menu_item_get_label(GTK_MENU_ITEM(currentChild->data)), -1)); + if (!strncmp(searchStringWithCaseFolded.get(), itemText.get(), prefixLength)) { + gtk_menu_shell_select_item(GTK_MENU_SHELL(m_popup), GTK_WIDGET(currentChild->data)); + break; + } + } while (currentChild != firstChild); + + return true; } -void WebPopupMenuProxyGtk::shutdownRunLoop() +void WebPopupMenuProxyGtk::resetTypeAheadFindState() { - if (g_main_loop_is_running(m_runLoop.get())) - g_main_loop_quit(m_runLoop.get()); + m_currentlySelectedMenuItem = nullptr; + m_previousKeyEventCharacter = 0; + m_previousKeyEventTimestamp = 0; + m_currentSearchString = emptyString(); } void WebPopupMenuProxyGtk::menuItemActivated(GtkAction* action, WebPopupMenuProxyGtk* popupMenu) { - popupMenu->setActiveItem(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "popup-menu-action-index"))); - popupMenu->shutdownRunLoop(); + popupMenu->m_dismissMenuTimer.stop(); + if (popupMenu->m_client) + popupMenu->m_client->valueChangedForPopupMenu(popupMenu, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "popup-menu-action-index"))); +} + +void WebPopupMenuProxyGtk::dismissMenuTimerFired() +{ + if (m_client) + m_client->valueChangedForPopupMenu(this, -1); +} + +void WebPopupMenuProxyGtk::menuUnmappedCallback(GtkWidget*, WebPopupMenuProxyGtk* popupMenu) +{ + if (!popupMenu->m_client) + return; + + // When an item is activated, the menu is first hidden and then activate signal is emitted, so at this point we don't know + // if the menu has been hidden because an item has been selected or because the menu has been dismissed. Wait until the next + // main loop iteration to dismiss the menu, if an item is activated the timer will be cancelled. + popupMenu->m_dismissMenuTimer.startOneShot(0); +} + +void WebPopupMenuProxyGtk::selectItemCallback(GtkWidget* item, WebPopupMenuProxyGtk* popupMenu) +{ + popupMenu->setCurrentlySelectedMenuItem(item); } -void WebPopupMenuProxyGtk::menuUnmapped(GtkWidget*, WebPopupMenuProxyGtk* popupMenu) +gboolean WebPopupMenuProxyGtk::keyPressEventCallback(GtkWidget*, GdkEventKey* event, WebPopupMenuProxyGtk* popupMenu) { - popupMenu->shutdownRunLoop(); + return popupMenu->typeAheadFind(event); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h index 4b335bcde..c9ceb6988 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h +++ b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h @@ -21,11 +21,16 @@ #define WebPopupMenuProxyGtk_h #include "WebPopupMenuProxy.h" -#include <WebCore/GtkPopupMenu.h> -#include <WebCore/IntRect.h> -#include <wtf/gobject/GRefPtr.h> +#include <wtf/RunLoop.h> +#include <wtf/glib/GRefPtr.h> +#include <wtf/text/WTFString.h> typedef struct _GMainLoop GMainLoop; +typedef struct _GdkEventKey GdkEventKey; + +namespace WebCore { +class IntRect; +} namespace WebKit { @@ -33,28 +38,42 @@ class WebPageProxy; class WebPopupMenuProxyGtk : public WebPopupMenuProxy { public: - static PassRefPtr<WebPopupMenuProxyGtk> create(GtkWidget* webView, WebPopupMenuProxy::Client* client) + static Ref<WebPopupMenuProxyGtk> create(GtkWidget* webView, WebPopupMenuProxy::Client& client) { - return adoptRef(new WebPopupMenuProxyGtk(webView, client)); + return adoptRef(*new WebPopupMenuProxyGtk(webView, client)); } ~WebPopupMenuProxyGtk(); - virtual void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex); - virtual void hidePopupMenu(); + void showPopupMenu(const WebCore::IntRect&, WebCore::TextDirection, double pageScaleFactor, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex) override; + void hidePopupMenu() override; + void cancelTracking() override; private: - WebPopupMenuProxyGtk(GtkWidget*, WebPopupMenuProxy::Client*); - void shutdownRunLoop(); - void setActiveItem(int activeItem) { m_activeItem = activeItem; } + WebPopupMenuProxyGtk(GtkWidget*, WebPopupMenuProxy::Client&); + + void setCurrentlySelectedMenuItem(GtkWidget* item) { m_currentlySelectedMenuItem = item; } GtkAction* createGtkActionForMenuItem(const WebPopupItem&, int itemIndex); + void populatePopupMenu(const Vector<WebPopupItem>&); + void dismissMenuTimerFired(); + + bool typeAheadFind(GdkEventKey*); + void resetTypeAheadFindState(); static void menuItemActivated(GtkAction*, WebPopupMenuProxyGtk*); - static void menuUnmapped(GtkWidget*, WebPopupMenuProxyGtk*); + static void selectItemCallback(GtkWidget*, WebPopupMenuProxyGtk*); + static gboolean keyPressEventCallback(GtkWidget*, GdkEventKey*, WebPopupMenuProxyGtk*); + static void menuUnmappedCallback(GtkWidget*, WebPopupMenuProxyGtk*); + + GtkWidget* m_webView { nullptr }; + GtkWidget* m_popup { nullptr }; + + RunLoop::Timer<WebPopupMenuProxyGtk> m_dismissMenuTimer; - GtkWidget* m_webView; - OwnPtr<WebCore::GtkPopupMenu> m_popup; - int m_activeItem; - GRefPtr<GMainLoop> m_runLoop; + // Typeahead find. + unsigned m_previousKeyEventCharacter { 0 }; + uint32_t m_previousKeyEventTimestamp { 0 }; + GtkWidget* m_currentlySelectedMenuItem { nullptr }; + String m_currentSearchString; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/WebPreferencesGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPreferencesGtk.cpp index 321a9cfcc..eca423b71 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPreferencesGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPreferencesGtk.cpp @@ -27,13 +27,17 @@ #include "config.h" #include "WebPreferences.h" +#include "HardwareAccelerationManager.h" #include <WebCore/NotImplemented.h> namespace WebKit { void WebPreferences::platformInitializeStore() { - notImplemented(); + if (!HardwareAccelerationManager::singleton().canUseHardwareAcceleration()) + setAcceleratedCompositingEnabled(false); + else if (HardwareAccelerationManager::singleton().forceHardwareAcceleration()) + setForceCompositingMode(true); } void WebPreferences::platformUpdateStringValueForKey(const String&, const String&) @@ -61,4 +65,28 @@ void WebPreferences::platformUpdateFloatValueForKey(const String&, float) notImplemented(); } +bool WebPreferences::platformGetStringUserValueForKey(const String&, String&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetBoolUserValueForKey(const String&, bool&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetUInt32UserValueForKey(const String&, uint32_t&) +{ + notImplemented(); + return false; +} + +bool WebPreferences::platformGetDoubleUserValueForKey(const String&, double&) +{ + notImplemented(); + return false; +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/gtk/WebContextGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebProcessPoolGtk.cpp index fbddf8f67..4daf672e3 100644 --- a/Source/WebKit2/UIProcess/gtk/WebContextGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebProcessPoolGtk.cpp @@ -26,24 +26,20 @@ */ #include "config.h" -#include "WebContext.h" +#include "WebProcessPool.h" +#include "APIProcessPoolConfiguration.h" #include "Logging.h" #include "WebCookieManagerProxy.h" #include "WebInspectorServer.h" #include "WebProcessCreationParameters.h" #include "WebProcessMessages.h" -#include "WebSoupCustomProtocolRequestManager.h" #include <WebCore/FileSystem.h> #include <WebCore/NotImplemented.h> #include <WebCore/SchemeRegistry.h> -#include <wtf/gobject/GUniquePtr.h> +#include <wtf/glib/GUniquePtr.h> #include <wtf/text/CString.h> -#if ENABLE(NETWORK_PROCESS) -#include "NetworkProcessMessages.h" -#endif - namespace WebKit { static void initInspectorServer() @@ -61,7 +57,7 @@ static void initInspectorServer() unsigned short port = 2999; Vector<String> result; - serverAddress.split(":", result); + serverAddress.split(':', result); if (result.size() == 2) { bindAddress = result[0]; @@ -74,7 +70,7 @@ static void initInspectorServer() } else LOG_ERROR("Couldn't parse %s, wrong format? Use 127.0.0.1:2999 instead.", serverAddress.utf8().data()); - if (!WebInspectorServer::shared().listen(bindAddress, port)) + if (!WebInspectorServer::singleton().listen(bindAddress, port)) LOG_ERROR("Couldn't start listening on: IP address=%s, port=%d.", bindAddress.utf8().data(), port); return; } @@ -83,77 +79,60 @@ static void initInspectorServer() #endif } -WTF::String WebContext::platformDefaultApplicationCacheDirectory() const +WTF::String WebProcessPool::legacyPlatformDefaultApplicationCacheDirectory() { - GUniquePtr<gchar> cacheDirectory(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "applications", nullptr)); - return WebCore::filenameToString(cacheDirectory.get()); + return API::WebsiteDataStore::defaultApplicationCacheDirectory(); } -void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters) +WTF::String WebProcessPool::legacyPlatformDefaultMediaCacheDirectory() { - initInspectorServer(); - - if (!parameters.urlSchemesRegisteredAsLocal.contains("resource")) { - WebCore::SchemeRegistry::registerURLSchemeAsLocal("resource"); - parameters.urlSchemesRegisteredAsLocal.append("resource"); - } - - if (!usesNetworkProcess()) { - parameters.urlSchemesRegisteredForCustomProtocols = supplement<WebSoupCustomProtocolRequestManager>()->registeredSchemesForCustomProtocols(); - - supplement<WebCookieManagerProxy>()->getCookiePersistentStorage(parameters.cookiePersistentStoragePath, parameters.cookiePersistentStorageType); - parameters.cookieAcceptPolicy = m_initialHTTPCookieAcceptPolicy; + return API::WebsiteDataStore::defaultMediaCacheDirectory(); +} - parameters.ignoreTLSErrors = m_ignoreTLSErrors; - } +void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters) +{ + initInspectorServer(); + parameters.memoryCacheDisabled = m_memoryCacheDisabled || cacheModel() == CacheModelDocumentViewer; + parameters.proxySettings = m_networkProxySettings; +} - parameters.shouldTrackVisitedLinks = true; +void WebProcessPool::platformInvalidateContext() +{ } -void WebContext::platformInvalidateContext() +String WebProcessPool::legacyPlatformDefaultWebSQLDatabaseDirectory() { + return API::WebsiteDataStore::defaultWebSQLDatabaseDirectory(); } -String WebContext::platformDefaultDatabaseDirectory() const +String WebProcessPool::legacyPlatformDefaultIndexedDBDatabaseDirectory() { - GUniquePtr<gchar> databaseDirectory(g_build_filename(g_get_user_data_dir(), "webkitgtk", "databases", nullptr)); - return WebCore::filenameToString(databaseDirectory.get()); + return API::WebsiteDataStore::defaultIndexedDBDatabaseDirectory(); } -String WebContext::platformDefaultIconDatabasePath() const +String WebProcessPool::platformDefaultIconDatabasePath() const { GUniquePtr<gchar> databaseDirectory(g_build_filename(g_get_user_cache_dir(), "webkitgtk", "icondatabase", nullptr)); - return WebCore::filenameToString(databaseDirectory.get()); + return WebCore::stringFromFileSystemRepresentation(databaseDirectory.get()); } -String WebContext::platformDefaultLocalStorageDirectory() const +String WebProcessPool::legacyPlatformDefaultLocalStorageDirectory() { - GUniquePtr<gchar> storageDirectory(g_build_filename(g_get_user_data_dir(), "webkitgtk", "localstorage", nullptr)); - return WebCore::filenameToString(storageDirectory.get()); + return API::WebsiteDataStore::defaultLocalStorageDirectory(); } -String WebContext::platformDefaultDiskCacheDirectory() const +String WebProcessPool::legacyPlatformDefaultMediaKeysStorageDirectory() { - GUniquePtr<char> diskCacheDirectory(g_build_filename(g_get_user_cache_dir(), g_get_prgname(), nullptr)); - return WebCore::filenameToString(diskCacheDirectory.get()); + return API::WebsiteDataStore::defaultMediaKeysStorageDirectory(); } -String WebContext::platformDefaultCookieStorageDirectory() const +String WebProcessPool::legacyPlatformDefaultNetworkCacheDirectory() { - notImplemented(); - return String(); + return API::WebsiteDataStore::defaultNetworkCacheDirectory(); } -void WebContext::setIgnoreTLSErrors(bool ignoreTLSErrors) +void WebProcessPool::platformResolvePathsForSandboxExtensions() { - m_ignoreTLSErrors = ignoreTLSErrors; -#if ENABLE(NETWORK_PROCESS) - if (usesNetworkProcess() && networkProcess()) { - networkProcess()->send(Messages::NetworkProcess::SetIgnoreTLSErrors(m_ignoreTLSErrors), 0); - return; - } -#endif - sendToAllProcesses(Messages::WebProcess::SetIgnoreTLSErrors(m_ignoreTLSErrors)); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp b/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp new file mode 100644 index 000000000..0608ab72f --- /dev/null +++ b/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "MemoryPressureMonitor.h" + +#if OS(LINUX) + +#include "Attachment.h" +#include <errno.h> +#include <fcntl.h> +#include <mutex> +#include <stdlib.h> +#include <string.h> +#include <sys/eventfd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <wtf/CurrentTime.h> +#include <wtf/Threading.h> +#include <wtf/UniStdExtras.h> + +namespace WebKit { + +static const size_t notSet = static_cast<size_t>(-1); + +static const double s_minPollingIntervalInSeconds = 1; +static const double s_maxPollingIntervalInSeconds = 5; +static const double s_minUsedMemoryPercentageForPolling = 50; +static const double s_maxUsedMemoryPercentageForPolling = 90; +static const int s_memoryPresurePercentageThreshold = 95; + +static size_t lowWatermarkPages() +{ + FILE* file = fopen("/proc/zoneinfo", "r"); + if (!file) + return notSet; + + size_t low = 0; + bool inZone = false; + bool foundLow = false; + char buffer[128]; + while (char* line = fgets(buffer, 128, file)) { + if (!strncmp(line, "Node", 4)) { + inZone = true; + foundLow = false; + continue; + } + + char* token = strtok(line, " "); + if (!token) + continue; + + if (!strcmp(token, "low")) { + if (!inZone || foundLow) { + low = notSet; + break; + } + token = strtok(nullptr, " "); + if (!token) { + low = notSet; + break; + } + low += atoll(token); + foundLow = true; + } + } + fclose(file); + + return low; +} + +static inline size_t systemPageSize() +{ + static size_t pageSize = 0; + if (!pageSize) + pageSize = sysconf(_SC_PAGE_SIZE); + return pageSize; +} + +// If MemAvailable was not present in /proc/meminfo, because it's an old kernel version, +// we can do the same calculation with the information we have from meminfo and the low watermaks. +// See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773 +static size_t calculateMemoryAvailable(size_t memoryFree, size_t activeFile, size_t inactiveFile, size_t slabReclaimable) +{ + if (memoryFree == notSet || activeFile == notSet || inactiveFile == notSet || slabReclaimable == notSet) + return notSet; + + size_t lowWatermark = lowWatermarkPages(); + if (lowWatermark == notSet) + return notSet; + + lowWatermark *= systemPageSize() / KB; + + // Estimate the amount of memory available for userspace allocations, without causing swapping. + // Free memory cannot be taken below the low watermark, before the system starts swapping. + lowWatermark *= systemPageSize() / KB; + size_t memoryAvailable = memoryFree - lowWatermark; + + // Not all the page cache can be freed, otherwise the system will start swapping. Assume at least + // half of the page cache, or the low watermark worth of cache, needs to stay. + size_t pageCache = activeFile + inactiveFile; + pageCache -= std::min(pageCache / 2, lowWatermark); + memoryAvailable += pageCache; + + // Part of the reclaimable slab consists of items that are in use, and cannot be freed. + // Cap this estimate at the low watermark. + memoryAvailable += slabReclaimable - std::min(slabReclaimable / 2, lowWatermark); + return memoryAvailable; +} + +static int systemMemoryUsedAsPercentage() +{ + FILE* file = fopen("/proc/meminfo", "r"); + if (!file) + return -1; + + size_t memoryAvailable, memoryTotal, memoryFree, activeFile, inactiveFile, slabReclaimable; + memoryAvailable = memoryTotal = memoryFree = activeFile = inactiveFile = slabReclaimable = notSet; + char buffer[128]; + while (char* line = fgets(buffer, 128, file)) { + char* token = strtok(line, " "); + if (!token) + break; + + if (!strcmp(token, "MemAvailable:")) { + if ((token = strtok(nullptr, " "))) { + memoryAvailable = atoll(token); + if (memoryTotal != notSet) + break; + } + } else if (!strcmp(token, "MemTotal:")) { + if ((token = strtok(nullptr, " "))) + memoryTotal = atoll(token); + else + break; + } else if (!strcmp(token, "MemFree:")) { + if ((token = strtok(nullptr, " "))) + memoryFree = atoll(token); + else + break; + } else if (!strcmp(token, "Active(file):")) { + if ((token = strtok(nullptr, " "))) + activeFile = atoll(token); + else + break; + } else if (!strcmp(token, "Inactive(file):")) { + if ((token = strtok(nullptr, " "))) + inactiveFile = atoll(token); + else + break; + } else if (!strcmp(token, "SReclaimable:")) { + if ((token = strtok(nullptr, " "))) + slabReclaimable = atoll(token); + else + break; + } + + if (memoryTotal != notSet && memoryFree != notSet && activeFile != notSet && inactiveFile != notSet && slabReclaimable != notSet) + break; + } + fclose(file); + + if (!memoryTotal || memoryTotal == notSet) + return -1; + + if (memoryAvailable == notSet) { + memoryAvailable = calculateMemoryAvailable(memoryFree, activeFile, inactiveFile, slabReclaimable); + if (memoryAvailable == notSet) + return -1; + } + + if (memoryAvailable > memoryTotal) + return -1; + + return ((memoryTotal - memoryAvailable) * 100) / memoryTotal; +} + +static inline double pollIntervalForUsedMemoryPercentage(int usedPercentage) +{ + // Use a different poll interval depending on the currently memory used, + // to avoid polling too often when the system is under low memory usage. + if (usedPercentage < s_minUsedMemoryPercentageForPolling) + return s_maxPollingIntervalInSeconds; + + if (usedPercentage >= s_maxUsedMemoryPercentageForPolling) + return s_minPollingIntervalInSeconds; + + return s_minPollingIntervalInSeconds + (s_maxPollingIntervalInSeconds - s_minPollingIntervalInSeconds) * + ((usedPercentage - s_minUsedMemoryPercentageForPolling) / (s_maxUsedMemoryPercentageForPolling - s_minUsedMemoryPercentageForPolling)); +} + +static bool isSystemdMemoryPressureMonitorAvailable() +{ + int fd = open("/sys/fs/cgroup/memory/memory.pressure_level", O_CLOEXEC | O_RDONLY); + if (fd == -1) + return false; + close(fd); + + fd = open("/sys/fs/cgroup/memory/cgroup.event_control", O_CLOEXEC | O_WRONLY); + if (fd == -1) + return false; + close(fd); + + return true; +} + +bool MemoryPressureMonitor::isEnabled() +{ + static std::once_flag onceFlag; + static bool enabled; + std::call_once(onceFlag, [] { enabled = !isSystemdMemoryPressureMonitorAvailable(); }); + return enabled; +} + +MemoryPressureMonitor& MemoryPressureMonitor::singleton() +{ + ASSERT(isEnabled()); + static NeverDestroyed<MemoryPressureMonitor> memoryMonitor; + return memoryMonitor; +} + +MemoryPressureMonitor::MemoryPressureMonitor() + : m_eventFD(eventfd(0, EFD_CLOEXEC)) +{ + if (m_eventFD == -1) + return; + + ThreadIdentifier threadIdentifier = createThread("MemoryPressureMonitor", [this] { + double pollInterval = s_maxPollingIntervalInSeconds; + while (true) { + sleep(pollInterval); + + int usedPercentage = systemMemoryUsedAsPercentage(); + if (usedPercentage == -1) { + WTFLogAlways("Failed to get the memory usage"); + break; + } + + if (usedPercentage >= s_memoryPresurePercentageThreshold) { + uint64_t fdEvent = 1; + ssize_t bytesWritten = write(m_eventFD, &fdEvent, sizeof(uint64_t)); + if (bytesWritten != sizeof(uint64_t)) { + WTFLogAlways("Error writing to MemoryPressureMonitor eventFD: %s", strerror(errno)); + break; + } + } + pollInterval = pollIntervalForUsedMemoryPercentage(usedPercentage); + } + close(m_eventFD); + }); + detachThread(threadIdentifier); +} + +IPC::Attachment MemoryPressureMonitor::createHandle() const +{ + int duplicatedHandle = dupCloseOnExec(m_eventFD); + if (duplicatedHandle == -1) + return { }; + return IPC::Attachment(duplicatedHandle); +} + +} // namespace WebKit + +#endif // OS(LINUX) diff --git a/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.h b/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.h new file mode 100644 index 000000000..3874d9051 --- /dev/null +++ b/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if OS(LINUX) + +#include <wtf/NeverDestroyed.h> +#include <wtf/Noncopyable.h> + +namespace IPC { +class Attachment; +} + +namespace WebKit { + +class MemoryPressureMonitor { + WTF_MAKE_NONCOPYABLE(MemoryPressureMonitor); + friend class NeverDestroyed<MemoryPressureMonitor>; +public: + static MemoryPressureMonitor& singleton(); + static bool isEnabled(); + + ~MemoryPressureMonitor(); + + IPC::Attachment createHandle() const; + +private: + MemoryPressureMonitor(); + + int m_eventFD { -1 }; +}; + +} // namespace WebKit + +#endif // OS(LINUX) diff --git a/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp b/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp index 457e0370f..af443eca6 100644 --- a/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp +++ b/Source/WebKit2/UIProcess/soup/WebCookieManagerProxySoup.cpp @@ -26,14 +26,14 @@ #include "config.h" #include "WebCookieManagerProxy.h" -#include "WebContext.h" #include "WebCookieManagerMessages.h" +#include "WebProcessPool.h" namespace WebKit { void WebCookieManagerProxy::setCookiePersistentStorage(const String& storagePath, uint32_t storageType) { - context()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::SetCookiePersistentStorage(storagePath, storageType)); + processPool()->sendToNetworkingProcessRelaunchingIfNecessary(Messages::WebCookieManager::SetCookiePersistentStorage(storagePath, storageType)); m_cookiePersistentStoragePath = storagePath; m_cookiePersistentStorageType = static_cast<SoupCookiePersistentStorageType>(storageType); diff --git a/Source/WebKit2/UIProcess/soup/WebContextSoup.cpp b/Source/WebKit2/UIProcess/soup/WebProcessPoolSoup.cpp index 43ee6719a..1c1bb3697 100644 --- a/Source/WebKit2/UIProcess/soup/WebContextSoup.cpp +++ b/Source/WebKit2/UIProcess/soup/WebProcessPoolSoup.cpp @@ -24,27 +24,41 @@ */ #include "config.h" -#if ENABLE(NETWORK_PROCESS) -#include "WebContext.h" +#include "WebProcessPool.h" +#include "APICustomProtocolManagerClient.h" #include "NetworkProcessCreationParameters.h" +#include "NetworkProcessMessages.h" #include "WebCookieManagerProxy.h" -#include "WebSoupCustomProtocolRequestManager.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcessMessages.h" #include <WebCore/Language.h> namespace WebKit { -void WebContext::platformInitializeNetworkProcess(NetworkProcessCreationParameters& parameters) +void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationParameters& parameters) { supplement<WebCookieManagerProxy>()->getCookiePersistentStorage(parameters.cookiePersistentStoragePath, parameters.cookiePersistentStorageType); parameters.cookieAcceptPolicy = m_initialHTTPCookieAcceptPolicy; parameters.ignoreTLSErrors = m_ignoreTLSErrors; parameters.languages = WebCore::userPreferredLanguages(); -#if ENABLE(CUSTOM_PROTOCOLS) - parameters.urlSchemesRegisteredForCustomProtocols = supplement<WebSoupCustomProtocolRequestManager>()->registeredSchemesForCustomProtocols(); -#endif + parameters.shouldEnableNetworkCacheEfficacyLogging = false; + parameters.proxySettings = m_networkProxySettings; } +void WebProcessPool::setIgnoreTLSErrors(bool ignoreTLSErrors) +{ + m_ignoreTLSErrors = ignoreTLSErrors; + if (networkProcess()) + networkProcess()->send(Messages::NetworkProcess::SetIgnoreTLSErrors(m_ignoreTLSErrors), 0); } -#endif +void WebProcessPool::setNetworkProxySettings(const WebCore::SoupNetworkProxySettings& settings) +{ + m_networkProxySettings = settings; + sendToAllProcesses(Messages::WebProcess::SetNetworkProxySettings(m_networkProxySettings)); + if (m_networkProcess) + m_networkProcess->send(Messages::NetworkProcess::SetNetworkProxySettings(m_networkProxySettings), 0); +} + +} |
