# 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 NotRefCounted {
    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()

    PrepareToSuspend(bool isSuspensionImminent) -> () Async
    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, struct WebKit::ServiceWorkerInitializationData initializationData) -> () Async
#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_FAMILY) && !PLATFORM(MACCATALYST)
    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

#if ENABLE(RESOURCE_LOAD_STATISTICS)
    SeedResourceLoadStatisticsForTesting(WebCore::RegistrableDomain firstPartyDomain, WebCore::RegistrableDomain thirdPartyDomain, bool shouldScheduleNotification) -> () Async
    SetShouldBlockThirdPartyCookiesForTesting(enum:uint8_t WebCore::ThirdPartyCookieBlockingMode blockingMode) -> () Async
#endif

#if PLATFORM(IOS)
    GrantAccessToAssetServices(WebKit::SandboxExtension::Handle mobileAssetHandle, WebKit::SandboxExtension::Handle mobileAssetV2Handle)
    RevokeAccessToAssetServices()
#endif
}
