Crash when setting HTMLInputElement.checked for a disconnected radio button in a...
[WebKit-https.git] / Source / WebKitLegacy / mac / Misc / WebCache.mm
1 /*
2  * Copyright (C) 2006 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 #import "WebCache.h"
27
28 #import "NetworkStorageSessionMap.h"
29 #import "WebApplicationCacheInternal.h"
30 #import "WebNSObjectExtras.h"
31 #import "WebPreferences.h"
32 #import "WebView.h"
33 #import "WebViewInternal.h"
34 #import <JavaScriptCore/InitializeThreading.h>
35 #import <WebCore/ApplicationCacheStorage.h>
36 #import <WebCore/CookieJar.h>
37 #import <WebCore/CredentialStorage.h>
38 #import <WebCore/CrossOriginPreflightResultCache.h>
39 #import <WebCore/Document.h>
40 #import <WebCore/MemoryCache.h>
41 #import <WebCore/NetworkStorageSession.h>
42 #import <WebCore/StorageSessionProvider.h>
43 #import <wtf/MainThread.h>
44 #import <wtf/RunLoop.h>
45
46 #if PLATFORM(IOS_FAMILY)
47 #import "MemoryMeasure.h"
48 #import "WebFrameInternal.h"
49 #import <WebCore/BackForwardCache.h>
50 #import <WebCore/CachedImage.h>
51 #import <WebCore/Frame.h>
52 #import <WebCore/WebCoreThreadRun.h>
53 #endif
54
55 class DefaultStorageSessionProvider : public WebCore::StorageSessionProvider {
56     WebCore::NetworkStorageSession* storageSession() const final
57     {
58         return &NetworkStorageSessionMap::defaultStorageSession();
59     }
60 };
61
62 @implementation WebCache
63
64 + (void)initialize
65 {
66 #if !PLATFORM(IOS_FAMILY)
67     JSC::initializeThreading();
68     RunLoop::initializeMainRunLoop();
69 #endif
70 }
71
72 + (NSArray *)statistics
73 {
74     WebCore::MemoryCache::Statistics s = WebCore::MemoryCache::singleton().getStatistics();
75
76     return [NSArray arrayWithObjects:
77         [NSDictionary dictionaryWithObjectsAndKeys:
78             [NSNumber numberWithInt:s.images.count], @"Images",
79             [NSNumber numberWithInt:s.cssStyleSheets.count], @"CSS",
80 #if ENABLE(XSLT)
81             [NSNumber numberWithInt:s.xslStyleSheets.count], @"XSL",
82 #else
83             [NSNumber numberWithInt:0], @"XSL",
84 #endif
85             [NSNumber numberWithInt:s.scripts.count], @"JavaScript",
86             nil],
87         [NSDictionary dictionaryWithObjectsAndKeys:
88             [NSNumber numberWithInt:s.images.size], @"Images",
89             [NSNumber numberWithInt:s.cssStyleSheets.size] ,@"CSS",
90 #if ENABLE(XSLT)
91             [NSNumber numberWithInt:s.xslStyleSheets.size], @"XSL",
92 #else
93             [NSNumber numberWithInt:0], @"XSL",
94 #endif
95             [NSNumber numberWithInt:s.scripts.size], @"JavaScript",
96             nil],
97         [NSDictionary dictionaryWithObjectsAndKeys:
98             [NSNumber numberWithInt:s.images.liveSize], @"Images",
99             [NSNumber numberWithInt:s.cssStyleSheets.liveSize] ,@"CSS",
100 #if ENABLE(XSLT)
101             [NSNumber numberWithInt:s.xslStyleSheets.liveSize], @"XSL",
102 #else
103             [NSNumber numberWithInt:0], @"XSL",
104 #endif
105             [NSNumber numberWithInt:s.scripts.liveSize], @"JavaScript",
106             nil],
107         [NSDictionary dictionaryWithObjectsAndKeys:
108             [NSNumber numberWithInt:s.images.decodedSize], @"Images",
109             [NSNumber numberWithInt:s.cssStyleSheets.decodedSize] ,@"CSS",
110 #if ENABLE(XSLT)
111             [NSNumber numberWithInt:s.xslStyleSheets.decodedSize], @"XSL",
112 #else
113             [NSNumber numberWithInt:0], @"XSL",
114 #endif
115             [NSNumber numberWithInt:s.scripts.decodedSize], @"JavaScript",
116             nil],
117         nil];
118 }
119
120 + (void)empty
121 {
122     // Toggling the cache model like this forces the cache to evict all its in-memory resources.
123     WebCacheModel cacheModel = [WebView _cacheModel];
124     [WebView _setCacheModel:WebCacheModelDocumentViewer];
125     [WebView _setCacheModel:cacheModel];
126
127     // Empty the application cache.
128     webApplicationCacheStorage().empty();
129
130     // Empty the Cross-Origin Preflight cache
131     WebCore::CrossOriginPreflightResultCache::singleton().clear();
132 }
133
134 #if PLATFORM(IOS_FAMILY)
135 + (void)emptyInMemoryResources
136 {
137     // This method gets called from MobileSafari after it calls [WebView
138     // _close]. [WebView _close] schedules its work on the WebThread. So we
139     // schedule this method on the WebThread as well so as to pick up all the
140     // dead resources left behind after closing the WebViews
141     WebThreadRun(^{
142         WebKit::MemoryMeasure measurer("[WebCache emptyInMemoryResources]");
143
144         // Toggling the cache model like this forces the cache to evict all its in-memory resources.
145         WebCacheModel cacheModel = [WebView _cacheModel];
146         [WebView _setCacheModel:WebCacheModelDocumentViewer];
147         [WebView _setCacheModel:cacheModel];
148
149         WebCore::MemoryCache::singleton().pruneLiveResources(true);
150     });
151 }
152
153 + (void)sizeOfDeadResources:(int *)resources
154 {
155     WebCore::MemoryCache::Statistics stats = WebCore::MemoryCache::singleton().getStatistics();
156     if (resources) {
157         *resources = (stats.images.size - stats.images.liveSize)
158                      + (stats.cssStyleSheets.size - stats.cssStyleSheets.liveSize)
159 #if ENABLE(XSLT)
160                      + (stats.xslStyleSheets.size - stats.xslStyleSheets.liveSize)
161 #endif
162                      + (stats.scripts.size - stats.scripts.liveSize);
163     }
164 }
165
166 + (CGImageRef)imageForURL:(NSURL *)url
167 {
168     if (!url)
169         return nullptr;
170     
171     WebCore::ResourceRequest request(url);
172     WebCore::CachedResource* cachedResource = WebCore::MemoryCache::singleton().resourceForRequest(request, PAL::SessionID::defaultSessionID());
173     if (!is<WebCore::CachedImage>(cachedResource))
174         return nullptr;
175     WebCore::CachedImage& cachedImage = downcast<WebCore::CachedImage>(*cachedResource);
176     if (!cachedImage.hasImage())
177         return nullptr;
178     return cachedImage.image()->nativeImage().get();
179 }
180
181 #endif // PLATFORM(IOS_FAMILY)
182
183 + (void)setDisabled:(BOOL)disabled
184 {
185     if (!pthread_main_np())
186         return [[self _webkit_invokeOnMainThread] setDisabled:disabled];
187
188     WebCore::MemoryCache::singleton().setDisabled(disabled);
189 }
190
191 + (BOOL)isDisabled
192 {
193     return WebCore::MemoryCache::singleton().disabled();
194 }
195
196 + (void)clearCachedCredentials
197 {
198     [WebView _makeAllWebViewsPerformSelector:@selector(_clearCredentials)];
199     NetworkStorageSessionMap::defaultStorageSession().credentialStorage().clearCredentials();
200 }
201
202 @end