Update peer connection preference
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPreferences.cpp
1 /*
2  * Copyright (C) 2010, 2011 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebPreferences.h"
28
29 #include "WebPageGroup.h"
30 #include "WebPreferencesKeys.h"
31 #include "WebProcessPool.h"
32 #include <WebCore/LibWebRTCProvider.h>
33 #include <wtf/NeverDestroyed.h>
34 #include <wtf/ThreadingPrimitives.h>
35
36 namespace WebKit {
37
38 // FIXME: Manipulating this variable is not thread safe.
39 // Instead of tracking private browsing state as a boolean preference, we should let the client provide storage sessions explicitly.
40 static unsigned privateBrowsingPageCount;
41
42 Ref<WebPreferences> WebPreferences::create(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix)
43 {
44     return adoptRef(*new WebPreferences(identifier, keyPrefix, globalDebugKeyPrefix));
45 }
46
47 PassRefPtr<WebPreferences> WebPreferences::createWithLegacyDefaults(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix)
48 {
49     auto preferences = WebPreferences::create(identifier, keyPrefix, globalDebugKeyPrefix);
50     // FIXME: The registerDefault...ValueForKey machinery is unnecessarily heavyweight and complicated.
51     // We can just compute different defaults for modern and legacy APIs in WebPreferencesDefinitions.h macros.
52     preferences->registerDefaultBoolValueForKey(WebPreferencesKey::javaEnabledKey(), true);
53     preferences->registerDefaultBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey(), true);
54     preferences->registerDefaultBoolValueForKey(WebPreferencesKey::pluginsEnabledKey(), true);
55     preferences->registerDefaultUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey(), WebCore::SecurityOrigin::AllowAllStorage);
56     return WTFMove(preferences);
57 }
58
59 WebPreferences::WebPreferences(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix)
60     : m_identifier(identifier)
61     , m_keyPrefix(keyPrefix)
62     , m_globalDebugKeyPrefix(globalDebugKeyPrefix)
63 {
64     platformInitializeStore();
65 }
66
67 WebPreferences::WebPreferences(const WebPreferences& other)
68     : m_keyPrefix(other.m_keyPrefix)
69     , m_globalDebugKeyPrefix(other.m_globalDebugKeyPrefix)
70     , m_store(other.m_store)
71 {
72     platformInitializeStore();
73 }
74
75 WebPreferences::~WebPreferences()
76 {
77     ASSERT(m_pages.isEmpty());
78 }
79
80 PassRefPtr<WebPreferences> WebPreferences::copy() const
81 {
82     return adoptRef(*new WebPreferences(*this));
83 }
84
85 void WebPreferences::addPage(WebPageProxy& webPageProxy)
86 {
87     ASSERT(!m_pages.contains(&webPageProxy));
88     m_pages.add(&webPageProxy);
89
90     if (privateBrowsingEnabled()) {
91         if (!privateBrowsingPageCount)
92             WebProcessPool::willStartUsingPrivateBrowsing();
93
94         ++privateBrowsingPageCount;
95     }
96 }
97
98 void WebPreferences::removePage(WebPageProxy& webPageProxy)
99 {
100     ASSERT(m_pages.contains(&webPageProxy));
101     m_pages.remove(&webPageProxy);
102
103     if (privateBrowsingEnabled()) {
104         --privateBrowsingPageCount;
105         if (!privateBrowsingPageCount)
106             WebProcessPool::willStopUsingPrivateBrowsing();
107     }
108 }
109
110 void WebPreferences::update()
111 {
112     for (auto& webPageProxy : m_pages)
113         webPageProxy->preferencesDidChange();
114 }
115
116 void WebPreferences::updateStringValueForKey(const String& key, const String& value)
117 {
118     platformUpdateStringValueForKey(key, value);
119     update(); // FIXME: Only send over the changed key and value.
120 }
121
122 void WebPreferences::updateBoolValueForKey(const String& key, bool value)
123 {
124     if (key == WebPreferencesKey::privateBrowsingEnabledKey()) {
125         updatePrivateBrowsingValue(value);
126         return;
127     }
128
129     platformUpdateBoolValueForKey(key, value);
130     update(); // FIXME: Only send over the changed key and value.
131 }
132
133 void WebPreferences::updateBoolValueForExperimentalFeatureKey(const String& key, bool value)
134 {
135     update(); // FIXME: Only send over the changed key and value.
136 }
137
138 void WebPreferences::updateUInt32ValueForKey(const String& key, uint32_t value)
139 {
140     platformUpdateUInt32ValueForKey(key, value);
141     update(); // FIXME: Only send over the changed key and value.
142 }
143
144 void WebPreferences::updateDoubleValueForKey(const String& key, double value)
145 {
146     platformUpdateDoubleValueForKey(key, value);
147     update(); // FIXME: Only send over the changed key and value.
148 }
149
150 void WebPreferences::updateFloatValueForKey(const String& key, float value)
151 {
152     platformUpdateFloatValueForKey(key, value);
153     update(); // FIXME: Only send over the changed key and value.
154 }
155
156 void WebPreferences::updatePrivateBrowsingValue(bool value)
157 {
158     platformUpdateBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey(), value);
159
160     unsigned pagesChanged = m_pages.size();
161     if (!pagesChanged)
162         return;
163
164     if (value) {
165         if (!privateBrowsingPageCount)
166             WebProcessPool::willStartUsingPrivateBrowsing();
167         privateBrowsingPageCount += pagesChanged;
168     }
169
170     update(); // FIXME: Only send over the changed key and value.
171
172     if (!value) {
173         ASSERT(privateBrowsingPageCount >= pagesChanged);
174         privateBrowsingPageCount -= pagesChanged;
175         if (!privateBrowsingPageCount)
176             WebProcessPool::willStopUsingPrivateBrowsing();
177     }
178 }
179
180 #define DEFINE_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
181     void WebPreferences::set##KeyUpper(const Type& value) \
182     { \
183         if (!m_store.set##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), value)) \
184             return; \
185         update##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), value); \
186         \
187     } \
188     \
189     Type WebPreferences::KeyLower() const \
190     { \
191         return m_store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()); \
192     } \
193
194 FOR_EACH_WEBKIT_PREFERENCE(DEFINE_PREFERENCE_GETTER_AND_SETTERS)
195 FOR_EACH_WEBKIT_DEBUG_PREFERENCE(DEFINE_PREFERENCE_GETTER_AND_SETTERS)
196
197 #undef DEFINE_PREFERENCE_GETTER_AND_SETTERS
198
199 #define DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
200     void WebPreferences::set##KeyUpper(const Type& value) \
201     { \
202         if (!m_store.set##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), value)) \
203             return; \
204         update##TypeName##ValueForExperimentalFeatureKey(WebPreferencesKey::KeyLower##Key(), value); \
205     \
206     } \
207     \
208     Type WebPreferences::KeyLower() const \
209     { \
210         return m_store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()); \
211     } \
212
213 FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS)
214
215 #undef DEFINE_EXPERIMENTAL_PREFERENCE_GETTER_AND_SETTERS
216
217 static Vector<RefPtr<API::Object>> createExperimentalFeaturesVector()
218 {
219     Vector<RefPtr<API::Object>> features;
220
221 #define ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
222     features.append(API::ExperimentalFeature::create(HumanReadableName, #KeyUpper, HumanReadableDescription, DefaultValue)); \
223
224     FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION)
225
226 #undef ADD_EXPERIMENTAL_PREFERENCE_DESCRIPTION
227
228     return features;
229 }
230
231 const Vector<RefPtr<API::Object>>& WebPreferences::experimentalFeatures()
232 {
233     static NeverDestroyed<Vector<RefPtr<API::Object>>> features = createExperimentalFeaturesVector();
234     return features;
235 }
236
237 bool WebPreferences::isEnabledForFeature(const API::ExperimentalFeature& feature) const
238 {
239     struct FeatureGetterMapping {
240         const char* name;
241         bool (WebPreferences::*function) () const;
242     };
243
244 #define MAKE_FEATURE_GETTER(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
245     { #KeyUpper, &WebPreferences::KeyLower }, \
246
247     static FeatureGetterMapping getters[] = {
248         FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(MAKE_FEATURE_GETTER)
249     };
250
251 #undef MAKE_FEATURE_GETTER
252
253     const String& key = feature.key();
254
255     for (auto& getter : getters) {
256         if (key == getter.name)
257             return (this->*getter.function)();
258     }
259
260     return false;
261 }
262
263 void WebPreferences::setEnabledForFeature(bool value, const API::ExperimentalFeature& feature)
264 {
265     struct FeatureSetterMapping {
266         const char* name;
267         void (WebPreferences::*function) (const bool&);
268     };
269
270 #define MAKE_FEATURE_SETTER(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
271     { #KeyUpper, &WebPreferences::set##KeyUpper }, \
272
273     static FeatureSetterMapping setters[] = {
274         FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(MAKE_FEATURE_SETTER)
275     };
276
277 #undef MAKE_FEATURE_SETTER
278
279     const String& key = feature.key();
280     
281     for (auto& setter : setters) {
282         if (key == setter.name) {
283             (this->*setter.function)(value);
284             return;
285         }
286     }
287 }
288
289 void WebPreferences::enableAllExperimentalFeatures()
290 {
291 #define SET_FEATURE_ENABLED(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) \
292     set##KeyUpper(true); \
293
294     FOR_EACH_WEBKIT_EXPERIMENTAL_FEATURE_PREFERENCE(SET_FEATURE_ENABLED)
295
296 #undef SET_FEATURE_ENABLED
297 }
298
299 bool WebPreferences::anyPagesAreUsingPrivateBrowsing()
300 {
301     return privateBrowsingPageCount;
302 }
303
304 void WebPreferences::registerDefaultBoolValueForKey(const String& key, bool value)
305 {
306     m_store.setOverrideDefaultsBoolValueForKey(key, value);
307     bool userValue;
308     if (platformGetBoolUserValueForKey(key, userValue))
309         m_store.setBoolValueForKey(key, userValue);
310 }
311
312 void WebPreferences::registerDefaultUInt32ValueForKey(const String& key, uint32_t value)
313 {
314     m_store.setOverrideDefaultsUInt32ValueForKey(key, value);
315     uint32_t userValue;
316     if (platformGetUInt32UserValueForKey(key, userValue))
317         m_store.setUInt32ValueForKey(key, userValue);
318 }
319
320 } // namespace WebKit