# Copyright (C) 2010-2018 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 -> WebProcess LegacyReceiver {
    InitializeWebProcess(struct WebKit::WebProcessCreationParameters processCreationParameters)
    SetWebsiteDataStoreParameters(struct WebKit::WebProcessDataStoreParameters parameters)

    # Create a new page.
    CreateWebPage(WebCore::PageIdentifier newPageID, struct WebKit::WebPageCreationParameters pageCreationParameters)

    PrewarmGlobally();
    PrewarmWithDomainInformation(struct WebCore::PrewarmInformation prewarmInformation)

    # Global preferences.
    SetCacheModel(enum:uint8_t WebKit::CacheModel cacheModel)

    RegisterURLSchemeAsEmptyDocument(String scheme)
    RegisterURLSchemeAsSecure(String scheme)
    RegisterURLSchemeAsBypassingContentSecurityPolicy(String scheme)
    SetDomainRelaxationForbiddenForURLScheme(String scheme)
    RegisterURLSchemeAsLocal(String scheme)
    RegisterURLSchemeAsNoAccess(String scheme)
    RegisterURLSchemeAsDisplayIsolated(String scheme)
    RegisterURLSchemeAsCORSEnabled(String scheme)
    RegisterURLSchemeAsCachePartitioned(String scheme)
    RegisterURLSchemeAsCanDisplayOnlyIfCanRequest(String scheme)

    SetDefaultRequestTimeoutInterval(double timeoutInterval)
    SetAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
    SetShouldUseFontSmoothing(bool useFontSmoothing)
    SetResourceLoadStatisticsEnabled(bool resourceLoadStatisticsEnabled);
    ClearResourceLoadStatistics();
    UserPreferredLanguagesChanged(Vector<String> languages)
    FullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)

    # Plug-ins.
    DidAddPlugInAutoStartOriginHash(uint32_t hash, WallTime expirationTime)
    ResetPlugInAutoStartOriginHashes(HashMap<uint32_t,WallTime> hashes)
    SetPluginLoadClientPolicy(uint8_t policy, String host, String bundleIdentifier, String versionString)
    ResetPluginLoadClientPolicies(HashMap<String, HashMap<String, HashMap<String, uint8_t>>> pluginLoadClientPolicies)
    ClearPluginClientPolicies()
    RefreshPlugins()

    void StartMemorySampler(WebKit::SandboxExtension::Handle sampleLogFileHandle, String sampleLogFilePath, double interval);
    void StopMemorySampler();

    SetTextCheckerState(struct WebKit::TextCheckerState textCheckerState)

    SetEnhancedAccessibility(bool flag)

    GetWebCoreStatistics(uint64_t callbackID)
    GarbageCollectJavaScriptObjects()
    SetJavaScriptGarbageCollectorTimerEnabled(bool enable)

    SetInjectedBundleParameter(String parameter, IPC::DataReference value);
    SetInjectedBundleParameters(IPC::DataReference parameters);
    HandleInjectedBundleMessage(String messageName, WebKit::UserData messageBody);

    FetchWebsiteData(OptionSet<WebKit::WebsiteDataType> websiteDataTypes) -> (struct WebKit::WebsiteData websiteData) Async
    DeleteWebsiteData(OptionSet<WebKit::WebsiteDataType> websiteDataTypes, WallTime modifiedSince) -> () Async
    DeleteWebsiteDataForOrigins(OptionSet<WebKit::WebsiteDataType> websiteDataTypes, Vector<WebCore::SecurityOriginData> origins) -> () Async

    SetHiddenPageDOMTimerThrottlingIncreaseLimit(int milliseconds)
#if PLATFORM(COCOA)
    SetQOS(int latencyQOS, int throughputQOS)
#endif

    SetMemoryCacheDisabled(bool disabled);

#if ENABLE(SERVICE_CONTROLS)
    SetEnabledServices(bool hasImageServices, bool hasSelectionServices, bool hasRichContentServices)
#endif

    EnsureAutomationSessionProxy(String sessionIdentifier)
    DestroyAutomationSessionProxy()

    ProcessWillSuspendImminently()
    PrepareToSuspend()
    CancelPrepareToSuspend()
    ProcessDidResume()

    MainThreadPing()
    BackgroundResponsivenessPing()

#if ENABLE(GAMEPAD)
    SetInitialGamepads(Vector<WebKit::GamepadData> gamepadDatas)
    GamepadConnected(WebKit::GamepadData gamepadData)
    GamepadDisconnected(unsigned index)
#endif

#if ENABLE(SERVICE_WORKER)
    EstablishWorkerContextConnectionToNetworkProcess(uint64_t pageGroupID, WebKit::WebPageProxyIdentifier webPageProxyID, WebCore::PageIdentifier pageID, struct WebKit::WebPreferencesStore store, WebCore::RegistrableDomain domain)
    RegisterServiceWorkerClients()
#endif

    SetHasSuspendedPageProxy(bool hasSuspendedPageProxy);
    SetIsInProcessCache(bool isInProcessCache)
    MarkIsNoLongerPrewarmed()
    UpdateActivePages()
    GetActivePagesOriginsForTesting() -> (Vector<String> activeOrigins) Async

#if PLATFORM(MAC)
    SetScreenProperties(struct WebCore::ScreenProperties screenProperties)
#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    ScrollerStylePreferenceChanged(bool useOvelayScrollbars)
    DisplayConfigurationChanged(CGDirectDisplayID displayID, CGDisplayChangeSummaryFlags flags)
    DisplayWasRefreshed(uint32_t displayID)
#endif
#endif

#if PLATFORM(IOS)
    BacklightLevelDidChange(float backlightLevel)
#endif

    IsJITEnabled() -> (bool enabled) Async

#if PLATFORM(COCOA)
    SetMediaMIMETypes(Vector<String> types)
#endif

#if ENABLE(MEDIA_STREAM)
    AddMockMediaDevice(struct WebCore::MockMediaDevice device);
    ClearMockMediaDevices();
    RemoveMockMediaDevice(String persistentId);
    ResetMockMediaDevices();

#if ENABLE(SANDBOX_EXTENSIONS)
    GrantUserMediaDeviceSandboxExtensions(WebKit::MediaDeviceSandboxExtensions sandboxExtensions)
    RevokeUserMediaDeviceSandboxExtensions(Vector<String> sandboxExtensionIDs)
#endif
#endif

    ClearCurrentModifierStateForTesting()

    SetBackForwardCacheCapacity(unsigned capacity);
    ClearCachedPage(struct WebCore::BackForwardItemIdentifier backForwardItemID) -> () Async

#if PLATFORM(IOS_FAMILY)
    UnblockAccessibilityServer(WebKit::SandboxExtension::Handle handle)
#endif

#if PLATFORM(GTK) || PLATFORM(WPE)
    SendMessageToWebExtension(struct WebKit::UserMessage userMessage)
#endif
}
