Unreviewed, rolling out r191902.
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / WKWebViewConfiguration.mm
1 /*
2  * Copyright (C) 2014, 2015 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 #import "config.h"
27 #import "WKWebViewConfigurationInternal.h"
28
29 #if WK_API_ENABLED
30
31 #import "APIPageConfiguration.h"
32 #import "WKPreferences.h"
33 #import "WKProcessPool.h"
34 #import "WKUserContentController.h"
35 #import "WKWebViewContentProviderRegistry.h"
36 #import "WeakObjCPtr.h"
37 #import "_WKVisitedLinkProvider.h"
38 #import "_WKWebsiteDataStoreInternal.h"
39 #import <wtf/RetainPtr.h>
40
41 #if PLATFORM(IOS)
42 #import "UIKitSPI.h"
43 #import "WebKitSystemInterfaceIOS.h"
44 #endif
45
46 template<typename T> class LazyInitialized {
47 public:
48     typedef typename WTF::GetPtrHelper<T>::PtrType PtrType;
49
50     template<typename F>
51     PtrType get(F&& f)
52     {
53         if (!m_isInitialized) {
54             m_value = f();
55             m_isInitialized = true;
56         }
57
58         return m_value.get();
59     }
60
61     void set(PtrType t)
62     {
63         m_value = t;
64         m_isInitialized = true;
65     }
66
67     void set(T&& t)
68     {
69         m_value = WTF::move(t);
70         m_isInitialized = true;
71     }
72
73     PtrType peek()
74     {
75         return m_value.get();
76     }
77
78 private:
79     bool m_isInitialized = false;
80     T m_value;
81 };
82
83 @implementation WKWebViewConfiguration {
84     LazyInitialized<RetainPtr<WKProcessPool>> _processPool;
85     LazyInitialized<RetainPtr<WKPreferences>> _preferences;
86     LazyInitialized<RetainPtr<WKUserContentController>> _userContentController;
87     LazyInitialized<RetainPtr<_WKVisitedLinkStore>> _visitedLinkStore;
88     LazyInitialized<RetainPtr<WKWebsiteDataStore>> _websiteDataStore;
89     WebKit::WeakObjCPtr<WKWebView> _relatedWebView;
90     WebKit::WeakObjCPtr<WKWebView> _alternateWebViewForNavigationGestures;
91     BOOL _treatsSHA1SignedCertificatesAsInsecure;
92     RetainPtr<NSString> _groupIdentifier;
93     LazyInitialized<RetainPtr<NSString>> _applicationNameForUserAgent;
94
95 #if PLATFORM(IOS)
96     LazyInitialized<RetainPtr<WKWebViewContentProviderRegistry>> _contentProviderRegistry;
97     BOOL _alwaysRunsAtForegroundPriority;
98     BOOL _allowsInlineMediaPlayback;
99     BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute;
100     BOOL _mediaDataLoadsAutomatically;
101 #endif
102 }
103
104 - (instancetype)init
105 {
106     if (!(self = [super init]))
107         return nil;
108     
109 #if PLATFORM(IOS)
110     _requiresUserActionForMediaPlayback = YES;
111     _allowsPictureInPictureMediaPlayback = YES;
112     _allowsInlineMediaPlayback = WKGetDeviceClass() == WKDeviceClassiPad;
113     _inlineMediaPlaybackRequiresPlaysInlineAttribute = !_allowsInlineMediaPlayback;
114     _mediaDataLoadsAutomatically = NO;
115 #endif
116
117 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
118     _allowsAirPlayForMediaPlayback = YES;
119 #endif
120
121     return self;
122 }
123
124 - (NSString *)description
125 {
126     return [NSString stringWithFormat:@"<%@: %p; processPool = %@; preferences = %@>", NSStringFromClass(self.class), self, self.processPool, self.preferences];
127 }
128
129 - (id)copyWithZone:(NSZone *)zone
130 {
131     WKWebViewConfiguration *configuration = [(WKWebViewConfiguration *)[[self class] allocWithZone:zone] init];
132
133     configuration.processPool = self.processPool;
134     configuration.preferences = self.preferences;
135     configuration.userContentController = self.userContentController;
136     configuration.websiteDataStore = self.websiteDataStore;
137     configuration._visitedLinkStore = self._visitedLinkStore;
138     configuration._relatedWebView = _relatedWebView.get().get();
139     configuration._alternateWebViewForNavigationGestures = _alternateWebViewForNavigationGestures.get().get();
140     configuration->_treatsSHA1SignedCertificatesAsInsecure = _treatsSHA1SignedCertificatesAsInsecure;
141 #if PLATFORM(IOS)
142     configuration._contentProviderRegistry = self._contentProviderRegistry;
143 #endif
144
145     configuration->_suppressesIncrementalRendering = self->_suppressesIncrementalRendering;
146     configuration.applicationNameForUserAgent = self.applicationNameForUserAgent;
147
148 #if PLATFORM(IOS)
149     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
150     configuration->_inlineMediaPlaybackRequiresPlaysInlineAttribute = self->_inlineMediaPlaybackRequiresPlaysInlineAttribute;
151     configuration->_mediaDataLoadsAutomatically = self->_mediaDataLoadsAutomatically;
152     configuration->_allowsPictureInPictureMediaPlayback = self->_allowsPictureInPictureMediaPlayback;
153     configuration->_alwaysRunsAtForegroundPriority = _alwaysRunsAtForegroundPriority;
154     configuration->_requiresUserActionForMediaPlayback = self->_requiresUserActionForMediaPlayback;
155     configuration->_selectionGranularity = self->_selectionGranularity;
156 #endif
157 #if ENABLE(WIRELESS_TARGET_PLAYBACK)
158     configuration->_allowsAirPlayForMediaPlayback = self->_allowsAirPlayForMediaPlayback;
159 #endif
160
161     return configuration;
162 }
163
164 - (WKProcessPool *)processPool
165 {
166     return _processPool.get([] { return adoptNS([[WKProcessPool alloc] init]); });
167 }
168
169 - (void)setProcessPool:(WKProcessPool *)processPool
170 {
171     _processPool.set(processPool);
172 }
173
174 - (WKPreferences *)preferences
175 {
176     return _preferences.get([] { return adoptNS([[WKPreferences alloc] init]); });
177 }
178
179 - (void)setPreferences:(WKPreferences *)preferences
180 {
181     _preferences.set(preferences);
182 }
183
184 - (WKUserContentController *)userContentController
185 {
186     return _userContentController.get([] { return adoptNS([[WKUserContentController alloc] init]); });
187 }
188
189 - (void)setUserContentController:(WKUserContentController *)userContentController
190 {
191     _userContentController.set(userContentController);
192 }
193
194 - (WKWebsiteDataStore *)websiteDataStore
195 {
196     return _websiteDataStore.get([] { return [WKWebsiteDataStore defaultDataStore]; });
197 }
198
199 - (void)setWebsiteDataStore:(WKWebsiteDataStore *)websiteDataStore
200 {
201     _websiteDataStore.set(websiteDataStore);
202 }
203
204 static NSString *defaultApplicationNameForUserAgent()
205 {
206 #if PLATFORM(IOS)
207     return [@"Mobile/" stringByAppendingString:[UIDevice currentDevice].buildVersion];
208 #else
209     return nil;
210 #endif
211 }
212
213 - (NSString *)applicationNameForUserAgent
214 {
215     return _applicationNameForUserAgent.get([] { return defaultApplicationNameForUserAgent(); });
216 }
217
218 - (void)setApplicationNameForUserAgent:(NSString *)applicationNameForUserAgent
219 {
220     _applicationNameForUserAgent.set(adoptNS([applicationNameForUserAgent copy]));
221 }
222
223 - (_WKVisitedLinkStore *)_visitedLinkStore
224 {
225     return _visitedLinkStore.get([] { return adoptNS([[_WKVisitedLinkStore alloc] init]); });
226 }
227
228 - (void)_setVisitedLinkStore:(_WKVisitedLinkStore *)visitedLinkStore
229 {
230     _visitedLinkStore.set(visitedLinkStore);
231 }
232
233 #pragma clang diagnostic push
234 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
235
236 - (_WKWebsiteDataStore *)_websiteDataStore
237 {
238     return self.websiteDataStore ? adoptNS([[_WKWebsiteDataStore alloc] initWithDataStore:self.websiteDataStore]).autorelease() : nullptr;
239 }
240
241 - (void)_setWebsiteDataStore:(_WKWebsiteDataStore *)websiteDataStore
242 {
243     self.websiteDataStore = websiteDataStore ? websiteDataStore->_dataStore.get() : nullptr;
244 }
245
246 -(_WKVisitedLinkProvider *)_visitedLinkProvider
247 {
248     return (_WKVisitedLinkProvider *)self._visitedLinkStore;
249 }
250
251 - (void)_setVisitedLinkProvider:(_WKVisitedLinkProvider *)_visitedLinkProvider
252 {
253     self._visitedLinkStore = _visitedLinkProvider;
254 }
255
256 #pragma clang diagnostic pop
257
258 #if PLATFORM(IOS)
259 - (WKWebViewContentProviderRegistry *)_contentProviderRegistry
260 {
261     return _contentProviderRegistry.get([] { return adoptNS([[WKWebViewContentProviderRegistry alloc] init]); });
262 }
263
264 - (void)_setContentProviderRegistry:(WKWebViewContentProviderRegistry *)registry
265 {
266     _contentProviderRegistry.set(registry);
267 }
268 #endif
269
270 - (void)_validate
271 {
272     if (!self.processPool)
273         [NSException raise:NSInvalidArgumentException format:@"configuration.processPool is nil"];
274
275     if (!self.preferences)
276         [NSException raise:NSInvalidArgumentException format:@"configuration.preferences is nil"];
277
278     if (!self.userContentController)
279         [NSException raise:NSInvalidArgumentException format:@"configuration.userContentController is nil"];
280
281     if (!self.websiteDataStore)
282         [NSException raise:NSInvalidArgumentException format:@"configuration.websiteDataStore is nil"];
283
284     if (!self._visitedLinkStore)
285         [NSException raise:NSInvalidArgumentException format:@"configuration._visitedLinkStore is nil"];
286
287 #if PLATFORM(IOS)
288     if (!self._contentProviderRegistry)
289         [NSException raise:NSInvalidArgumentException format:@"configuration._contentProviderRegistry is nil"];
290 #endif
291 }
292
293 @end
294
295 @implementation WKWebViewConfiguration (WKPrivate)
296
297 - (WKWebView *)_relatedWebView
298 {
299     return _relatedWebView.getAutoreleased();
300 }
301
302 - (void)_setRelatedWebView:(WKWebView *)relatedWebView
303 {
304     _relatedWebView = relatedWebView;
305 }
306
307 - (WKWebView *)_alternateWebViewForNavigationGestures
308 {
309     return _alternateWebViewForNavigationGestures.getAutoreleased();
310 }
311
312 - (void)_setAlternateWebViewForNavigationGestures:(WKWebView *)alternateView
313 {
314     _alternateWebViewForNavigationGestures = alternateView;
315 }
316
317 - (NSString *)_groupIdentifier
318 {
319     return _groupIdentifier.get();
320 }
321
322 - (void)_setGroupIdentifier:(NSString *)groupIdentifier
323 {
324     _groupIdentifier = groupIdentifier;
325 }
326
327 - (BOOL)_treatsSHA1SignedCertificatesAsInsecure
328 {
329     return _treatsSHA1SignedCertificatesAsInsecure;
330 }
331
332 - (void)_setTreatsSHA1SignedCertificatesAsInsecure:(BOOL)insecure
333 {
334     _treatsSHA1SignedCertificatesAsInsecure = insecure;
335 }
336
337 #if PLATFORM(IOS)
338 - (BOOL)_alwaysRunsAtForegroundPriority
339 {
340     return _alwaysRunsAtForegroundPriority;
341 }
342
343 - (void)_setAlwaysRunsAtForegroundPriority:(BOOL)alwaysRunsAtForegroundPriority
344 {
345     _alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority;
346 }
347
348 - (BOOL)_inlineMediaPlaybackRequiresPlaysInlineAttribute
349 {
350     return _inlineMediaPlaybackRequiresPlaysInlineAttribute;
351 }
352
353 - (void)_setInlineMediaPlaybackRequiresPlaysInlineAttribute:(BOOL)requires
354 {
355     _inlineMediaPlaybackRequiresPlaysInlineAttribute = requires;
356 }
357
358 - (BOOL)_mediaDataLoadsAutomatically
359 {
360     return _mediaDataLoadsAutomatically;
361 }
362
363 - (void)_setMediaDataLoadsAutomatically:(BOOL)mediaDataLoadsAutomatically
364 {
365     _mediaDataLoadsAutomatically = mediaDataLoadsAutomatically;
366 }
367 #endif
368
369 @end
370
371 @implementation WKWebViewConfiguration (WKDeprecated)
372
373 #if PLATFORM(IOS)
374 - (BOOL)mediaPlaybackAllowsAirPlay
375 {
376     return self.allowsAirPlayForMediaPlayback;
377 }
378
379 - (void)setMediaPlaybackAllowsAirPlay:(BOOL)allowed
380 {
381     self.allowsAirPlayForMediaPlayback = allowed;
382 }
383
384 - (BOOL)mediaPlaybackRequiresUserAction
385 {
386     return self.requiresUserActionForMediaPlayback;
387 }
388
389 - (void)setMediaPlaybackRequiresUserAction:(BOOL)required
390 {
391     self.requiresUserActionForMediaPlayback = required;
392 }
393 #endif // PLATFORM(IOS)
394
395 @end
396
397 #endif // WK_API_ENABLED