1/*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "Settings.h"
28
29#include "AudioSession.h"
30#include "BackForwardController.h"
31#include "CachedResourceLoader.h"
32#include "CookieStorage.h"
33#include "DOMTimer.h"
34#include "Database.h"
35#include "Document.h"
36#include "Font.h"
37#include "FontGenericFamilies.h"
38#include "FrameTree.h"
39#include "FrameView.h"
40#include "HTMLMediaElement.h"
41#include "HistoryItem.h"
42#include "InspectorInstrumentation.h"
43#include "MainFrame.h"
44#include "Page.h"
45#include "PageCache.h"
46#include "StorageMap.h"
47#include "TextAutosizer.h"
48#include <limits>
49#include <wtf/NeverDestroyed.h>
50#include <wtf/StdLibExtras.h>
51
52namespace WebCore {
53
54static void setImageLoadingSettings(Page* page)
55{
56    for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
57        frame->document()->cachedResourceLoader()->setImagesEnabled(page->settings().areImagesEnabled());
58        frame->document()->cachedResourceLoader()->setAutoLoadImages(page->settings().loadsImagesAutomatically());
59    }
60}
61
62static void invalidateAfterGenericFamilyChange(Page* page)
63{
64    invalidateFontGlyphsCache();
65    if (page)
66        page->setNeedsRecalcStyleInAllFrames();
67}
68
69double Settings::gDefaultMinDOMTimerInterval = 0.010; // 10 milliseconds
70double Settings::gDefaultDOMTimerAlignmentInterval = 0;
71double Settings::gHiddenPageDOMTimerAlignmentInterval = 1.0;
72
73#if USE(SAFARI_THEME)
74bool Settings::gShouldPaintNativeControls = true;
75#endif
76
77#if USE(AVFOUNDATION)
78bool Settings::gAVFoundationEnabled = false;
79#endif
80
81#if PLATFORM(COCOA)
82bool Settings::gQTKitEnabled = true;
83#endif
84
85bool Settings::gMockScrollbarsEnabled = false;
86bool Settings::gUsesOverlayScrollbars = false;
87
88#if PLATFORM(WIN)
89bool Settings::gShouldUseHighResolutionTimers = true;
90#endif
91
92bool Settings::gShouldRespectPriorityInCSSAttributeSetters = false;
93bool Settings::gLowPowerVideoAudioBufferSizeEnabled = false;
94
95#if PLATFORM(IOS)
96bool Settings::gNetworkDataUsageTrackingEnabled = false;
97bool Settings::gAVKitEnabled = false;
98bool Settings::gShouldOptOutOfNetworkStateObservation = false;
99bool Settings::gManageAudioSession = false;
100#endif
101
102// NOTEs
103//  1) EditingMacBehavior comprises Tiger, Leopard, SnowLeopard and iOS builds, as well as QtWebKit when built on Mac;
104//  2) EditingWindowsBehavior comprises Win32 and WinCE builds, as well as QtWebKit and Chromium when built on Windows;
105//  3) EditingUnixBehavior comprises all unix-based systems, but Darwin/MacOS (and then abusing the terminology);
106// 99) MacEditingBehavior is used as a fallback.
107static EditingBehaviorType editingBehaviorTypeForPlatform()
108{
109    return
110#if OS(DARWIN)
111    EditingMacBehavior
112#elif OS(WINDOWS)
113    EditingWindowsBehavior
114#elif OS(UNIX)
115    EditingUnixBehavior
116#else
117    // Fallback
118    EditingMacBehavior
119#endif
120    ;
121}
122
123#if PLATFORM(IOS)
124static const bool defaultFixedPositionCreatesStackingContext = true;
125static const bool defaultFixedBackgroundsPaintRelativeToDocument = true;
126static const bool defaultAcceleratedCompositingForFixedPositionEnabled = true;
127static const bool defaultMediaPlaybackAllowsInline = false;
128static const bool defaultMediaPlaybackRequiresUserGesture = true;
129static const bool defaultShouldRespectImageOrientation = true;
130static const bool defaultScrollingTreeIncludesFrames = true;
131#else
132static const bool defaultFixedPositionCreatesStackingContext = false;
133static const bool defaultFixedBackgroundsPaintRelativeToDocument = false;
134static const bool defaultAcceleratedCompositingForFixedPositionEnabled = false;
135static const bool defaultMediaPlaybackAllowsInline = true;
136static const bool defaultMediaPlaybackRequiresUserGesture = false;
137static const bool defaultShouldRespectImageOrientation = false;
138static const bool defaultScrollingTreeIncludesFrames = false;
139#endif
140
141static const double defaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
142#if USE(UNIFIED_TEXT_CHECKING)
143static const bool defaultUnifiedTextCheckerEnabled = true;
144#else
145static const bool defaultUnifiedTextCheckerEnabled = false;
146#endif
147static const bool defaultSmartInsertDeleteEnabled = true;
148static const bool defaultSelectTrailingWhitespaceEnabled = false;
149
150// This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
151// FIXME: For faster machines this value can really be lowered to 200. 250 is adequate, but a little high
152// for dual G5s. :)
153static const auto layoutScheduleThreshold = std::chrono::milliseconds(250);
154
155Settings::Settings(Page* page)
156    : m_page(0)
157    , m_mediaTypeOverride("screen")
158    , m_fontGenericFamilies(std::make_unique<FontGenericFamilies>())
159    , m_storageBlockingPolicy(SecurityOrigin::AllowAllStorage)
160    , m_layoutInterval(layoutScheduleThreshold)
161#if ENABLE(TEXT_AUTOSIZING)
162    , m_textAutosizingFontScaleFactor(1)
163#if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP
164    , m_textAutosizingWindowSizeOverride(320, 480)
165    , m_textAutosizingEnabled(true)
166#else
167    , m_textAutosizingEnabled(false)
168#endif
169#endif
170    SETTINGS_INITIALIZER_LIST
171    , m_screenFontSubstitutionEnabled(shouldEnableScreenFontSubstitutionByDefault())
172    , m_isJavaEnabled(false)
173    , m_isJavaEnabledForLocalFiles(true)
174    , m_loadsImagesAutomatically(false)
175    , m_areImagesEnabled(true)
176    , m_arePluginsEnabled(false)
177    , m_isScriptEnabled(false)
178    , m_needsAdobeFrameReloadingQuirk(false)
179    , m_usesPageCache(false)
180    , m_fontRenderingMode(0)
181    , m_showTiledScrollingIndicator(false)
182    , m_backgroundShouldExtendBeyondPage(false)
183    , m_dnsPrefetchingEnabled(false)
184#if ENABLE(TOUCH_EVENTS)
185    , m_touchEventEmulationEnabled(false)
186#endif
187    , m_scrollingPerformanceLoggingEnabled(false)
188    , m_timeWithoutMouseMovementBeforeHidingControls(3)
189    , m_setImageLoadingSettingsTimer(this, &Settings::imageLoadingSettingsTimerFired)
190#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
191    , m_hiddenPageDOMTimerThrottlingEnabled(false)
192#endif
193    , m_hiddenPageCSSAnimationSuspensionEnabled(false)
194    , m_fontFallbackPrefersPictographs(false)
195{
196    // A Frame may not have been created yet, so we initialize the AtomicString
197    // hash before trying to use it.
198    AtomicString::init();
199    initializeDefaultFontFamilies();
200    m_page = page; // Page is not yet fully initialized wen constructing Settings, so keeping m_page null over initializeDefaultFontFamilies() call.
201}
202
203Settings::~Settings()
204{
205}
206
207PassRefPtr<Settings> Settings::create(Page* page)
208{
209    return adoptRef(new Settings(page));
210}
211
212SETTINGS_SETTER_BODIES
213
214void Settings::setHiddenPageDOMTimerAlignmentInterval(double hiddenPageDOMTimerAlignmentinterval)
215{
216    gHiddenPageDOMTimerAlignmentInterval = hiddenPageDOMTimerAlignmentinterval;
217}
218
219double Settings::hiddenPageDOMTimerAlignmentInterval()
220{
221    return gHiddenPageDOMTimerAlignmentInterval;
222}
223
224#if !PLATFORM(COCOA)
225bool Settings::shouldEnableScreenFontSubstitutionByDefault()
226{
227    return true;
228}
229#endif
230
231#if !PLATFORM(COCOA)
232void Settings::initializeDefaultFontFamilies()
233{
234    // Other platforms can set up fonts from a client, but on Mac, we want it in WebCore to share code between WebKit1 and WebKit2.
235}
236#endif
237
238const AtomicString& Settings::standardFontFamily(UScriptCode script) const
239{
240    return m_fontGenericFamilies->standardFontFamily(script);
241}
242
243void Settings::setStandardFontFamily(const AtomicString& family, UScriptCode script)
244{
245    bool changes = m_fontGenericFamilies->setStandardFontFamily(family, script);
246    if (changes)
247        invalidateAfterGenericFamilyChange(m_page);
248}
249
250const AtomicString& Settings::fixedFontFamily(UScriptCode script) const
251{
252    return m_fontGenericFamilies->fixedFontFamily(script);
253}
254
255void Settings::setFixedFontFamily(const AtomicString& family, UScriptCode script)
256{
257    bool changes = m_fontGenericFamilies->setFixedFontFamily(family, script);
258    if (changes)
259        invalidateAfterGenericFamilyChange(m_page);
260}
261
262const AtomicString& Settings::serifFontFamily(UScriptCode script) const
263{
264    return m_fontGenericFamilies->serifFontFamily(script);
265}
266
267void Settings::setSerifFontFamily(const AtomicString& family, UScriptCode script)
268{
269    bool changes = m_fontGenericFamilies->setSerifFontFamily(family, script);
270    if (changes)
271        invalidateAfterGenericFamilyChange(m_page);
272}
273
274const AtomicString& Settings::sansSerifFontFamily(UScriptCode script) const
275{
276    return m_fontGenericFamilies->sansSerifFontFamily(script);
277}
278
279void Settings::setSansSerifFontFamily(const AtomicString& family, UScriptCode script)
280{
281    bool changes = m_fontGenericFamilies->setSansSerifFontFamily(family, script);
282    if (changes)
283        invalidateAfterGenericFamilyChange(m_page);
284}
285
286const AtomicString& Settings::cursiveFontFamily(UScriptCode script) const
287{
288    return m_fontGenericFamilies->cursiveFontFamily(script);
289}
290
291void Settings::setCursiveFontFamily(const AtomicString& family, UScriptCode script)
292{
293    bool changes = m_fontGenericFamilies->setCursiveFontFamily(family, script);
294    if (changes)
295        invalidateAfterGenericFamilyChange(m_page);
296}
297
298const AtomicString& Settings::fantasyFontFamily(UScriptCode script) const
299{
300    return m_fontGenericFamilies->fantasyFontFamily(script);
301}
302
303void Settings::setFantasyFontFamily(const AtomicString& family, UScriptCode script)
304{
305    bool changes = m_fontGenericFamilies->setFantasyFontFamily(family, script);
306    if (changes)
307        invalidateAfterGenericFamilyChange(m_page);
308}
309
310const AtomicString& Settings::pictographFontFamily(UScriptCode script) const
311{
312    return m_fontGenericFamilies->pictographFontFamily(script);
313}
314
315void Settings::setPictographFontFamily(const AtomicString& family, UScriptCode script)
316{
317    bool changes = m_fontGenericFamilies->setPictographFontFamily(family, script);
318    if (changes)
319        invalidateAfterGenericFamilyChange(m_page);
320}
321
322#if ENABLE(TEXT_AUTOSIZING)
323void Settings::setTextAutosizingEnabled(bool textAutosizingEnabled)
324{
325    if (m_textAutosizingEnabled == textAutosizingEnabled)
326        return;
327
328    m_textAutosizingEnabled = textAutosizingEnabled;
329    m_page->setNeedsRecalcStyleInAllFrames();
330}
331
332void Settings::setTextAutosizingWindowSizeOverride(const IntSize& textAutosizingWindowSizeOverride)
333{
334    if (m_textAutosizingWindowSizeOverride == textAutosizingWindowSizeOverride)
335        return;
336
337    m_textAutosizingWindowSizeOverride = textAutosizingWindowSizeOverride;
338    m_page->setNeedsRecalcStyleInAllFrames();
339}
340
341void Settings::setTextAutosizingFontScaleFactor(float fontScaleFactor)
342{
343    m_textAutosizingFontScaleFactor = fontScaleFactor;
344
345    // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
346    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext())
347        frame->document()->textAutosizer()->recalculateMultipliers();
348
349    m_page->setNeedsRecalcStyleInAllFrames();
350}
351
352#endif
353
354void Settings::setMediaTypeOverride(const String& mediaTypeOverride)
355{
356    if (m_mediaTypeOverride == mediaTypeOverride)
357        return;
358
359    m_mediaTypeOverride = mediaTypeOverride;
360
361    FrameView* view = m_page->mainFrame().view();
362    ASSERT(view);
363
364    view->setMediaType(mediaTypeOverride);
365    m_page->setNeedsRecalcStyleInAllFrames();
366}
367
368void Settings::setLoadsImagesAutomatically(bool loadsImagesAutomatically)
369{
370    m_loadsImagesAutomatically = loadsImagesAutomatically;
371
372    // Changing this setting to true might immediately start new loads for images that had previously had loading disabled.
373    // If this happens while a WebView is being dealloc'ed, and we don't know the WebView is being dealloc'ed, these new loads
374    // can cause crashes downstream when the WebView memory has actually been free'd.
375    // One example where this can happen is in Mac apps that subclass WebView then do work in their overridden dealloc methods.
376    // Starting these loads synchronously is not important.  By putting it on a 0-delay, properly closing the Page cancels them
377    // before they have a chance to really start.
378    // See http://webkit.org/b/60572 for more discussion.
379    m_setImageLoadingSettingsTimer.startOneShot(0);
380}
381
382void Settings::imageLoadingSettingsTimerFired(Timer<Settings>*)
383{
384    setImageLoadingSettings(m_page);
385}
386
387void Settings::setScriptEnabled(bool isScriptEnabled)
388{
389    if (m_isScriptEnabled == isScriptEnabled)
390        return;
391
392    m_isScriptEnabled = isScriptEnabled;
393#if PLATFORM(IOS)
394    m_page->setNeedsRecalcStyleInAllFrames();
395#endif
396    InspectorInstrumentation::scriptsEnabled(m_page, m_isScriptEnabled);
397}
398
399void Settings::setJavaEnabled(bool isJavaEnabled)
400{
401    m_isJavaEnabled = isJavaEnabled;
402}
403
404void Settings::setJavaEnabledForLocalFiles(bool isJavaEnabledForLocalFiles)
405{
406    m_isJavaEnabledForLocalFiles = isJavaEnabledForLocalFiles;
407}
408
409void Settings::setImagesEnabled(bool areImagesEnabled)
410{
411    m_areImagesEnabled = areImagesEnabled;
412
413    // See comment in setLoadsImagesAutomatically.
414    m_setImageLoadingSettingsTimer.startOneShot(0);
415}
416
417void Settings::setPluginsEnabled(bool arePluginsEnabled)
418{
419    if (m_arePluginsEnabled == arePluginsEnabled)
420        return;
421
422    m_arePluginsEnabled = arePluginsEnabled;
423    Page::refreshPlugins(false);
424}
425
426void Settings::setUserStyleSheetLocation(const URL& userStyleSheetLocation)
427{
428    if (m_userStyleSheetLocation == userStyleSheetLocation)
429        return;
430
431    m_userStyleSheetLocation = userStyleSheetLocation;
432
433    m_page->userStyleSheetLocationChanged();
434}
435
436// FIXME: This quirk is needed because of Radar 4674537 and 5211271. We need to phase it out once Adobe
437// can fix the bug from their end.
438void Settings::setNeedsAdobeFrameReloadingQuirk(bool shouldNotReloadIFramesForUnchangedSRC)
439{
440    m_needsAdobeFrameReloadingQuirk = shouldNotReloadIFramesForUnchangedSRC;
441}
442
443void Settings::setDefaultMinDOMTimerInterval(double interval)
444{
445    gDefaultMinDOMTimerInterval = interval;
446}
447
448double Settings::defaultMinDOMTimerInterval()
449{
450    return gDefaultMinDOMTimerInterval;
451}
452
453void Settings::setMinDOMTimerInterval(double interval)
454{
455    m_page->setMinimumTimerInterval(interval);
456}
457
458double Settings::minDOMTimerInterval()
459{
460    return m_page->minimumTimerInterval();
461}
462
463void Settings::setDefaultDOMTimerAlignmentInterval(double interval)
464{
465    gDefaultDOMTimerAlignmentInterval = interval;
466}
467
468double Settings::defaultDOMTimerAlignmentInterval()
469{
470    return gDefaultDOMTimerAlignmentInterval;
471}
472
473double Settings::domTimerAlignmentInterval() const
474{
475    return m_page->timerAlignmentInterval();
476}
477
478void Settings::setLayoutInterval(std::chrono::milliseconds layoutInterval)
479{
480    // FIXME: It seems weird that this function may disregard the specified layout interval.
481    // We should either expose layoutScheduleThreshold or better communicate this invariant.
482    m_layoutInterval = std::max(layoutInterval, layoutScheduleThreshold);
483}
484
485void Settings::setUsesPageCache(bool usesPageCache)
486{
487    if (m_usesPageCache == usesPageCache)
488        return;
489
490    m_usesPageCache = usesPageCache;
491    if (!m_usesPageCache) {
492        int first = -m_page->backForward().backCount();
493        int last = m_page->backForward().forwardCount();
494        for (int i = first; i <= last; i++)
495            pageCache()->remove(m_page->backForward().itemAtIndex(i));
496    }
497}
498
499void Settings::setScreenFontSubstitutionEnabled(bool enabled)
500{
501    if (m_screenFontSubstitutionEnabled == enabled)
502        return;
503    m_screenFontSubstitutionEnabled = enabled;
504    m_page->setNeedsRecalcStyleInAllFrames();
505}
506
507void Settings::setFontRenderingMode(FontRenderingMode mode)
508{
509    if (fontRenderingMode() == mode)
510        return;
511    m_fontRenderingMode = mode;
512    m_page->setNeedsRecalcStyleInAllFrames();
513}
514
515FontRenderingMode Settings::fontRenderingMode() const
516{
517    return static_cast<FontRenderingMode>(m_fontRenderingMode);
518}
519
520#if USE(SAFARI_THEME)
521void Settings::setShouldPaintNativeControls(bool shouldPaintNativeControls)
522{
523    gShouldPaintNativeControls = shouldPaintNativeControls;
524}
525#endif
526
527void Settings::setDNSPrefetchingEnabled(bool dnsPrefetchingEnabled)
528{
529    if (m_dnsPrefetchingEnabled == dnsPrefetchingEnabled)
530        return;
531
532    m_dnsPrefetchingEnabled = dnsPrefetchingEnabled;
533    m_page->dnsPrefetchingStateChanged();
534}
535
536void Settings::setShowTiledScrollingIndicator(bool enabled)
537{
538    if (m_showTiledScrollingIndicator == enabled)
539        return;
540
541    m_showTiledScrollingIndicator = enabled;
542}
543
544#if PLATFORM(WIN)
545void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
546{
547    gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers;
548}
549#endif
550
551void Settings::setStorageBlockingPolicy(SecurityOrigin::StorageBlockingPolicy enabled)
552{
553    if (m_storageBlockingPolicy == enabled)
554        return;
555
556    m_storageBlockingPolicy = enabled;
557    m_page->storageBlockingStateChanged();
558}
559
560void Settings::setBackgroundShouldExtendBeyondPage(bool shouldExtend)
561{
562    if (m_backgroundShouldExtendBeyondPage == shouldExtend)
563        return;
564
565    m_backgroundShouldExtendBeyondPage = shouldExtend;
566
567    m_page->mainFrame().view()->updateExtendBackgroundIfNecessary();
568}
569
570#if USE(AVFOUNDATION)
571void Settings::setAVFoundationEnabled(bool enabled)
572{
573    if (gAVFoundationEnabled == enabled)
574        return;
575
576    gAVFoundationEnabled = enabled;
577    HTMLMediaElement::resetMediaEngines();
578}
579#endif
580
581#if PLATFORM(COCOA)
582void Settings::setQTKitEnabled(bool enabled)
583{
584    if (gQTKitEnabled == enabled)
585        return;
586
587    gQTKitEnabled = enabled;
588    HTMLMediaElement::resetMediaEngines();
589}
590#endif
591
592void Settings::setScrollingPerformanceLoggingEnabled(bool enabled)
593{
594    m_scrollingPerformanceLoggingEnabled = enabled;
595
596    if (m_page->mainFrame().view())
597        m_page->mainFrame().view()->setScrollingPerformanceLoggingEnabled(enabled);
598}
599
600void Settings::setMockScrollbarsEnabled(bool flag)
601{
602    gMockScrollbarsEnabled = flag;
603    // FIXME: This should update scroll bars in existing pages.
604}
605
606bool Settings::mockScrollbarsEnabled()
607{
608    return gMockScrollbarsEnabled;
609}
610
611void Settings::setUsesOverlayScrollbars(bool flag)
612{
613    gUsesOverlayScrollbars = flag;
614    // FIXME: This should update scroll bars in existing pages.
615}
616
617bool Settings::usesOverlayScrollbars()
618{
619    return gUsesOverlayScrollbars;
620}
621
622void Settings::setShouldRespectPriorityInCSSAttributeSetters(bool flag)
623{
624    gShouldRespectPriorityInCSSAttributeSetters = flag;
625}
626
627bool Settings::shouldRespectPriorityInCSSAttributeSetters()
628{
629    return gShouldRespectPriorityInCSSAttributeSetters;
630}
631
632#if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
633void Settings::setHiddenPageDOMTimerThrottlingEnabled(bool flag)
634{
635    if (m_hiddenPageDOMTimerThrottlingEnabled == flag)
636        return;
637    m_hiddenPageDOMTimerThrottlingEnabled = flag;
638    m_page->hiddenPageDOMTimerThrottlingStateChanged();
639}
640#endif
641
642void Settings::setHiddenPageCSSAnimationSuspensionEnabled(bool flag)
643{
644    if (m_hiddenPageCSSAnimationSuspensionEnabled == flag)
645        return;
646    m_hiddenPageCSSAnimationSuspensionEnabled = flag;
647    m_page->hiddenPageCSSAnimationSuspensionStateChanged();
648}
649
650void Settings::setFontFallbackPrefersPictographs(bool preferPictographs)
651{
652    if (m_fontFallbackPrefersPictographs == preferPictographs)
653        return;
654
655    m_fontFallbackPrefersPictographs = preferPictographs;
656    m_page->setNeedsRecalcStyleInAllFrames();
657}
658
659void Settings::setLowPowerVideoAudioBufferSizeEnabled(bool flag)
660{
661    gLowPowerVideoAudioBufferSizeEnabled = flag;
662}
663
664#if PLATFORM(IOS)
665void Settings::setAudioSessionCategoryOverride(unsigned sessionCategory)
666{
667    AudioSession::sharedSession().setCategoryOverride(static_cast<AudioSession::CategoryType>(sessionCategory));
668}
669
670unsigned Settings::audioSessionCategoryOverride()
671{
672    return AudioSession::sharedSession().categoryOverride();
673}
674
675void Settings::setNetworkDataUsageTrackingEnabled(bool trackingEnabled)
676{
677    gNetworkDataUsageTrackingEnabled = trackingEnabled;
678}
679
680bool Settings::networkDataUsageTrackingEnabled()
681{
682    return gNetworkDataUsageTrackingEnabled;
683}
684
685static String& sharedNetworkInterfaceNameGlobal()
686{
687    static NeverDestroyed<String> networkInterfaceName;
688    return networkInterfaceName;
689}
690
691void Settings::setNetworkInterfaceName(const String& networkInterfaceName)
692{
693    sharedNetworkInterfaceNameGlobal() = networkInterfaceName;
694}
695
696const String& Settings::networkInterfaceName()
697{
698    return sharedNetworkInterfaceNameGlobal();
699}
700#endif
701
702} // namespace WebCore
703