2
* Copyright (C) 2010 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
27
#import "WebContext.h"
29
#import "NetworkProcessManager.h"
30
#import "PluginProcessManager.h"
31
#import "SharedWorkerProcessManager.h"
32
#import "WKBrowsingContextControllerInternal.h"
33
#import "WebKitSystemInterface.h"
34
#import "WebProcessCreationParameters.h"
35
#import "WebProcessMessages.h"
36
#import <WebCore/Color.h>
37
#import <WebCore/FileSystem.h>
38
#include <WebCore/NotImplemented.h>
39
#import <WebCore/PlatformPasteboard.h>
42
#if HAVE(HOSTED_CORE_ANIMATION) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
43
#import <QuartzCore/CARemoteLayerServer.h>
46
using namespace WebCore;
48
NSString *WebDatabaseDirectoryDefaultsKey = @"WebDatabaseDirectory";
49
NSString *WebKitLocalCacheDefaultsKey = @"WebKitLocalCache";
50
NSString *WebStorageDirectoryDefaultsKey = @"WebKitLocalStorageDatabasePathPreferenceKey";
51
NSString *WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey = @"WebKitKerningAndLigaturesEnabledByDefault";
53
static NSString *WebKitApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification = @"NSApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification";
55
// FIXME: <rdar://problem/9138817> - After this "backwards compatibility" radar is removed, this code should be removed to only return an empty String.
56
NSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey";
60
NSString *SchemeForCustomProtocolRegisteredNotificationName = @"WebKitSchemeForCustomProtocolRegisteredNotification";
61
NSString *SchemeForCustomProtocolUnregisteredNotificationName = @"WebKitSchemeForCustomProtocolUnregisteredNotification";
63
bool WebContext::s_applicationIsOccluded = false;
65
String WebContext::applicationCacheDirectory()
67
NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
69
appName = [[NSProcessInfo processInfo] processName];
73
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
74
NSString *cacheDir = [defaults objectForKey:WebKitLocalCacheDefaultsKey];
76
if (!cacheDir || ![cacheDir isKindOfClass:[NSString class]]) {
77
char cacheDirectory[MAXPATHLEN];
78
size_t cacheDirectoryLen = confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDirectory, MAXPATHLEN);
80
if (cacheDirectoryLen)
81
cacheDir = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:cacheDirectory length:cacheDirectoryLen - 1];
84
return [cacheDir stringByAppendingPathComponent:appName];
87
static void registerUserDefaultsIfNeeded()
89
static bool didRegister;
94
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
95
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey]];
99
void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
101
parameters.presenterApplicationPid = getpid();
103
parameters.parentProcessName = [[NSProcessInfo processInfo] processName];
105
NSURLCache *urlCache = [NSURLCache sharedURLCache];
106
parameters.nsURLCacheMemoryCapacity = [urlCache memoryCapacity];
107
parameters.nsURLCacheDiskCapacity = [urlCache diskCapacity];
109
registerUserDefaultsIfNeeded();
110
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
111
parameters.shouldForceScreenFontSubstitution = [[NSUserDefaults standardUserDefaults] boolForKey:@"NSFontDefaultScreenFontSubstitutionEnabled"];
113
parameters.shouldEnableKerningAndLigaturesByDefault = [[NSUserDefaults standardUserDefaults] boolForKey:WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey];
115
#if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION)
116
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
117
mach_port_t renderServerPort = [[CARemoteLayerServer sharedServer] serverPort];
119
mach_port_t renderServerPort = WKInitializeRenderServer();
121
if (renderServerPort != MACH_PORT_NULL)
122
parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND);
125
// FIXME: This should really be configurable; we shouldn't just blindly allow read access to the UI process bundle.
126
parameters.uiProcessBundleResourcePath = [[NSBundle mainBundle] resourcePath];
127
SandboxExtension::createHandle(parameters.uiProcessBundleResourcePath, SandboxExtension::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle);
129
parameters.uiProcessBundleIdentifier = String([[NSBundle mainBundle] bundleIdentifier]);
131
NSArray *schemes = [[WKBrowsingContextController customSchemes] allObjects];
132
for (size_t i = 0; i < [schemes count]; ++i)
133
parameters.urlSchemesRegisteredForCustomProtocols.append([schemes objectAtIndex:i]);
135
m_customSchemeRegisteredObserver = [[NSNotificationCenter defaultCenter] addObserverForName:WebKit::SchemeForCustomProtocolRegisteredNotificationName object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
136
NSString *scheme = [notification object];
137
ASSERT([scheme isKindOfClass:[NSString class]]);
138
sendToAllProcesses(Messages::WebProcess::RegisterSchemeForCustomProtocol(scheme));
141
m_customSchemeUnregisteredObserver = [[NSNotificationCenter defaultCenter] addObserverForName:WebKit::SchemeForCustomProtocolUnregisteredNotificationName object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
142
NSString *scheme = [notification object];
143
ASSERT([scheme isKindOfClass:[NSString class]]);
144
sendToAllProcesses(Messages::WebProcess::UnregisterSchemeForCustomProtocol(scheme));
147
// Listen for enhanced accessibility changes and propagate them to the WebProcess.
148
m_enhancedAccessibilityObserver = [[NSNotificationCenter defaultCenter] addObserverForName:WebKitApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *note) {
149
setEnhancedAccessibility([[[note userInfo] objectForKey:@"AXEnhancedUserInterface"] boolValue]);
153
void WebContext::platformInvalidateContext()
155
[[NSNotificationCenter defaultCenter] removeObserver:(id)m_enhancedAccessibilityObserver.get()];
158
String WebContext::platformDefaultDiskCacheDirectory() const
160
RetainPtr<NSString> cachePath(AdoptNS, (NSString *)WKCopyFoundationCacheDirectory());
162
cachePath = @"~/Library/Caches/com.apple.WebKit2.WebProcess";
164
return [cachePath.get() stringByStandardizingPath];
167
String WebContext::platformDefaultCookieStorageDirectory() const
170
return [@"" stringByStandardizingPath];
173
String WebContext::platformDefaultDatabaseDirectory() const
175
NSString *databasesDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebDatabaseDirectoryDefaultsKey];
176
if (!databasesDirectory || ![databasesDirectory isKindOfClass:[NSString class]])
177
databasesDirectory = @"~/Library/WebKit/Databases";
178
return [databasesDirectory stringByStandardizingPath];
181
String WebContext::platformDefaultIconDatabasePath() const
183
// FIXME: <rdar://problem/9138817> - After this "backwards compatibility" radar is removed, this code should be removed to only return an empty String.
184
NSString *databasesDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebIconDatabaseDirectoryDefaultsKey];
185
if (!databasesDirectory || ![databasesDirectory isKindOfClass:[NSString class]])
186
databasesDirectory = @"~/Library/Icons/WebpageIcons.db";
187
return [databasesDirectory stringByStandardizingPath];
190
String WebContext::platformDefaultLocalStorageDirectory() const
192
NSString *localStorageDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebStorageDirectoryDefaultsKey];
193
if (!localStorageDirectory || ![localStorageDirectory isKindOfClass:[NSString class]])
194
localStorageDirectory = @"~/Library/WebKit/LocalStorage";
195
return [localStorageDirectory stringByStandardizingPath];
198
bool WebContext::omitPDFSupport()
200
// Since this is a "secret default" we don't bother registering it.
201
return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"];
204
void WebContext::getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes)
206
PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes);
209
void WebContext::getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames)
211
PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType);
214
void WebContext::getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String& string)
216
string = PlatformPasteboard(pasteboardName).stringForType(pasteboardType);
219
void WebContext::getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle& handle, uint64_t& size)
221
RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).bufferForType(pasteboardType);
224
size = buffer->size();
225
RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(size);
226
memcpy(sharedMemoryBuffer->data(), buffer->data(), size);
227
sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly);
230
void WebContext::pasteboardCopy(const String& fromPasteboard, const String& toPasteboard)
232
PlatformPasteboard(toPasteboard).copy(fromPasteboard);
235
void WebContext::getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount)
237
changeCount = PlatformPasteboard(pasteboardName).changeCount();
240
void WebContext::getPasteboardUniqueName(String& pasteboardName)
242
pasteboardName = PlatformPasteboard::uniqueName();
245
void WebContext::getPasteboardColor(const String& pasteboardName, WebCore::Color& color)
247
color = PlatformPasteboard(pasteboardName).color();
250
void WebContext::getPasteboardURL(const String& pasteboardName, WTF::String& urlString)
252
urlString = PlatformPasteboard(pasteboardName).url().string();
255
void WebContext::addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes)
257
PlatformPasteboard(pasteboardName).addTypes(pasteboardTypes);
260
void WebContext::setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes)
262
PlatformPasteboard(pasteboardName).setTypes(pasteboardTypes);
265
void WebContext::setPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames)
267
PlatformPasteboard(pasteboardName).setPathnamesForType(pathnames, pasteboardType);
270
void WebContext::setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String& string)
272
PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType);
275
void WebContext::setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle& handle, uint64_t size)
277
if (handle.isNull()) {
278
PlatformPasteboard(pasteboardName).setBufferForType(0, pasteboardType);
281
RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly);
282
RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size);
283
PlatformPasteboard(pasteboardName).setBufferForType(buffer, pasteboardType);
286
void WebContext::applicationBecameVisible(uint32_t, void*, uint32_t, void*, uint32_t)
288
if (s_applicationIsOccluded) {
289
s_applicationIsOccluded = false;
291
const Vector<WebContext*>& contexts = WebContext::allContexts();
292
for (size_t i = 0, count = contexts.size(); i < count; ++i)
293
contexts[i]->sendToAllProcesses(Messages::WebProcess::SetApplicationIsOccluded(false));
295
#if ENABLE(PLUGIN_PROCESS)
296
PluginProcessManager::shared().setApplicationIsOccluded(false);
298
#if ENABLE(NETWORK_PROCESS)
299
NetworkProcessManager::shared().setApplicationIsOccluded(false);
301
#if ENABLE(SHARED_WORKER_PROCESS)
302
SharedWorkerProcessManager::shared().setApplicationIsOccluded(false);
307
void WebContext::applicationBecameOccluded(uint32_t, void*, uint32_t, void*, uint32_t)
309
if (!s_applicationIsOccluded) {
310
s_applicationIsOccluded = true;
311
const Vector<WebContext*>& contexts = WebContext::allContexts();
312
for (size_t i = 0, count = contexts.size(); i < count; ++i)
313
contexts[i]->sendToAllProcesses(Messages::WebProcess::SetApplicationIsOccluded(true));
315
#if ENABLE(PLUGIN_PROCESS)
316
PluginProcessManager::shared().setApplicationIsOccluded(true);
318
#if ENABLE(NETWORK_PROCESS)
319
NetworkProcessManager::shared().setApplicationIsOccluded(true);
321
#if ENABLE(SHARED_WORKER_PROCESS)
322
SharedWorkerProcessManager::shared().setApplicationIsOccluded(true);
327
void WebContext::initializeProcessSuppressionSupport()
329
static bool didInitialize = false;
333
didInitialize = true;
334
// A temporary default until process suppression is enabled by default, at which point a context setting can be added with the
335
// interpretation that any context disabling process suppression disables it for plugin/network and shared worker processes.
336
bool processSuppressionSupportEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitProcessSuppressionSupportEnabled"];
337
if (processSuppressionSupportEnabled)
338
registerOcclusionNotificationHandlers();
341
void WebContext::registerOcclusionNotificationHandlers()
343
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
344
if (!WKRegisterOcclusionNotificationHandler(WKOcclusionNotificationTypeApplicationBecameVisible, applicationBecameVisible)) {
345
WTFLogAlways("Registeration of \"App Became Visible\" notification handler failed.\n");
349
if (!WKRegisterOcclusionNotificationHandler(WKOcclusionNotificationTypeApplicationBecameOccluded, applicationBecameOccluded))
350
WTFLogAlways("Registeration of \"App Became Occluded\" notification handler failed.\n");
354
} // namespace WebKit