<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[209212] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/209212">209212</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2016-12-01 14:31:01 -0800 (Thu, 01 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Every WKWebView initialization spends a few milliseconds hitting the disk
https://bugs.webkit.org/show_bug.cgi?id=165268
&lt;rdar://problem/29010113&gt;

Reviewed by Brady Eidson.

Every WKWebView init currently involves doing directory creation and
symlink resolution for a number of paths (to create sandbox extensions
for all of our storage directories), which means touching the disk a
lot during init. All of these paths are immutable per-WebProcessPool,
so, instead, cache them on WebProcessPool and create sandbox extensions
from the already-resolved paths. This is a sizable (~4x) speedup when
initializing subsequent web views.

* Shared/SandboxExtension.h:
(WebKit::SandboxExtension::createHandleWithoutResolvingPath):
Add createHandleWithoutResolvingPath, which makes a sandbox extension
handle without doing symlink resolution.

(WebKit::resolvePathForSandboxExtension):
(WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension):
Add two functions that do the same resolution that SandboxExtension::createHandle
and ::createHandleForReadWriteDirectory do, but just return the paths,
for later use with createHandleWithoutResolvingPath.

* Shared/mac/SandboxExtensionMac.mm:
(WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension):
(WebKit::resolvePathForSandboxExtension):
(WebKit::SandboxExtension::createHandleWithoutResolvingPath):
(WebKit::SandboxExtension::createHandle):
(WebKit::SandboxExtension::createHandleForReadWriteDirectory):
Implement the aforementioned functions, and reimplement the existing
createHandle{ForReadWriteDirectory} functions in terms of them.

* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformDefaultIconDatabasePath):
Stop wasting time generating and resolving a platform default icon
database path, since we don't actually use it for anything anymore except
to determine whether the icon database is enabled, and we only want to
enable it if the client has provided a path.

(WebKit::WebProcessPool::platformResolvePathsForSandboxExtensions):
(WebKit::WebProcessPool::platformInitializeWebProcess):
* UIProcess/WebProcessPool.cpp:
(WebKit::m_hiddenPageThrottlingTimer):
(WebKit::WebProcessPool::resolvePathsForSandboxExtensions):
(WebKit::WebProcessPool::createNewWebProcess):
* UIProcess/WebProcessPool.h:
Resolve paths in resolvePathsForSandboxExtensions, and use the resolved
paths along with createHandleWithoutResolvingPath in order to effectively
cache the resolution operation.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedSandboxExtensionh">trunk/Source/WebKit2/Shared/SandboxExtension.h</a></li>
<li><a href="#trunkSourceWebKit2SharedmacSandboxExtensionMacmm">trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm">trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolcpp">trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolh">trunk/Source/WebKit2/UIProcess/WebProcessPool.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/ChangeLog        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2016-12-01  Tim Horton  &lt;timothy_horton@apple.com&gt;
+
+        Every WKWebView initialization spends a few milliseconds hitting the disk
+        https://bugs.webkit.org/show_bug.cgi?id=165268
+        &lt;rdar://problem/29010113&gt;
+
+        Reviewed by Brady Eidson.
+
+        Every WKWebView init currently involves doing directory creation and
+        symlink resolution for a number of paths (to create sandbox extensions
+        for all of our storage directories), which means touching the disk a
+        lot during init. All of these paths are immutable per-WebProcessPool,
+        so, instead, cache them on WebProcessPool and create sandbox extensions
+        from the already-resolved paths. This is a sizable (~4x) speedup when
+        initializing subsequent web views.
+
+        * Shared/SandboxExtension.h:
+        (WebKit::SandboxExtension::createHandleWithoutResolvingPath):
+        Add createHandleWithoutResolvingPath, which makes a sandbox extension
+        handle without doing symlink resolution.
+
+        (WebKit::resolvePathForSandboxExtension):
+        (WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension):
+        Add two functions that do the same resolution that SandboxExtension::createHandle
+        and ::createHandleForReadWriteDirectory do, but just return the paths,
+        for later use with createHandleWithoutResolvingPath.
+
+        * Shared/mac/SandboxExtensionMac.mm:
+        (WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension):
+        (WebKit::resolvePathForSandboxExtension):
+        (WebKit::SandboxExtension::createHandleWithoutResolvingPath):
+        (WebKit::SandboxExtension::createHandle):
+        (WebKit::SandboxExtension::createHandleForReadWriteDirectory):
+        Implement the aforementioned functions, and reimplement the existing
+        createHandle{ForReadWriteDirectory} functions in terms of them.
+
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformDefaultIconDatabasePath):
+        Stop wasting time generating and resolving a platform default icon
+        database path, since we don't actually use it for anything anymore except
+        to determine whether the icon database is enabled, and we only want to
+        enable it if the client has provided a path.
+
+        (WebKit::WebProcessPool::platformResolvePathsForSandboxExtensions):
+        (WebKit::WebProcessPool::platformInitializeWebProcess):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::m_hiddenPageThrottlingTimer):
+        (WebKit::WebProcessPool::resolvePathsForSandboxExtensions):
+        (WebKit::WebProcessPool::createNewWebProcess):
+        * UIProcess/WebProcessPool.h:
+        Resolve paths in resolvePathsForSandboxExtensions, and use the resolved
+        paths along with createHandleWithoutResolvingPath in order to effectively
+        cache the resolution operation.
+
</ins><span class="cx"> 2016-12-01  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Revert r208931
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedSandboxExtensionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/SandboxExtension.h (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/SandboxExtension.h        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/Shared/SandboxExtension.h        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -91,9 +91,10 @@
</span><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     static RefPtr&lt;SandboxExtension&gt; create(const Handle&amp;);
</span><del>-    static bool createHandle(const String&amp; path, Type type, Handle&amp;);
</del><ins>+    static bool createHandle(const String&amp; path, Type, Handle&amp;);
+    static bool createHandleWithoutResolvingPath(const String&amp; path, Type, Handle&amp;);
</ins><span class="cx">     static bool createHandleForReadWriteDirectory(const String&amp; path, Handle&amp;); // Will attempt to create the directory.
</span><del>-    static String createHandleForTemporaryFile(const String&amp; prefix, Type type, Handle&amp;);
</del><ins>+    static String createHandleForTemporaryFile(const String&amp; prefix, Type, Handle&amp;);
</ins><span class="cx">     static bool createHandleForGenericExtension(const String&amp; extensionClass, Handle&amp;);
</span><span class="cx">     ~SandboxExtension();
</span><span class="cx"> 
</span><span class="lines">@@ -127,6 +128,7 @@
</span><span class="cx"> inline bool SandboxExtension::HandleArray::decode(IPC::Decoder&amp;, HandleArray&amp;) { return true; }
</span><span class="cx"> inline RefPtr&lt;SandboxExtension&gt; SandboxExtension::create(const Handle&amp;) { return nullptr; }
</span><span class="cx"> inline bool SandboxExtension::createHandle(const String&amp;, Type, Handle&amp;) { return true; }
</span><ins>+inline bool SandboxExtension::createHandleWithoutResolvingPath(const String&amp;, Type, Handle&amp;) { return true; }
</ins><span class="cx"> inline bool SandboxExtension::createHandleForReadWriteDirectory(const String&amp;, Handle&amp;) { return true; }
</span><span class="cx"> inline String SandboxExtension::createHandleForTemporaryFile(const String&amp; /*prefix*/, Type, Handle&amp;) {return String();}
</span><span class="cx"> inline bool SandboxExtension::createHandleForGenericExtension(const String&amp; /*extensionClass*/, Handle&amp;) { return true; }
</span><span class="lines">@@ -136,8 +138,12 @@
</span><span class="cx"> inline bool SandboxExtension::consumePermanently() { return true; }
</span><span class="cx"> inline bool SandboxExtension::consumePermanently(const Handle&amp;) { return true; }
</span><span class="cx"> inline String stringByResolvingSymlinksInPath(const String&amp; path) { return path; }
</span><ins>+inline String resolvePathForSandboxExtension(const String&amp; path) { return path; }
+inline String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String&amp; path) { return path; }
</ins><span class="cx"> #else
</span><span class="cx"> String stringByResolvingSymlinksInPath(const String&amp; path);
</span><ins>+String resolvePathForSandboxExtension(const String&amp; path);
+String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String&amp; path);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebKit
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedmacSandboxExtensionMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -215,19 +215,37 @@
</span><span class="cx">     return String::fromUTF8(resolveSymlinksInPath(path.utf8()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool SandboxExtension::createHandle(const String&amp; path, Type type, Handle&amp; handle)
</del><ins>+String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String&amp; path)
</ins><span class="cx"> {
</span><del>-    ASSERT(!handle.m_sandboxExtension);
</del><ins>+    NSError *error = nil;
+    NSString *nsPath = path;
</ins><span class="cx"> 
</span><ins>+    if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&amp;error]) {
+        NSLog(@&quot;could not create \&quot;%@\&quot;, error %@&quot;, nsPath, error);
+        return { };
+    }
+
+    return resolvePathForSandboxExtension(path);
+}
+
+String resolvePathForSandboxExtension(const String&amp; path)
+{
</ins><span class="cx">     // FIXME: Do we need both resolveSymlinksInPath() and -stringByStandardizingPath?
</span><span class="cx">     CString fileSystemPath = fileSystemRepresentation([(NSString *)path stringByStandardizingPath]);
</span><span class="cx">     if (fileSystemPath.isNull()) {
</span><span class="cx">         LOG_ERROR(&quot;Could not create a valid file system representation for the string '%s' of length %lu&quot;, fileSystemPath.data(), fileSystemPath.length());
</span><del>-        return false;
</del><ins>+        return { };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CString standardizedPath = resolveSymlinksInPath(fileSystemPath);
</span><del>-    handle.m_sandboxExtension = WKSandboxExtensionCreate(standardizedPath.data(), wkSandboxExtensionType(type));
</del><ins>+    return String::fromUTF8(standardizedPath);
+}
+
+bool SandboxExtension::createHandleWithoutResolvingPath(const String&amp; path, Type type, Handle&amp; handle)
+{
+    ASSERT(!handle.m_sandboxExtension);
+
+    handle.m_sandboxExtension = WKSandboxExtensionCreate(path.utf8().data(), wkSandboxExtensionType(type));
</ins><span class="cx">     if (!handle.m_sandboxExtension) {
</span><span class="cx">         LOG_ERROR(&quot;Could not create a sandbox extension for '%s'&quot;, path.utf8().data());
</span><span class="cx">         return false;
</span><span class="lines">@@ -235,17 +253,20 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SandboxExtension::createHandle(const String&amp; path, Type type, Handle&amp; handle)
+{
+    ASSERT(!handle.m_sandboxExtension);
+
+    return createHandleWithoutResolvingPath(resolvePathForSandboxExtension(path), type, handle);
+}
+
</ins><span class="cx"> bool SandboxExtension::createHandleForReadWriteDirectory(const String&amp; path, SandboxExtension::Handle&amp; handle)
</span><span class="cx"> {
</span><del>-    NSError *error = nil;
-    NSString *nsPath = path;
-
-    if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&amp;error]) {
-        NSLog(@&quot;could not create \&quot;%@\&quot;, error %@&quot;, nsPath, error);
</del><ins>+    String resolvedPath = resolveAndCreateReadWriteDirectoryForSandboxExtension(path);
+    if (resolvedPath.isNull())
</ins><span class="cx">         return false;
</span><del>-    }
</del><span class="cx"> 
</span><del>-    return SandboxExtension::createHandle(path, SandboxExtension::ReadWrite, handle);
</del><ins>+    return SandboxExtension::createHandleWithoutResolvingPath(resolvedPath, SandboxExtension::ReadWrite, handle);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String SandboxExtension::createHandleForTemporaryFile(const String&amp; prefix, Type type, Handle&amp; handle)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -159,6 +159,17 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void WebProcessPool::platformResolvePathsForSandboxExtensions()
+{
+    m_resolvedPaths.uiProcessBundleResourcePath = resolvePathForSandboxExtension([[NSBundle mainBundle] resourcePath]);
+
+#if PLATFORM(IOS)
+    m_resolvedPaths.cookieStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(cookieStorageDirectory());
+    m_resolvedPaths.containerCachesDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(webContentCachesDirectory());
+    m_resolvedPaths.containerTemporaryDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(containerTemporaryDirectory());
+#endif
+}
+
</ins><span class="cx"> void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters&amp; parameters)
</span><span class="cx"> {
</span><span class="cx">     parameters.presenterApplicationPid = getpid();
</span><span class="lines">@@ -186,11 +197,22 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     // FIXME: This should really be configurable; we shouldn't just blindly allow read access to the UI process bundle.
</span><del>-    parameters.uiProcessBundleResourcePath = [[NSBundle mainBundle] resourcePath];
-    SandboxExtension::createHandle(parameters.uiProcessBundleResourcePath, SandboxExtension::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle);
</del><ins>+    parameters.uiProcessBundleResourcePath = m_resolvedPaths.uiProcessBundleResourcePath;
+    SandboxExtension::createHandleWithoutResolvingPath(parameters.uiProcessBundleResourcePath, SandboxExtension::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle);
</ins><span class="cx"> 
</span><span class="cx">     parameters.uiProcessBundleIdentifier = String([[NSBundle mainBundle] bundleIdentifier]);
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    if (!m_resolvedPaths.cookieStorageDirectory.isEmpty())
+        SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.cookieStorageDirectory, SandboxExtension::ReadWrite, parameters.cookieStorageDirectoryExtensionHandle);
+
+    if (!m_resolvedPaths.containerCachesDirectory.isEmpty())
+        SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerCachesDirectory, SandboxExtension::ReadWrite, parameters.containerCachesDirectoryExtensionHandle);
+
+    if (!m_resolvedPaths.containerTemporaryDirectory.isEmpty())
+        SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerTemporaryDirectory, SandboxExtension::ReadWrite, parameters.containerTemporaryDirectoryExtensionHandle);
+#endif
+
</ins><span class="cx">     parameters.fontWhitelist = m_fontWhitelist;
</span><span class="cx"> 
</span><span class="cx">     if (m_bundleParameters) {
</span><span class="lines">@@ -437,11 +459,7 @@
</span><span class="cx"> 
</span><span class="cx"> String WebProcessPool::platformDefaultIconDatabasePath() const
</span><span class="cx"> {
</span><del>-    // FIXME: &lt;rdar://problem/9138817&gt; - After this &quot;backwards compatibility&quot; radar is removed, this code should be removed to only return an empty String.
-    NSString *databasesDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebIconDatabaseDirectoryDefaultsKey];
-    if (!databasesDirectory || ![databasesDirectory isKindOfClass:[NSString class]])
-        databasesDirectory = @&quot;~/Library/Icons/WebpageIcons.db&quot;;
-    return stringByResolvingSymlinksInPath([databasesDirectory stringByStandardizingPath]);
</del><ins>+    return &quot;&quot;;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WebProcessPool::omitPDFSupport()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -202,6 +202,8 @@
</span><span class="cx"> 
</span><span class="cx">     addLanguageChangeObserver(this, languageChanged);
</span><span class="cx"> 
</span><ins>+    resolvePathsForSandboxExtensions();
+
</ins><span class="cx"> #if !LOG_DISABLED || !RELEASE_LOG_DISABLED
</span><span class="cx">     WebCore::initializeLogChannelsIfNecessary();
</span><span class="cx">     WebKit::initializeLogChannelsIfNecessary();
</span><span class="lines">@@ -527,6 +529,17 @@
</span><span class="cx">     m_processWithPageCache = process;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebProcessPool::resolvePathsForSandboxExtensions()
+{
+    m_resolvedPaths.injectedBundlePath = resolvePathForSandboxExtension(injectedBundlePath());
+    m_resolvedPaths.applicationCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration-&gt;applicationCacheDirectory());
+    m_resolvedPaths.webSQLDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration-&gt;webSQLDatabaseDirectory());
+    m_resolvedPaths.mediaCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration-&gt;mediaCacheDirectory());
+    m_resolvedPaths.mediaKeyStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration-&gt;mediaKeysStorageDirectory());
+
+    platformResolvePathsForSandboxExtensions();
+}
+
</ins><span class="cx"> WebProcessProxy&amp; WebProcessPool::createNewWebProcess()
</span><span class="cx"> {
</span><span class="cx">     ensureNetworkProcess();
</span><span class="lines">@@ -537,41 +550,27 @@
</span><span class="cx"> 
</span><span class="cx">     parameters.urlParserEnabled = URLParser::enabled();
</span><span class="cx">     
</span><del>-    parameters.injectedBundlePath = injectedBundlePath();
</del><ins>+    parameters.injectedBundlePath = m_resolvedPaths.injectedBundlePath;
</ins><span class="cx">     if (!parameters.injectedBundlePath.isEmpty())
</span><del>-        SandboxExtension::createHandle(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle);
</del><ins>+        SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle);
</ins><span class="cx"> 
</span><del>-    parameters.applicationCacheDirectory = m_configuration-&gt;applicationCacheDirectory();
</del><ins>+    parameters.applicationCacheDirectory = m_resolvedPaths.applicationCacheDirectory;
+    if (!parameters.applicationCacheDirectory.isEmpty())
+        SandboxExtension::createHandleWithoutResolvingPath(parameters.applicationCacheDirectory, SandboxExtension::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle);
+
</ins><span class="cx">     parameters.applicationCacheFlatFileSubdirectoryName = m_configuration-&gt;applicationCacheFlatFileSubdirectoryName();
</span><span class="cx"> 
</span><del>-    if (!parameters.applicationCacheDirectory.isEmpty())
-        SandboxExtension::createHandleForReadWriteDirectory(parameters.applicationCacheDirectory, parameters.applicationCacheDirectoryExtensionHandle);
-
-    parameters.webSQLDatabaseDirectory = m_configuration-&gt;webSQLDatabaseDirectory();
</del><ins>+    parameters.webSQLDatabaseDirectory = m_resolvedPaths.webSQLDatabaseDirectory;
</ins><span class="cx">     if (!parameters.webSQLDatabaseDirectory.isEmpty())
</span><del>-        SandboxExtension::createHandleForReadWriteDirectory(parameters.webSQLDatabaseDirectory, parameters.webSQLDatabaseDirectoryExtensionHandle);
</del><ins>+        SandboxExtension::createHandleWithoutResolvingPath(parameters.webSQLDatabaseDirectory, SandboxExtension::ReadWrite, parameters.webSQLDatabaseDirectoryExtensionHandle);
</ins><span class="cx"> 
</span><del>-    parameters.mediaCacheDirectory = m_configuration-&gt;mediaCacheDirectory();
</del><ins>+    parameters.mediaCacheDirectory = m_resolvedPaths.mediaCacheDirectory;
</ins><span class="cx">     if (!parameters.mediaCacheDirectory.isEmpty())
</span><del>-        SandboxExtension::createHandleForReadWriteDirectory(parameters.mediaCacheDirectory, parameters.mediaCacheDirectoryExtensionHandle);
</del><ins>+        SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaCacheDirectory, SandboxExtension::ReadWrite, parameters.mediaCacheDirectoryExtensionHandle);
</ins><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
-    String cookieStorageDirectory = this-&gt;cookieStorageDirectory();
-    if (!cookieStorageDirectory.isEmpty())
-        SandboxExtension::createHandleForReadWriteDirectory(cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle);
-
-    String containerCachesDirectory = this-&gt;webContentCachesDirectory();
-    if (!containerCachesDirectory.isEmpty())
-        SandboxExtension::createHandleForReadWriteDirectory(containerCachesDirectory, parameters.containerCachesDirectoryExtensionHandle);
-
-    String containerTemporaryDirectory = this-&gt;containerTemporaryDirectory();
-    if (!containerTemporaryDirectory.isEmpty())
-        SandboxExtension::createHandleForReadWriteDirectory(containerTemporaryDirectory, parameters.containerTemporaryDirectoryExtensionHandle);
-#endif
-
-    parameters.mediaKeyStorageDirectory = m_configuration-&gt;mediaKeysStorageDirectory();
</del><ins>+    parameters.mediaKeyStorageDirectory = m_resolvedPaths.mediaKeyStorageDirectory;
</ins><span class="cx">     if (!parameters.mediaKeyStorageDirectory.isEmpty())
</span><del>-        SandboxExtension::createHandleForReadWriteDirectory(parameters.mediaKeyStorageDirectory, parameters.mediaKeyStorageDirectoryExtensionHandle);
</del><ins>+        SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaKeyStorageDirectory, SandboxExtension::ReadWrite, parameters.mediaKeyStorageDirectoryExtensionHandle);
</ins><span class="cx"> 
</span><span class="cx">     parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession;
</span><span class="cx"> 
</span><span class="lines">@@ -594,8 +593,6 @@
</span><span class="cx">     parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
</span><span class="cx">     parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing;
</span><span class="cx"> 
</span><del>-    // FIXME: This leaves UI process and WebProcess disagreeing about the state if the client hasn't set the path.
-    // iconDatabasePath is non-empty by default, but m_iconDatabase isn't enabled in UI process unless setDatabasePath is called explicitly.
</del><span class="cx">     parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty();
</span><span class="cx"> 
</span><span class="cx">     parameters.terminationTimeout = 0;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.h (209211 => 209212)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2016-12-01 22:24:07 UTC (rev 209211)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2016-12-01 22:31:01 UTC (rev 209212)
</span><span class="lines">@@ -444,6 +444,9 @@
</span><span class="cx"> 
</span><span class="cx">     void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool);
</span><span class="cx"> 
</span><ins>+    void resolvePathsForSandboxExtensions();
+    void platformResolvePathsForSandboxExtensions();
+
</ins><span class="cx">     Ref&lt;API::ProcessPoolConfiguration&gt; m_configuration;
</span><span class="cx"> 
</span><span class="cx">     IPC::MessageReceiverMap m_messageReceiverMap;
</span><span class="lines">@@ -574,6 +577,22 @@
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     bool m_cookieStoragePartitioningEnabled { false };
</span><span class="cx"> #endif
</span><ins>+
+    struct Paths {
+        String injectedBundlePath;
+        String applicationCacheDirectory;
+        String webSQLDatabaseDirectory;
+        String mediaCacheDirectory;
+        String mediaKeyStorageDirectory;
+        String uiProcessBundleResourcePath;
+
+#if PLATFORM(IOS)
+        String cookieStorageDirectory;
+        String containerCachesDirectory;
+        String containerTemporaryDirectory;
+#endif
+    };
+    Paths m_resolvedPaths;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T&gt;
</span></span></pre>
</div>
</div>

</body>
</html>