# 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)

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

    # Global preferences.
    SetCacheModel(uint32_t 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)

    ClearCachedCredentials()

    AddWebsiteDataStore(struct WebKit::WebsiteDataStoreParameters websiteDataStoreParameters);
    DestroySession(PAL::SessionID sessionID)

    # Plug-ins.
    DidAddPlugInAutoStartOriginHash(uint32_t hash, WallTime expirationTime, PAL::SessionID sessionID)
    ResetPlugInAutoStartOriginDefaultHashes(HashMap<uint32_t,WallTime> hashes)
    ResetPlugInAutoStartOriginHashes(HashMap<PAL::SessionID, 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);

    ReleasePageCache()

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

    SetHiddenPageDOMTimerThrottlingIncreaseLimit(int milliseconds)
    SetProcessSuppressionEnabled(bool flag)
#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() -> (bool handled)
    PrepareToSuspend()
    CancelPrepareToSuspend()
    ProcessDidResume()

    MainThreadPing()
    BackgroundResponsivenessPing()

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

    SyncIPCMessageWhileWaitingForSyncReplyForTesting() -> ()

#if USE(SOUP)
    SetNetworkProxySettings(struct WebCore::SoupNetworkProxySettings settings)
#endif

#if ENABLE(SERVICE_WORKER)
    EstablishWorkerContextConnectionToStorageProcess(uint64_t pageGroupID, uint64_t pageID, struct WebKit::WebPreferencesStore store, PAL::SessionID initialSessionID)
    RegisterServiceWorkerClients()
#endif

    DidTakeAllMessagesForPort(Vector<WebCore::MessageWithMessagePorts> messages, uint64_t messageCallbackIdentifier, uint64_t messageBatchIdentifier)
    DidCheckRemotePortForActivity(uint64_t callbackIdentifier, bool hasActivity)
    CheckProcessLocalPortForActivity(struct WebCore::MessagePortIdentifier port, uint64_t callbackIdentifier)
    MessagesAvailableForPort(struct WebCore::MessagePortIdentifier port)

    UpdateActivePages()

#if PLATFORM(MAC)
    SetScreenProperties(uint32_t primaryScreenID, HashMap<uint32_t, WebCore::ScreenProperties> screenProperties)
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
    ScrollerStylePreferenceChanged(bool useOvelayScrollbars)
#endif
#endif
}
