/*
 * Copyright (C) 2006, 2007, 2008, 2009, 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. ``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 "Settings.h"

#include "AudioSession.h"
#include "BackForwardController.h"
#include "CachedResourceLoader.h"
#include "CookieStorage.h"
#include "DOMTimer.h"
#include "Database.h"
#include "Document.h"
#include "FontCascade.h"
#include "FontGenericFamilies.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HTMLMediaElement.h"
#include "HistoryItem.h"
#include "InspectorInstrumentation.h"
#include "MainFrame.h"
#include "Page.h"
#include "PageCache.h"
#include "RuntimeApplicationChecks.h"
#include "StorageMap.h"
#include <limits>
#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>

#if ENABLE(MEDIA_STREAM)
#include "MockRealtimeMediaSourceCenter.h"
#endif

namespace WebCore {

static void setImageLoadingSettings(Page* page)
{
    if (!page)
        return;

    for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
        if (!frame->document())
            continue;
        frame->document()->cachedResourceLoader().setImagesEnabled(page->settings().areImagesEnabled());
        frame->document()->cachedResourceLoader().setAutoLoadImages(page->settings().loadsImagesAutomatically());
    }
}

static void invalidateAfterGenericFamilyChange(Page* page)
{
    invalidateFontCascadeCache();
    if (page)
        page->setNeedsRecalcStyleInAllFrames();
}

#if USE(AVFOUNDATION)
bool Settings::gAVFoundationEnabled = true;
bool Settings::gAVFoundationNSURLSessionEnabled = true;
#endif

#if PLATFORM(COCOA)
bool Settings::gQTKitEnabled = false;
#endif

bool Settings::gMockScrollbarsEnabled = false;
bool Settings::gUsesOverlayScrollbars = false;
bool Settings::gMockScrollAnimatorEnabled = false;

#if ENABLE(MEDIA_STREAM)
bool Settings::gMockCaptureDevicesEnabled = false;
#endif

#if PLATFORM(WIN)
bool Settings::gShouldUseHighResolutionTimers = true;
#endif
    
bool Settings::gShouldRespectPriorityInCSSAttributeSetters = false;
bool Settings::gLowPowerVideoAudioBufferSizeEnabled = false;
bool Settings::gResourceLoadStatisticsEnabledEnabled = false;
bool Settings::gAllowsAnySSLCertificate = false;

#if PLATFORM(IOS)
bool Settings::gNetworkDataUsageTrackingEnabled = false;
bool Settings::gAVKitEnabled = false;
bool Settings::gShouldOptOutOfNetworkStateObservation = false;
bool Settings::gManageAudioSession = false;
#endif

// NOTEs
//  1) EditingMacBehavior comprises Tiger, Leopard, SnowLeopard and iOS builds, as well as QtWebKit when built on Mac;
//  2) EditingWindowsBehavior comprises Win32 build;
//  3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS (and then abusing the terminology);
// 99) MacEditingBehavior is used as a fallback.
static EditingBehaviorType editingBehaviorTypeForPlatform()
{
    return
#if PLATFORM(IOS)
    EditingIOSBehavior
#elif OS(DARWIN)
    EditingMacBehavior
#elif OS(WINDOWS)
    EditingWindowsBehavior
#elif OS(UNIX)
    EditingUnixBehavior
#else
    // Fallback
    EditingMacBehavior
#endif
    ;
}

#if PLATFORM(COCOA)
static const bool defaultYouTubeFlashPluginReplacementEnabled = true;
#else
static const bool defaultYouTubeFlashPluginReplacementEnabled = false;
#endif

#if PLATFORM(IOS)
static const bool defaultFixedPositionCreatesStackingContext = true;
static const bool defaultFixedBackgroundsPaintRelativeToDocument = true;
static const bool defaultAcceleratedCompositingForFixedPositionEnabled = true;
static const bool defaultAllowsInlineMediaPlayback = false;
static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = true;
static const bool defaultVideoPlaybackRequiresUserGesture = true;
static const bool defaultAudioPlaybackRequiresUserGesture = true;
static const bool defaultMediaDataLoadsAutomatically = false;
static const bool defaultShouldRespectImageOrientation = true;
static const bool defaultImageSubsamplingEnabled = true;
static const bool defaultScrollingTreeIncludesFrames = true;
static const bool defaultMediaControlsScaleWithPageZoom = true;
static const bool defaultQuickTimePluginReplacementEnabled = true;
#else
static const bool defaultFixedPositionCreatesStackingContext = false;
static const bool defaultFixedBackgroundsPaintRelativeToDocument = false;
static const bool defaultAcceleratedCompositingForFixedPositionEnabled = false;
static const bool defaultAllowsInlineMediaPlayback = true;
static const bool defaultInlineMediaPlaybackRequiresPlaysInlineAttribute = false;
static const bool defaultVideoPlaybackRequiresUserGesture = false;
static const bool defaultAudioPlaybackRequiresUserGesture = false;
static const bool defaultMediaDataLoadsAutomatically = true;
static const bool defaultShouldRespectImageOrientation = false;
static const bool defaultImageSubsamplingEnabled = false;
static const bool defaultScrollingTreeIncludesFrames = false;
static const bool defaultMediaControlsScaleWithPageZoom = true;
static const bool defaultQuickTimePluginReplacementEnabled = false;
#endif

static const bool defaultRequiresUserGestureToLoadVideo = true;

static const bool defaultAllowsPictureInPictureMediaPlayback = true;

static const double defaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
#if USE(UNIFIED_TEXT_CHECKING)
static const bool defaultUnifiedTextCheckerEnabled = true;
#else
static const bool defaultUnifiedTextCheckerEnabled = false;
#endif
static const bool defaultSmartInsertDeleteEnabled = true;
static const bool defaultSelectTrailingWhitespaceEnabled = false;

// This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
// FIXME: For faster machines this value can really be lowered to 200. 250 is adequate, but a little high
// for dual G5s. :)
static const auto layoutScheduleThreshold = 250ms;

Settings::Settings(Page* page)
    : m_page(nullptr)
    , m_mediaTypeOverride("screen")
    , m_fontGenericFamilies(std::make_unique<FontGenericFamilies>())
    , m_storageBlockingPolicy(SecurityOrigin::AllowAllStorage)
    , m_layoutInterval(layoutScheduleThreshold)
    , m_minimumDOMTimerInterval(DOMTimer::defaultMinimumInterval())
    SETTINGS_INITIALIZER_LIST
    , m_isJavaEnabled(false)
    , m_isJavaEnabledForLocalFiles(true)
    , m_loadsImagesAutomatically(false)
    , m_areImagesEnabled(true)
    , m_preferMIMETypeForImages(false)
    , m_arePluginsEnabled(false)
    , m_isScriptEnabled(false)
    , m_needsAdobeFrameReloadingQuirk(false)
    , m_usesPageCache(false)
    , m_fontRenderingMode(0)
    , m_showTiledScrollingIndicator(false)
    , m_backgroundShouldExtendBeyondPage(false)
    , m_dnsPrefetchingEnabled(false)
#if ENABLE(TOUCH_EVENTS)
    , m_touchEventEmulationEnabled(false)
#endif
    , m_scrollingPerformanceLoggingEnabled(false)
    , m_timeWithoutMouseMovementBeforeHidingControls(3)
    , m_setImageLoadingSettingsTimer(*this, &Settings::imageLoadingSettingsTimerFired)
    , m_hiddenPageDOMTimerThrottlingEnabled(false)
    , m_hiddenPageCSSAnimationSuspensionEnabled(false)
    , m_fontFallbackPrefersPictographs(false)
    , m_webFontsAlwaysFallBack(false)
    , m_forcePendingWebGLPolicy(false)
{
    // A Frame may not have been created yet, so we initialize the AtomicString
    // hash before trying to use it.
    AtomicString::init();
    initializeDefaultFontFamilies();
    m_page = page; // Page is not yet fully initialized when constructing Settings, so keeping m_page null over initializeDefaultFontFamilies() call.
}

Settings::~Settings()
{
}

Ref<Settings> Settings::create(Page* page)
{
    return adoptRef(*new Settings(page));
}

SETTINGS_SETTER_BODIES

#if !PLATFORM(COCOA)
void Settings::initializeDefaultFontFamilies()
{
    // Other platforms can set up fonts from a client, but on Mac, we want it in WebCore to share code between WebKit1 and WebKit2.
}
#endif

const AtomicString& Settings::standardFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->standardFontFamily(script);
}

void Settings::setStandardFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setStandardFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::fixedFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->fixedFontFamily(script);
}

void Settings::setFixedFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setFixedFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::serifFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->serifFontFamily(script);
}

void Settings::setSerifFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setSerifFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::sansSerifFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->sansSerifFontFamily(script);
}

void Settings::setSansSerifFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setSansSerifFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::cursiveFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->cursiveFontFamily(script);
}

void Settings::setCursiveFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setCursiveFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::fantasyFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->fantasyFontFamily(script);
}

void Settings::setFantasyFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setFantasyFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

const AtomicString& Settings::pictographFontFamily(UScriptCode script) const
{
    return m_fontGenericFamilies->pictographFontFamily(script);
}

void Settings::setPictographFontFamily(const AtomicString& family, UScriptCode script)
{
    bool changes = m_fontGenericFamilies->setPictographFontFamily(family, script);
    if (changes)
        invalidateAfterGenericFamilyChange(m_page);
}

float Settings::defaultMinimumZoomFontSize()
{
    return 15;
}

#if !PLATFORM(IOS)
bool Settings::defaultTextAutosizingEnabled()
{
    return false;
}
#endif

void Settings::setMediaTypeOverride(const String& mediaTypeOverride)
{
    if (m_mediaTypeOverride == mediaTypeOverride)
        return;

    m_mediaTypeOverride = mediaTypeOverride;

    if (!m_page)
        return;

    FrameView* view = m_page->mainFrame().view();
    ASSERT(view);

    view->setMediaType(mediaTypeOverride);
    m_page->setNeedsRecalcStyleInAllFrames();
}

void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically)
{
    m_loadsImagesAutomatically = loadsImagesAutomatically;
    
    // Changing this setting to true might immediately start new loads for images that had previously had loading disabled.
    // If this happens while a WebView is being dealloc'ed, and we don't know the WebView is being dealloc'ed, these new loads
    // can cause crashes downstream when the WebView memory has actually been free'd.
    // One example where this can happen is in Mac apps that subclass WebView then do work in their overridden dealloc methods.
    // Starting these loads synchronously is not important.  By putting it on a 0-delay, properly closing the Page cancels them
    // before they have a chance to really start.
    // See http://webkit.org/b/60572 for more discussion.
    m_setImageLoadingSettingsTimer.startOneShot(0);
}

void Settings::imageLoadingSettingsTimerFired()
{
    setImageLoadingSettings(m_page);
}

void Settings::setScriptEnabled(bool isScriptEnabled)
{
    if (m_isScriptEnabled == isScriptEnabled)
        return;

    m_isScriptEnabled = isScriptEnabled;

    if (!m_page)
        return;

#if PLATFORM(IOS)
    m_page->setNeedsRecalcStyleInAllFrames();
#endif
    InspectorInstrumentation::scriptsEnabled(*m_page, m_isScriptEnabled);
}

void Settings::setJavaEnabled(bool isJavaEnabled)
{
    m_isJavaEnabled = isJavaEnabled;
}

void Settings::setJavaEnabledForLocalFiles(bool isJavaEnabledForLocalFiles)
{
    m_isJavaEnabledForLocalFiles = isJavaEnabledForLocalFiles;
}

void Settings::setImagesEnabled(bool areImagesEnabled)
{
    m_areImagesEnabled = areImagesEnabled;

    // See comment in setLoadsImagesAutomatically.
    m_setImageLoadingSettingsTimer.startOneShot(0);
}

void Settings::setPreferMIMETypeForImages(bool preferMIMETypeForImages)
{
    m_preferMIMETypeForImages = preferMIMETypeForImages;
}

void Settings::setForcePendingWebGLPolicy(bool forced)
{
    m_forcePendingWebGLPolicy = forced;
}

void Settings::setPluginsEnabled(bool arePluginsEnabled)
{
    if (m_arePluginsEnabled == arePluginsEnabled)
        return;

    m_arePluginsEnabled = arePluginsEnabled;
    Page::refreshPlugins(false);
}

void Settings::setUserStyleSheetLocation(const URL& userStyleSheetLocation)
{
    if (m_userStyleSheetLocation == userStyleSheetLocation)
        return;

    m_userStyleSheetLocation = userStyleSheetLocation;

    if (m_page)
        m_page->userStyleSheetLocationChanged();
}

// FIXME: This quirk is needed because of Radar 4674537 and 5211271. We need to phase it out once Adobe
// can fix the bug from their end.
void Settings::setNeedsAdobeFrameReloadingQuirk(bool shouldNotReloadIFramesForUnchangedSRC)
{
    m_needsAdobeFrameReloadingQuirk = shouldNotReloadIFramesForUnchangedSRC;
}

void Settings::setMinimumDOMTimerInterval(std::chrono::milliseconds interval)
{
    auto oldTimerInterval = m_minimumDOMTimerInterval;
    m_minimumDOMTimerInterval = interval;

    if (!m_page)
        return;

    for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
        if (frame->document())
            frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
    }
}

void Settings::setLayoutInterval(std::chrono::milliseconds layoutInterval)
{
    // FIXME: It seems weird that this function may disregard the specified layout interval.
    // We should either expose layoutScheduleThreshold or better communicate this invariant.
    m_layoutInterval = std::max(layoutInterval, layoutScheduleThreshold);
}

void Settings::setUsesPageCache(bool usesPageCache)
{
    if (m_usesPageCache == usesPageCache)
        return;
        
    m_usesPageCache = usesPageCache;

    if (!m_page)
        return;

    if (!m_usesPageCache)
        PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
}

void Settings::setFontRenderingMode(FontRenderingMode mode)
{
    if (fontRenderingMode() == mode)
        return;
    m_fontRenderingMode = static_cast<int>(mode);
    if (m_page)
        m_page->setNeedsRecalcStyleInAllFrames();
}

FontRenderingMode Settings::fontRenderingMode() const
{
    return static_cast<FontRenderingMode>(m_fontRenderingMode);
}

void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled)
{
    if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled)
        return;

    m_dnsPrefetchingEnabled = dnsPrefetchingEnabled;
    if (m_page)
        m_page->dnsPrefetchingStateChanged();
}

void Settings::setShowTiledScrollingIndicator(bool enabled)
{
    if (m_showTiledScrollingIndicator == enabled)
        return;
        
    m_showTiledScrollingIndicator = enabled;
}

#if ENABLE(RESOURCE_USAGE)
void Settings::setResourceUsageOverlayVisible(bool visible)
{
    if (m_resourceUsageOverlayVisible == visible)
        return;

    m_resourceUsageOverlayVisible = visible;
    if (m_page)
        m_page->setResourceUsageOverlayVisible(visible);
}
#endif

#if PLATFORM(WIN)
void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
{
    gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers;
}
#endif

void Settings::setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy enabled)
{
    if (m_storageBlockingPolicy == enabled)
        return;

    m_storageBlockingPolicy = enabled;
    if (m_page)
        m_page->storageBlockingStateChanged();
}

void Settings::setBackgroundShouldExtendBeyondPage(bool shouldExtend)
{
    if (m_backgroundShouldExtendBeyondPage == shouldExtend)
        return;

    m_backgroundShouldExtendBeyondPage = shouldExtend;

    if (m_page)
        m_page->mainFrame().view()->updateExtendBackgroundIfNecessary();
}

#if USE(AVFOUNDATION)
void Settings::setAVFoundationEnabled(bool enabled)
{
    if (gAVFoundationEnabled == enabled)
        return;

    gAVFoundationEnabled = enabled;
    HTMLMediaElement::resetMediaEngines();
}

void Settings::setAVFoundationNSURLSessionEnabled(bool enabled)
{
    if (gAVFoundationNSURLSessionEnabled == enabled)
        return;

    gAVFoundationNSURLSessionEnabled = enabled;
}
#endif

#if PLATFORM(COCOA)
void Settings::setQTKitEnabled(bool enabled)
{
    if (gQTKitEnabled == enabled)
        return;

    gQTKitEnabled = enabled;
    HTMLMediaElement::resetMediaEngines();
}
#endif

#if ENABLE(MEDIA_STREAM)
bool Settings::mockCaptureDevicesEnabled()
{
    return gMockCaptureDevicesEnabled;
}

void Settings::setMockCaptureDevicesEnabled(bool enabled)
{
    gMockCaptureDevicesEnabled = enabled;
    MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(enabled);
}
#endif

void Settings::setScrollingPerformanceLoggingEnabled(bool enabled)
{
    m_scrollingPerformanceLoggingEnabled = enabled;

    if (m_page && m_page->mainFrame().view())
        m_page->mainFrame().view()->setScrollingPerformanceLoggingEnabled(enabled);
}

// It's very important that this setting doesn't change in the middle of a document's lifetime.
// The Mac port uses this flag when registering and deregistering platform-dependent scrollbar
// objects. Therefore, if this changes at an unexpected time, deregistration may not happen
// correctly, which may cause the platform to follow dangling pointers.
void Settings::setMockScrollbarsEnabled(bool flag)
{
    gMockScrollbarsEnabled = flag;
    // FIXME: This should update scroll bars in existing pages.
}

bool Settings::mockScrollbarsEnabled()
{
    return gMockScrollbarsEnabled;
}

void Settings::setUsesOverlayScrollbars(bool flag)
{
    gUsesOverlayScrollbars = flag;
    // FIXME: This should update scroll bars in existing pages.
}

bool Settings::usesOverlayScrollbars()
{
    return gUsesOverlayScrollbars;
}

void Settings::setUsesMockScrollAnimator(bool flag)
{
    gMockScrollAnimatorEnabled = flag;
}

bool Settings::usesMockScrollAnimator()
{
    return gMockScrollAnimatorEnabled;
}

void Settings::setShouldRespectPriorityInCSSAttributeSetters(bool flag)
{
    gShouldRespectPriorityInCSSAttributeSetters = flag;
}

bool Settings::shouldRespectPriorityInCSSAttributeSetters()
{
    return gShouldRespectPriorityInCSSAttributeSetters;
}

void Settings::setHiddenPageDOMTimerThrottlingEnabled(bool flag)
{
    if (m_hiddenPageDOMTimerThrottlingEnabled == flag)
        return;
    m_hiddenPageDOMTimerThrottlingEnabled = flag;
    if (m_page)
        m_page->hiddenPageDOMTimerThrottlingStateChanged();
}

void Settings::setHiddenPageDOMTimerThrottlingAutoIncreases(bool flag)
{
    if (m_hiddenPageDOMTimerThrottlingAutoIncreases == flag)
        return;
    m_hiddenPageDOMTimerThrottlingAutoIncreases = flag;
    if (m_page)
        m_page->hiddenPageDOMTimerThrottlingStateChanged();
}

void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
{
    if (m_hiddenPageCSSAnimationSuspensionEnabled == flag)
        return;
    m_hiddenPageCSSAnimationSuspensionEnabled = flag;
    if (m_page)
        m_page->hiddenPageCSSAnimationSuspensionStateChanged();
}

void Settings::setFontFallbackPrefersPictographs(bool preferPictographs)
{
    if (m_fontFallbackPrefersPictographs == preferPictographs)
        return;

    m_fontFallbackPrefersPictographs = preferPictographs;
    if (m_page)
        m_page->setNeedsRecalcStyleInAllFrames();
}

void Settings::setWebFontsAlwaysFallBack(bool enable)
{
    if (m_webFontsAlwaysFallBack == enable)
        return;

    m_webFontsAlwaysFallBack = enable;
}

void Settings::setLowPowerVideoAudioBufferSizeEnabled(bool flag)
{
    gLowPowerVideoAudioBufferSizeEnabled = flag;
}

void Settings::setResourceLoadStatisticsEnabled(bool flag)
{
    gResourceLoadStatisticsEnabledEnabled = flag;
}

#if PLATFORM(IOS)
void Settings::setAudioSessionCategoryOverride(unsigned sessionCategory)
{
    AudioSession::sharedSession().setCategoryOverride(static_cast<AudioSession::CategoryType>(sessionCategory));
}

unsigned Settings::audioSessionCategoryOverride()
{
    return AudioSession::sharedSession().categoryOverride();
}

void Settings::setNetworkDataUsageTrackingEnabled(bool trackingEnabled)
{
    gNetworkDataUsageTrackingEnabled = trackingEnabled;
}

bool Settings::networkDataUsageTrackingEnabled()
{
    return gNetworkDataUsageTrackingEnabled;
}

static String& sharedNetworkInterfaceNameGlobal()
{
    static NeverDestroyed<String> networkInterfaceName;
    return networkInterfaceName;
}

void Settings::setNetworkInterfaceName(const String& networkInterfaceName)
{
    sharedNetworkInterfaceNameGlobal() = networkInterfaceName;
}

const String& Settings::networkInterfaceName()
{
    return sharedNetworkInterfaceNameGlobal();
}
#endif

bool Settings::globalConstRedeclarationShouldThrow()
{
#if PLATFORM(MAC)
    return !MacApplication::isIBooks();
#elif PLATFORM(IOS)
    return !IOSApplication::isIBooks();
#else
    return true;
#endif
}

void Settings::setAllowsAnySSLCertificate(bool allowAnySSLCertificate)
{
    gAllowsAnySSLCertificate = allowAnySSLCertificate;
}

bool Settings::allowsAnySSLCertificate()
{
    return gAllowsAnySSLCertificate;
}

} // namespace WebCore
