[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebCore / page / SettingsBase.cpp
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 "SettingsBase.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 "FontCascade.h"
37 #include "FontGenericFamilies.h"
38 #include "Frame.h"
39 #include "FrameTree.h"
40 #include "FrameView.h"
41 #include "HistoryItem.h"
42 #include "Page.h"
43 #include "PageCache.h"
44 #include "RenderWidget.h"
45 #include "RuntimeApplicationChecks.h"
46 #include "Settings.h"
47 #include "StorageMap.h"
48 #include <limits>
49 #include <wtf/StdLibExtras.h>
50
51 #if ENABLE(MEDIA_STREAM)
52 #include "MockRealtimeMediaSourceCenter.h"
53 #endif
54
55 namespace WebCore {
56
57 static void invalidateAfterGenericFamilyChange(Page* page)
58 {
59     invalidateFontCascadeCache();
60     if (page)
61         page->setNeedsRecalcStyleInAllFrames();
62 }
63
64 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
65 // FIXME: For faster machines this value can really be lowered to 200. 250 is adequate, but a little high
66 // for dual G5s. :)
67 static const Seconds layoutScheduleThreshold = 250_ms;
68
69 SettingsBase::SettingsBase(Page* page)
70     : m_page(nullptr)
71     , m_fontGenericFamilies(makeUnique<FontGenericFamilies>())
72     , m_layoutInterval(layoutScheduleThreshold)
73     , m_minimumDOMTimerInterval(DOMTimer::defaultMinimumInterval())
74     , m_setImageLoadingSettingsTimer(*this, &SettingsBase::imageLoadingSettingsTimerFired)
75 {
76     // A Frame may not have been created yet, so we initialize the AtomString
77     // hash before trying to use it.
78     AtomString::init();
79     initializeDefaultFontFamilies();
80     m_page = page; // Page is not yet fully initialized when constructing Settings, so keeping m_page null over initializeDefaultFontFamilies() call.
81 }
82
83 SettingsBase::~SettingsBase() = default;
84
85 float SettingsBase::defaultMinimumZoomFontSize()
86 {
87 #if PLATFORM(WATCHOS)
88     return 30;
89 #else
90     return 15;
91 #endif
92 }
93
94 #if !PLATFORM(IOS_FAMILY)
95 bool SettingsBase::defaultTextAutosizingEnabled()
96 {
97     return false;
98 }
99 #endif
100
101 bool SettingsBase::defaultDownloadableBinaryFontsEnabled()
102 {
103 #if PLATFORM(WATCHOS)
104     return false;
105 #else
106     return true;
107 #endif
108 }
109
110 bool SettingsBase::defaultContentChangeObserverEnabled()
111 {
112 #if PLATFORM(IOS_FAMILY) && !PLATFORM(MACCATALYST)
113     return true;
114 #else
115     return false;
116 #endif
117 }
118
119 #if !PLATFORM(COCOA)
120 const String& SettingsBase::defaultMediaContentTypesRequiringHardwareSupport()
121 {
122     return emptyString();
123 }
124 #endif
125
126 #if !PLATFORM(COCOA)
127 void SettingsBase::initializeDefaultFontFamilies()
128 {
129     // Other platforms can set up fonts from a client, but on Mac, we want it in WebCore to share code between WebKit1 and WebKit2.
130 }
131 #endif
132
133 #if ENABLE(MEDIA_SOURCE) && !PLATFORM(COCOA)
134 bool SettingsBase::platformDefaultMediaSourceEnabled()
135 {
136     return true;
137 }
138 #endif
139
140 const AtomString& SettingsBase::standardFontFamily(UScriptCode script) const
141 {
142     return m_fontGenericFamilies->standardFontFamily(script);
143 }
144
145 void SettingsBase::setStandardFontFamily(const AtomString& family, UScriptCode script)
146 {
147     bool changes = m_fontGenericFamilies->setStandardFontFamily(family, script);
148     if (changes)
149         invalidateAfterGenericFamilyChange(m_page);
150 }
151
152 const AtomString& SettingsBase::fixedFontFamily(UScriptCode script) const
153 {
154     return m_fontGenericFamilies->fixedFontFamily(script);
155 }
156
157 void SettingsBase::setFixedFontFamily(const AtomString& family, UScriptCode script)
158 {
159     bool changes = m_fontGenericFamilies->setFixedFontFamily(family, script);
160     if (changes)
161         invalidateAfterGenericFamilyChange(m_page);
162 }
163
164 const AtomString& SettingsBase::serifFontFamily(UScriptCode script) const
165 {
166     return m_fontGenericFamilies->serifFontFamily(script);
167 }
168
169 void SettingsBase::setSerifFontFamily(const AtomString& family, UScriptCode script)
170 {
171     bool changes = m_fontGenericFamilies->setSerifFontFamily(family, script);
172     if (changes)
173         invalidateAfterGenericFamilyChange(m_page);
174 }
175
176 const AtomString& SettingsBase::sansSerifFontFamily(UScriptCode script) const
177 {
178     return m_fontGenericFamilies->sansSerifFontFamily(script);
179 }
180
181 void SettingsBase::setSansSerifFontFamily(const AtomString& family, UScriptCode script)
182 {
183     bool changes = m_fontGenericFamilies->setSansSerifFontFamily(family, script);
184     if (changes)
185         invalidateAfterGenericFamilyChange(m_page);
186 }
187
188 const AtomString& SettingsBase::cursiveFontFamily(UScriptCode script) const
189 {
190     return m_fontGenericFamilies->cursiveFontFamily(script);
191 }
192
193 void SettingsBase::setCursiveFontFamily(const AtomString& family, UScriptCode script)
194 {
195     bool changes = m_fontGenericFamilies->setCursiveFontFamily(family, script);
196     if (changes)
197         invalidateAfterGenericFamilyChange(m_page);
198 }
199
200 const AtomString& SettingsBase::fantasyFontFamily(UScriptCode script) const
201 {
202     return m_fontGenericFamilies->fantasyFontFamily(script);
203 }
204
205 void SettingsBase::setFantasyFontFamily(const AtomString& family, UScriptCode script)
206 {
207     bool changes = m_fontGenericFamilies->setFantasyFontFamily(family, script);
208     if (changes)
209         invalidateAfterGenericFamilyChange(m_page);
210 }
211
212 const AtomString& SettingsBase::pictographFontFamily(UScriptCode script) const
213 {
214     return m_fontGenericFamilies->pictographFontFamily(script);
215 }
216
217 void SettingsBase::setPictographFontFamily(const AtomString& family, UScriptCode script)
218 {
219     bool changes = m_fontGenericFamilies->setPictographFontFamily(family, script);
220     if (changes)
221         invalidateAfterGenericFamilyChange(m_page);
222 }
223
224 void SettingsBase::setMinimumDOMTimerInterval(Seconds interval)
225 {
226     auto oldTimerInterval = std::exchange(m_minimumDOMTimerInterval, interval);
227
228     if (!m_page)
229         return;
230
231     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
232         if (frame->document())
233             frame->document()->adjustMinimumDOMTimerInterval(oldTimerInterval);
234     }
235 }
236
237 void SettingsBase::setLayoutInterval(Seconds layoutInterval)
238 {
239     // FIXME: It seems weird that this function may disregard the specified layout interval.
240     // We should either expose layoutScheduleThreshold or better communicate this invariant.
241     m_layoutInterval = std::max(layoutInterval, layoutScheduleThreshold);
242 }
243
244 void SettingsBase::setMediaContentTypesRequiringHardwareSupport(const String& contentTypes)
245 {
246     m_mediaContentTypesRequiringHardwareSupport.shrink(0);
247     for (auto type : StringView(contentTypes).split(':'))
248         m_mediaContentTypesRequiringHardwareSupport.append(ContentType { type.toString() });
249 }
250
251 void SettingsBase::setMediaContentTypesRequiringHardwareSupport(const Vector<ContentType>& contentTypes)
252 {
253     m_mediaContentTypesRequiringHardwareSupport = contentTypes;
254 }
255
256
257
258 // MARK - onChange handlers
259
260 void SettingsBase::setNeedsRecalcStyleInAllFrames()
261 {
262     if (m_page)
263         m_page->setNeedsRecalcStyleInAllFrames();
264 }
265
266 void SettingsBase::setNeedsRelayoutAllFrames()
267 {
268     if (!m_page)
269         return;
270
271     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
272         if (!frame->ownerRenderer())
273             continue;
274         frame->ownerRenderer()->setNeedsLayoutAndPrefWidthsRecalc();
275     }
276 }
277
278 void SettingsBase::mediaTypeOverrideChanged()
279 {
280     if (!m_page)
281         return;
282
283     FrameView* view = m_page->mainFrame().view();
284     if (view)
285         view->setMediaType(m_page->settings().mediaTypeOverride());
286
287     m_page->setNeedsRecalcStyleInAllFrames();
288 }
289
290 void SettingsBase::imagesEnabledChanged()
291 {
292     // Changing this setting to true might immediately start new loads for images that had previously had loading disabled.
293     // If this happens while a WebView is being dealloc'ed, and we don't know the WebView is being dealloc'ed, these new loads
294     // can cause crashes downstream when the WebView memory has actually been free'd.
295     // One example where this can happen is in Mac apps that subclass WebView then do work in their overridden dealloc methods.
296     // Starting these loads synchronously is not important. By putting it on a 0-delay, properly closing the Page cancels them
297     // before they have a chance to really start.
298     // See http://webkit.org/b/60572 for more discussion.
299     m_setImageLoadingSettingsTimer.startOneShot(0_s);
300 }
301
302 void SettingsBase::imageLoadingSettingsTimerFired()
303 {
304     if (!m_page)
305         return;
306
307     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
308         if (!frame->document())
309             continue;
310         frame->document()->cachedResourceLoader().setImagesEnabled(m_page->settings().areImagesEnabled());
311         frame->document()->cachedResourceLoader().setAutoLoadImages(m_page->settings().loadsImagesAutomatically());
312     }
313 }
314
315 void SettingsBase::pluginsEnabledChanged()
316 {
317     Page::refreshPlugins(false);
318 }
319
320 void SettingsBase::iceCandidateFilteringEnabledChanged()
321 {
322     if (!m_page)
323         return;
324
325     if (m_page->settings().iceCandidateFilteringEnabled())
326         m_page->enableICECandidateFiltering();
327     else
328         m_page->disableICECandidateFiltering();
329 }
330
331 #if ENABLE(TEXT_AUTOSIZING)
332
333 void SettingsBase::shouldEnableTextAutosizingBoostChanged()
334 {
335     if (!m_page)
336         return;
337
338     bool boostAutosizing = m_page->settings().shouldEnableTextAutosizingBoost();
339     m_oneLineTextMultiplierCoefficient = boostAutosizing ? boostedOneLineTextMultiplierCoefficient : defaultOneLineTextMultiplierCoefficient;
340     m_multiLineTextMultiplierCoefficient = boostAutosizing ? boostedMultiLineTextMultiplierCoefficient : defaultMultiLineTextMultiplierCoefficient;
341     m_maxTextAutosizingScaleIncrease = boostAutosizing ? boostedMaxTextAutosizingScaleIncrease : defaultMaxTextAutosizingScaleIncrease;
342
343     setNeedsRecalcStyleInAllFrames();
344 }
345
346 #endif
347
348 #if ENABLE(MEDIA_STREAM)
349 void SettingsBase::mockCaptureDevicesEnabledChanged()
350 {
351     bool enabled = false;
352     if (m_page)
353         enabled = m_page->settings().mockCaptureDevicesEnabled();
354
355     MockRealtimeMediaSourceCenter::setMockRealtimeMediaSourceCenterEnabled(enabled);
356 }
357 #endif
358
359 void SettingsBase::userStyleSheetLocationChanged()
360 {
361     if (m_page)
362         m_page->userStyleSheetLocationChanged();
363 }
364
365 void SettingsBase::usesPageCacheChanged()
366 {
367     if (!m_page)
368         return;
369
370     if (!m_page->settings().usesPageCache())
371         PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
372 }
373
374 void SettingsBase::dnsPrefetchingEnabledChanged()
375 {
376     if (m_page)
377         m_page->dnsPrefetchingStateChanged();
378 }
379
380 void SettingsBase::storageBlockingPolicyChanged()
381 {
382     if (m_page)
383         m_page->storageBlockingStateChanged();
384 }
385
386 void SettingsBase::backgroundShouldExtendBeyondPageChanged()
387 {
388     if (m_page)
389         m_page->mainFrame().view()->updateExtendBackgroundIfNecessary();
390 }
391
392 void SettingsBase::scrollingPerformanceLoggingEnabledChanged()
393 {
394     if (m_page && m_page->mainFrame().view())
395         m_page->mainFrame().view()->setScrollingPerformanceLoggingEnabled(m_page->settings().scrollingPerformanceLoggingEnabled());
396 }
397
398 void SettingsBase::hiddenPageDOMTimerThrottlingStateChanged()
399 {
400     if (m_page)
401         m_page->hiddenPageDOMTimerThrottlingStateChanged();
402 }
403
404 void SettingsBase::hiddenPageCSSAnimationSuspensionEnabledChanged()
405 {
406     if (m_page)
407         m_page->hiddenPageCSSAnimationSuspensionStateChanged();
408 }
409
410 void SettingsBase::resourceUsageOverlayVisibleChanged()
411 {
412 #if ENABLE(RESOURCE_USAGE)
413     if (m_page)
414         m_page->setResourceUsageOverlayVisible(m_page->settings().resourceUsageOverlayVisible());
415 #endif
416 }
417
418 } // namespace WebCore