<!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>[285799] trunk</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/285799">285799</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2021-11-14 23:17:34 -0800 (Sun, 14 Nov 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Get daemon API ready to work in the iOS simulator (starting with WebPushD)
https://bugs.webkit.org/show_bug.cgi?id=232982

Reviewed by Geoff Garen.

Source/WebKit:

Move all the "enable Notifications" SPI from Mac-only to cross platform:
* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _setNotificationsEnabled:]):
(-[WKPreferences _notificationsEnabled]):
* UIProcess/API/Cocoa/WKPreferencesPrivate.h:
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/Cocoa/UIDelegate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::setDelegate):
(WebKit::UIDelegate::UIClient::decidePolicyForNotificationPermissionRequest):

* WebKit.xcodeproj/project.pbxproj: Add a build phase script to install the daemon executables
  inside a Daemons directory within the built WebKit.framework for engineering builds.
* webpushd/WebPushDaemon.mm:

Tools:

To get this working we needed to:
- Have the Daemons installed in a simulator-runtime-root-visible path
- Point the OSLaunchDJob plist to the simulator-relative path, not Mac-relative
- Solve the "How do I kill existing instances to run a clean test?" problem within the simulator.

This patch does those things.

* TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements:
* TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:

* TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
(TestWebKitAPI::testWebPushDaemonPList):
(TestWebKitAPI::setUpTestWebPushD):
(TestWebKitAPI::cleanUpTestWebPushD):

* TestWebKitAPI/cocoa/DaemonTestUtilities.h:
* TestWebKitAPI/cocoa/DaemonTestUtilities.mm:
(TestWebKitAPI::registerPlistWithLaunchD):
(TestWebKitAPI::pidOfFirstDaemonInstance):
(TestWebKitAPI::killFirstInstanceOfDaemon):

WebKitLibraries:

* WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoaWKPreferencesmm">trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoaWKPreferencesPrivateh">trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessAPICocoaWKUIDelegatePrivateh">trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessCocoaUIDelegateh">trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessCocoaUIDelegatemm">trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm</a></li>
<li><a href="#trunkSourceWebKitWebKitxcodeprojprojectpbxproj">trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIiOSentitlements">trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements</a></li>
<li><a href="#trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig">trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWebKitCocoaWebPushDaemonmm">trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPIcocoaDaemonTestUtilitiesh">trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.h</a></li>
<li><a href="#trunkToolsTestWebKitAPIcocoaDaemonTestUtilitiesmm">trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.mm</a></li>
<li><a href="#trunkWebKitLibrariesChangeLog">trunk/WebKitLibraries/ChangeLog</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/</li>
<li><a href="#trunkWebKitLibrariesWebKitPrivateFrameworkStubsiOS15AppServerSupportframeworkAppServerSupporttbd">trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/ChangeLog       2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2021-11-14  Brady Eidson  <beidson@apple.com>
+
+        Get daemon API ready to work in the iOS simulator (starting with WebPushD)
+        https://bugs.webkit.org/show_bug.cgi?id=232982
+
+        Reviewed by Geoff Garen.
+
+        Move all the "enable Notifications" SPI from Mac-only to cross platform:
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _setNotificationsEnabled:]):
+        (-[WKPreferences _notificationsEnabled]):
+        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        * UIProcess/Cocoa/UIDelegate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::UIDelegate::setDelegate):
+        (WebKit::UIDelegate::UIClient::decidePolicyForNotificationPermissionRequest):
+
+        * WebKit.xcodeproj/project.pbxproj: Add a build phase script to install the daemon executables
+          inside a Daemons directory within the built WebKit.framework for engineering builds.
+        * webpushd/WebPushDaemon.mm:
+
</ins><span class="cx"> 2021-11-14  Fujii Hironori  <Hironori.Fujii@sony.com>
</span><span class="cx"> 
</span><span class="cx">         [GraphicsLayerWC] Incorrect compositing debug border color
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoaWKPreferencesmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm 2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm    2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -1163,16 +1163,6 @@
</span><span class="cx">     return _preferences->standardFontFamily();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)_setNotificationsEnabled:(BOOL)enabled
-{
-    _preferences->setNotificationsEnabled(enabled);
-}
-
-- (BOOL)_notificationsEnabled
-{
-    return _preferences->notificationsEnabled();
-}
-
</del><span class="cx"> - (void)_setBackspaceKeyNavigationEnabled:(BOOL)enabled
</span><span class="cx"> {
</span><span class="cx">     _preferences->setBackspaceKeyNavigationEnabled(enabled);
</span><span class="lines">@@ -1564,6 +1554,16 @@
</span><span class="cx">     _preferences->setAccessHandleEnabled(accessHandleEnabled);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_setNotificationsEnabled:(BOOL)enabled
+{
+    _preferences->setNotificationsEnabled(enabled);
+}
+
+- (BOOL)_notificationsEnabled
+{
+    return _preferences->notificationsEnabled();
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoaWKPreferencesPrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h   2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h      2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -176,6 +176,7 @@
</span><span class="cx"> @property (nonatomic, setter=_setFileSystemAccessEnabled:) BOOL _fileSystemAccessEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
</span><span class="cx"> @property (nonatomic, setter=_setStorageAPIEnabled:) BOOL _storageAPIEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
</span><span class="cx"> @property (nonatomic, setter=_setAccessHandleEnabled:) BOOL _accessHandleEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
</span><ins>+@property (nonatomic, setter=_setNotificationsEnabled:) BOOL _notificationsEnabled WK_API_AVAILABLE(macos(10.13.4), ios(WK_IOS_TBA));
</ins><span class="cx"> 
</span><span class="cx"> #if !TARGET_OS_IPHONE
</span><span class="cx"> @property (nonatomic, setter=_setWebGLEnabled:) BOOL _webGLEnabled WK_API_AVAILABLE(macos(10.13.4));
</span><span class="lines">@@ -200,7 +201,6 @@
</span><span class="cx"> @property (nonatomic, setter=_setPlugInSnapshottingEnabled:) BOOL _plugInSnapshottingEnabled WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> @property (nonatomic, setter=_setViewGestureDebuggingEnabled:) BOOL _viewGestureDebuggingEnabled WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> @property (nonatomic, setter=_setStandardFontFamily:) NSString *_standardFontFamily WK_API_AVAILABLE(macos(10.13.4));
</span><del>-@property (nonatomic, setter=_setNotificationsEnabled:) BOOL _notificationsEnabled WK_API_AVAILABLE(macos(10.13.4));
</del><span class="cx"> @property (nonatomic, setter=_setBackspaceKeyNavigationEnabled:) BOOL _backspaceKeyNavigationEnabled WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> @property (nonatomic, setter=_setAllowsInlineMediaPlayback:) BOOL _allowsInlineMediaPlayback WK_API_AVAILABLE(macos(10.14));
</span><span class="cx"> @property (nonatomic, setter=_setApplePayEnabled:) BOOL _applePayEnabled WK_API_AVAILABLE(macos(10.14));
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessAPICocoaWKUIDelegatePrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h    2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h       2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -159,6 +159,7 @@
</span><span class="cx"> - (void)_webViewDidDisableInspectorBrowserDomain:(WKWebView *)webView WK_API_AVAILABLE(macos(12.0), ios(15.0));
</span><span class="cx"> 
</span><span class="cx"> - (void)_webView:(WKWebView *)webView startXRSessionWithCompletionHandler:(void (^)(id))completionHandler WK_API_AVAILABLE(macos(12.0), ios(15.0));
</span><ins>+- (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(macos(10.13.4));
</ins><span class="cx"> 
</span><span class="cx"> #if TARGET_OS_IPHONE
</span><span class="cx"> 
</span><span class="lines">@@ -244,7 +245,6 @@
</span><span class="cx"> - (CGFloat)_webViewFooterHeight:(WKWebView *)webView WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> - (void)_webView:(WKWebView *)webView drawHeaderInRect:(CGRect)rect forPageWithTitle:(NSString *)title URL:(NSURL *)url WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> - (void)_webView:(WKWebView *)webView drawFooterInRect:(CGRect)rect forPageWithTitle:(NSString *)title URL:(NSURL *)url WK_API_AVAILABLE(macos(10.13.4));
</span><del>-- (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(macos(10.13.4));
</del><span class="cx"> - (void)_webView:(WKWebView *)webview mouseDidMoveOverElement:(_WKHitTestResult *)hitTestResult withFlags:(NSEventModifierFlags)flags userInfo:(id <NSSecureCoding>)userInfo;
</span><span class="cx"> - (void)_webView:(WKWebView *)webView didExceedBackgroundResourceLimitWhileInForeground:(_WKResourceLimit)limit WK_API_AVAILABLE(macos(10.13.4));
</span><span class="cx"> - (void)_webView:(WKWebView *)webView setResizable:(BOOL)isResizable WK_API_AVAILABLE(macos(10.13.4));
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessCocoaUIDelegateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h 2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h    2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -105,6 +105,8 @@
</span><span class="cx">         void didResignInputElementStrongPasswordAppearance(WebPageProxy&, API::Object*) final;
</span><span class="cx">         bool takeFocus(WebPageProxy*, WKFocusDirection) final;
</span><span class="cx">         void handleAutoplayEvent(WebPageProxy&, WebCore::AutoplayEvent, OptionSet<WebCore::AutoplayEventFlags>) final;
</span><ins>+        void decidePolicyForNotificationPermissionRequest(WebPageProxy&, API::SecurityOrigin&, CompletionHandler<void(bool allowed)>&&) final;
+
</ins><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">         void showPage(WebPageProxy*) final;
</span><span class="cx">         void focus(WebPageProxy*) final;
</span><span class="lines">@@ -123,7 +125,6 @@
</span><span class="cx">         void drawHeader(WebPageProxy&, WebFrameProxy&, WebCore::FloatRect&&) final;
</span><span class="cx">         void drawFooter(WebPageProxy&, WebFrameProxy&, WebCore::FloatRect&&) final;
</span><span class="cx"> 
</span><del>-        void decidePolicyForNotificationPermissionRequest(WebPageProxy&, API::SecurityOrigin&, CompletionHandler<void(bool allowed)>&&) final;
</del><span class="cx">         void mouseDidMoveOverElement(WebPageProxy&, const WebHitTestResultData&, OptionSet<WebEvent::Modifier>, API::Object*);
</span><span class="cx">         void didClickAutoFillButton(WebPageProxy&, API::Object*) final;
</span><span class="cx">         void toolbarsAreVisible(WebPageProxy&, Function<void(bool)>&&) final;
</span><span class="lines">@@ -215,7 +216,6 @@
</span><span class="cx">         bool webViewDidExceedBackgroundResourceLimitWhileInForeground : 1;
</span><span class="cx">         bool webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL : 1;
</span><span class="cx">         bool webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler : 1;
</span><del>-        bool webViewRequestNotificationPermissionForSecurityOriginDecisionHandler : 1;
</del><span class="cx">         bool webViewConfigurationForLocalInspector : 1;
</span><span class="cx">         bool webViewDidAttachLocalInspector : 1;
</span><span class="cx">         bool webViewWillCloseLocalInspector : 1;
</span><span class="lines">@@ -267,6 +267,7 @@
</span><span class="cx"> #if ENABLE(WEBXR) && PLATFORM(COCOA)
</span><span class="cx">         bool webViewStartXRSessionWithCompletionHandler : 1;
</span><span class="cx"> #endif
</span><ins>+        bool webViewRequestNotificationPermissionForSecurityOriginDecisionHandler : 1;
</ins><span class="cx">     } m_delegateMethods;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessCocoaUIDelegatemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm        2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm   2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -138,7 +138,6 @@
</span><span class="cx">     m_delegateMethods.webViewDidExceedBackgroundResourceLimitWhileInForeground = [delegate respondsToSelector:@selector(_webView:didExceedBackgroundResourceLimitWhileInForeground:)];
</span><span class="cx">     m_delegateMethods.webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL = [delegate respondsToSelector:@selector(_webView:saveDataToFile:suggestedFilename:mimeType:originatingURL:)];
</span><span class="cx">     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
</span><del>-    m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
</del><span class="cx">     m_delegateMethods.webViewConfigurationForLocalInspector = [delegate respondsToSelector:@selector(_webView:configurationForLocalInspector:)];
</span><span class="cx">     m_delegateMethods.webViewDidAttachLocalInspector = [delegate respondsToSelector:@selector(_webView:didAttachLocalInspector:)];
</span><span class="cx">     m_delegateMethods.webViewWillCloseLocalInspector = [delegate respondsToSelector:@selector(_webView:willCloseLocalInspector:)];
</span><span class="lines">@@ -196,6 +195,7 @@
</span><span class="cx"> #if ENABLE(WEBXR) && PLATFORM(COCOA)
</span><span class="cx">     m_delegateMethods.webViewStartXRSessionWithCompletionHandler = [delegate respondsToSelector:@selector(_webView:startXRSessionWithCompletionHandler:)];
</span><span class="cx"> #endif
</span><ins>+    m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CONTEXT_MENUS)
</span><span class="lines">@@ -619,6 +619,27 @@
</span><span class="cx">     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate->m_webView.get().get() handleAutoplayEvent:toWKAutoplayEvent(event) withFlags:toWKAutoplayEventFlags(flags)];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIDelegate::UIClient::decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy&, API::SecurityOrigin& securityOrigin, CompletionHandler<void(bool allowed)>&& completionHandler)
+{
+    if (!m_uiDelegate)
+        return completionHandler(false);
+
+    if (!m_uiDelegate->m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler)
+        return completionHandler(false);
+
+    auto delegate = m_uiDelegate->m_delegate.get();
+    if (!delegate)
+        return completionHandler(false);
+
+    auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:));
+    [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate->m_webView.get().get() requestNotificationPermissionForSecurityOrigin:wrapper(securityOrigin) decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
+        if (checker->completionHandlerHasBeenCalled())
+            return;
+        checker->didCallCompletionHandler();
+        completionHandler(result);
+    }).get()];
+}
+
</ins><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx"> bool UIDelegate::UIClient::canRunModal() const
</span><span class="cx"> {
</span><span class="lines">@@ -921,27 +942,6 @@
</span><span class="cx">     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate->m_webView.get().get() saveDataToFile:wrapper(data) suggestedFilename:suggestedFilename mimeType:mimeType originatingURL:originatingURL];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UIDelegate::UIClient::decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy&, API::SecurityOrigin& securityOrigin, CompletionHandler<void(bool allowed)>&& completionHandler)
-{
-    if (!m_uiDelegate)
-        return completionHandler(false);
-
-    if (!m_uiDelegate->m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler)
-        return completionHandler(false);
-    
-    auto delegate = m_uiDelegate->m_delegate.get();
-    if (!delegate)
-        return completionHandler(false);
-
-    auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:));
-    [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate->m_webView.get().get() requestNotificationPermissionForSecurityOrigin:wrapper(securityOrigin) decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
-        if (checker->completionHandlerHasBeenCalled())
-            return;
-        checker->didCallCompletionHandler();
-        completionHandler(result);
-    }).get()];
-}
-
</del><span class="cx"> Ref<API::InspectorConfiguration> UIDelegate::UIClient::configurationForLocalInspector(WebPageProxy&, WebInspectorUIProxy& inspector)
</span><span class="cx"> {
</span><span class="cx">     if (!m_uiDelegate)
</span></span></pre></div>
<a id="trunkSourceWebKitWebKitxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj     2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj        2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -13238,6 +13238,7 @@
</span><span class="cx">                          1D12CC4E2414265300FDA0A3 /* Copy Feature Flags Plist */,
</span><span class="cx">                          5379C7AC21E5288500E4A8F6 /* Check .xcfilelists */,
</span><span class="cx">                          933170072234674500B32554 /* Create symlinks to XPC services for engineering builds */,
</span><ins>+                               512B81CA273CAFBE00D87D49 /* Create symlinks to Daemons for engineering builds */,
</ins><span class="cx">                           0FB94836239F31B700926A8F /* Copy Testing Headers */,
</span><span class="cx">                          DFD03A29270D5F57001A996E /* Copy Daemon Plists */,
</span><span class="cx">                  );
</span><span class="lines">@@ -13731,6 +13732,24 @@
</span><span class="cx">                  shellPath = /bin/sh;
</span><span class="cx">                  shellScript = "Scripts/process-entitlements.sh\n";
</span><span class="cx">          };
</span><ins>+               512B81CA273CAFBE00D87D49 /* Create symlinks to Daemons for engineering builds */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputFileListPaths = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Create symlinks to Daemons for engineering builds";
+                       outputFileListPaths = (
+                       );
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/sh;
+                       shellScript = "if [[ \"${DEPLOYMENT_LOCATION}\" == \"YES\" ]]; then\n    exit\nfi\n\n# If we move the Mac Daemons path to WebKit.framework/Versions/A/Daemons,\n# in addition to a Mac-specific plists, the Mac paths below have to be updated as well.\nif [[ ${WK_PLATFORM_NAME} != \"macosx\" ]]; then\n    DAEMONS_PATH=\"${BUILT_PRODUCTS_DIR}/WebKit.framework/Daemons\"\n    BUILT_PRODUCTS_DIR_RELATIVE_PATH_FROM_DAEMONS=\"../..\"\nelse\n    DAEMONS_PATH=\"${BUILT_PRODUCTS_DIR}/WebKit.framework/Daemons\"\n    BUILT_PRODUCTS_DIR_RELATIVE_PATH_FROM_DAEMONS=\"../..\"\nfi\n\nmkdir -p \"${DAEMONS_PATH}\"\nln -sFh \"${BUILT_PRODUCTS_DIR_RELATIVE_PATH_FROM_DAEMONS}/webpushd\" \"${DAEMONS_PATH}/webpushd\"\nln -sFh \"${BUILT_PRODUCTS_DIR_RELATIVE_PATH_FROM_DAEMONS}/adattributiond\" \"${DAEMONS_PATH}/adattributiond\"\n";
+               };
</ins><span class="cx">           5325BDD221DFF47C00A0DEE1 /* ShellScript */ = {
</span><span class="cx">                  isa = PBXShellScriptBuildPhase;
</span><span class="cx">                  buildActionMask = 2147483647;
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/ChangeLog       2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2021-11-14  Brady Eidson  <beidson@apple.com>
+
+        Get daemon API ready to work in the iOS simulator (starting with WebPushD)
+        https://bugs.webkit.org/show_bug.cgi?id=232982
+
+        Reviewed by Geoff Garen.
+
+        To get this working we needed to:
+        - Have the Daemons installed in a simulator-runtime-root-visible path
+        - Point the OSLaunchDJob plist to the simulator-relative path, not Mac-relative
+        - Solve the "How do I kill existing instances to run a clean test?" problem within the simulator.
+        
+        This patch does those things.
+        
+        * TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements:
+        * TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig:
+        
+        * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
+        (TestWebKitAPI::testWebPushDaemonPList):
+        (TestWebKitAPI::setUpTestWebPushD):
+        (TestWebKitAPI::cleanUpTestWebPushD):
+        
+        * TestWebKitAPI/cocoa/DaemonTestUtilities.h:
+        * TestWebKitAPI/cocoa/DaemonTestUtilities.mm:
+        (TestWebKitAPI::registerPlistWithLaunchD):
+        (TestWebKitAPI::pidOfFirstDaemonInstance):
+        (TestWebKitAPI::killFirstInstanceOfDaemon):
+
</ins><span class="cx"> 2021-11-13  Simon Fraser  <simon.fraser@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Implement UIScriptController.sendEventStream() for DumpRenderTree
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIiOSentitlements"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements  2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements     2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -10,5 +10,7 @@
</span><span class="cx">  <true/>
</span><span class="cx">  <key>com.apple.Pasteboard.paste-unchecked</key>
</span><span class="cx">  <true/>
</span><ins>+       <key>com.apple.private.xpc.launchd.job-manager</key>
+       <string>TestWebKitAPI</string>
</ins><span class="cx"> </dict>
</span><span class="cx"> </plist>
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPIConfigurationsTestWebKitAPIxcconfig"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig  2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI.xcconfig     2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -46,6 +46,9 @@
</span><span class="cx"> WK_APPSERVERSUPPORT_LDFLAGS = $(WK_APPSERVERSUPPORT_LDFLAGS_$(WK_PLATFORM_NAME));
</span><span class="cx"> WK_APPSERVERSUPPORT_LDFLAGS_macosx = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_MACOS_1200));
</span><span class="cx"> WK_APPSERVERSUPPORT_LDFLAGS_MACOS_SINCE_1200 = -framework AppServerSupport
</span><ins>+WK_APPSERVERSUPPORT_LDFLAGS_iphoneos = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_IOS_15));
+WK_APPSERVERSUPPORT_LDFLAGS_iphonesimulator = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_IOS_15));
+WK_APPSERVERSUPPORT_LDFLAGS_IOS_SINCE_15 = -framework AppServerSupport
</ins><span class="cx"> 
</span><span class="cx"> WK_AUTHKIT_LDFLAGS = $(WK_AUTHKIT_LDFLAGS_$(WK_PLATFORM_NAME));
</span><span class="cx"> WK_AUTHKIT_LDFLAGS_iphoneos = $(WK_AUTHKIT_LDFLAGS$(WK_IOS_13));
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWebKitCocoaWebPushDaemonmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm     2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm        2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -32,6 +32,9 @@
</span><span class="cx"> #import <WebKit/WKUIDelegatePrivate.h>
</span><span class="cx"> #import <WebKit/_WKExperimentalFeature.h>
</span><span class="cx"> 
</span><ins>+// FIXME: These tests are still currently disabled on iOS while tooling issues with `run-api-tests` are resolved.
+#if PLATFORM(MAC)
+
</ins><span class="cx"> static bool alertReceived = false;
</span><span class="cx"> @interface NotificationPermissionDelegate : NSObject<WKUIDelegatePrivate>
</span><span class="cx"> @end
</span><span class="lines">@@ -53,9 +56,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace TestWebKitAPI {
</span><span class="cx"> 
</span><del>-// FIXME: Get this working in the iOS simulator.
-#if PLATFORM(MAC)
-
</del><span class="cx"> static RetainPtr<NSURL> testWebPushDaemonLocation()
</span><span class="cx"> {
</span><span class="cx">     return [currentExecutableDirectory() URLByAppendingPathComponent:@"webpushd" isDirectory:NO];
</span><span class="lines">@@ -84,7 +84,14 @@
</span><span class="cx">     {
</span><span class="cx">         auto programArguments = adoptNS(xpc_array_create(nullptr, 0));
</span><span class="cx">         auto executableLocation = testWebPushDaemonLocation();
</span><ins>+#if PLATFORM(MAC)
</ins><span class="cx">         xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, executableLocation.get().fileSystemRepresentation);
</span><ins>+#else
+        // FIXME: These tests are still currently disabled on iOS while tooling issues with `run-api-tests` are resolved.
+        // Once enabled, this patch must point to the webpushd executable at a path that exists within
+        // the simulator runtime root.
+        xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, "/usr/local/bin/webkit-testing/webpushd");
+#endif
</ins><span class="cx">         xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, "--machServiceName");
</span><span class="cx">         xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, "org.webkit.webpushtestdaemon.service");
</span><span class="cx">         xpc_dictionary_set_value(plist.get(), "ProgramArguments", programArguments.get());
</span><span class="lines">@@ -121,7 +128,7 @@
</span><span class="cx">         [fileManager removeItemAtURL:tempDir error:&error];
</span><span class="cx">     EXPECT_NULL(error);
</span><span class="cx"> 
</span><del>-    system("killall webpushd -9 2> /dev/null");
</del><ins>+    killFirstInstanceOfDaemon(@"webpushd");
</ins><span class="cx"> 
</span><span class="cx">     auto plist = testWebPushDaemonPList(tempDir);
</span><span class="cx"> #if HAVE(OS_LAUNCHD_JOB)
</span><span class="lines">@@ -135,7 +142,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void cleanUpTestWebPushD(NSURL *tempDir)
</span><span class="cx"> {
</span><del>-    system("killall webpushd -9");
</del><ins>+    killFirstInstanceOfDaemon(@"webpushd");
</ins><span class="cx"> 
</span><span class="cx">     EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:tempDir.path]);
</span><span class="cx">     NSError *error = nil;
</span><span class="lines">@@ -159,6 +166,13 @@
</span><span class="cx">     
</span><span class="cx">     __block bool done = false;
</span><span class="cx">     xpc_connection_send_message_with_reply(connection.get(), dictionary.get(), dispatch_get_main_queue(), ^(xpc_object_t reply) {
</span><ins>+        if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
+            NSLog(@"Unexpected non-dictionary: %@", reply);
+            done = true;
+            EXPECT_TRUE(FALSE);
+            return;
+        }
+
</ins><span class="cx">         size_t dataSize = 0;
</span><span class="cx">         const void* data = xpc_dictionary_get_data(reply, "encoded message", &dataSize);
</span><span class="cx">         EXPECT_EQ(dataSize, 15u);
</span><span class="lines">@@ -187,6 +201,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
</span><span class="cx">     configuration.get().websiteDataStore = dataStore.get();
</span><ins>+    [configuration.get().preferences _setNotificationsEnabled:YES];
</ins><span class="cx">     for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {
</span><span class="cx">         if ([feature.key isEqualToString:@"BuiltInNotificationsEnabled"])
</span><span class="cx">             [[configuration preferences] _setEnabled:YES forFeature:feature];
</span><span class="lines">@@ -222,6 +237,12 @@
</span><span class="cx">     EXPECT_TRUE([origin.get().protocol isEqualToString:@"testing"]);
</span><span class="cx">     EXPECT_TRUE([origin.get().host isEqualToString:@"main"]);
</span><span class="cx"> 
</span><ins>+    // If we failed to retrieve an expected origin, we will have failed the above checks
+    if (!origin) {
+        cleanUpTestWebPushD(tempDirectory);
+        return;
+    }
+
</ins><span class="cx">     originOperationDone = false;
</span><span class="cx">     [dataStore _deletePushAndNotificationRegistration:origin.get() completionHandler:^(NSError *error) {
</span><span class="cx">         EXPECT_FALSE(!!error);
</span><span class="lines">@@ -240,6 +261,6 @@
</span><span class="cx">     cleanUpTestWebPushD(tempDirectory);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+} // namespace TestWebKitAPI
+
</ins><span class="cx"> #endif // PLATFORM(MAC)
</span><del>-
-} // namespace TestWebKitAPI
</del></span></pre></div>
<a id="trunkToolsTestWebKitAPIcocoaDaemonTestUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.h (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.h    2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.h       2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -25,6 +25,8 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC) || PLATFORM(IOS)
+
</ins><span class="cx"> #import <wtf/RetainPtr.h>
</span><span class="cx"> #import <wtf/spi/darwin/XPCSPI.h>
</span><span class="cx"> 
</span><span class="lines">@@ -35,13 +37,15 @@
</span><span class="cx"> 
</span><span class="cx"> RetainPtr<NSURL> currentExecutableDirectory();
</span><span class="cx"> 
</span><del>-// FIXME: Get this working in the iOS simulator.
-#if PLATFORM(MAC)
</del><ins>+void killFirstInstanceOfDaemon(NSString *daemonExecutableName);
+
</ins><span class="cx"> #if HAVE(OS_LAUNCHD_JOB)
</span><span class="cx"> void registerPlistWithLaunchD(RetainPtr<xpc_object_t>&&);
</span><span class="cx"> #else
</span><span class="cx"> void registerPlistWithLaunchD(RetainPtr<NSDictionary>&&, NSURL *tempDir);
</span><span class="cx"> #endif
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> } // namespace TestWebKitAPI
</span><ins>+
+#endif // PLATFORM(MAC) || PLATFORM(IOS)
+
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPIcocoaDaemonTestUtilitiesmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.mm (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.mm   2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/Tools/TestWebKitAPI/cocoa/DaemonTestUtilities.mm      2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -26,9 +26,26 @@
</span><span class="cx"> #import "config.h"
</span><span class="cx"> #import "DaemonTestUtilities.h"
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC) || PLATFORM(IOS)
+
</ins><span class="cx"> #import <mach-o/dyld.h>
</span><span class="cx"> #import <wtf/Vector.h>
</span><span class="cx"> 
</span><ins>+NS_ASSUME_NONNULL_BEGIN
+
+#if PLATFORM(IOS)
+@interface NSTask : NSObject
+- (instancetype)init;
+- (void)launch;
+- (void)waitUntilExit;
+
+@property (nullable, copy) NSString *launchPath;
+@property (nullable, copy) NSArray<NSString *> *arguments;
+@property (nullable, retain) id standardOutput;
+@property (readonly, getter=isRunning) BOOL running;
+@end
+#endif
+
</ins><span class="cx"> namespace TestWebKitAPI {
</span><span class="cx"> 
</span><span class="cx"> static RetainPtr<NSURL> currentExecutableLocation()
</span><span class="lines">@@ -48,8 +65,6 @@
</span><span class="cx">     return [currentExecutableLocation() URLByDeletingLastPathComponent];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: Get this working in the iOS simulator.
-#if PLATFORM(MAC)
</del><span class="cx"> #if HAVE(OS_LAUNCHD_JOB)
</span><span class="cx"> 
</span><span class="cx"> void registerPlistWithLaunchD(RetainPtr<xpc_object_t>&& plist)
</span><span class="lines">@@ -57,7 +72,13 @@
</span><span class="cx">     NSError *error = nil;
</span><span class="cx">     auto launchDJob = adoptNS([[OSLaunchdJob alloc] initWithPlist:plist.get()]);
</span><span class="cx">     [launchDJob submit:&error];
</span><ins>+
+    // In the iOS Simulator we often see the following error here:
+    // Error Domain=OSLaunchdErrorDomain Code=17 "File exists"
+    // Tests still behave as expected.
+#if PLATFORM(MAC)
</ins><span class="cx">     EXPECT_FALSE(error);
</span><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #else // HAVE(OS_LAUNCHD_JOB)
</span><span class="lines">@@ -77,6 +98,59 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // HAVE(OS_LAUNCHD_JOB)
</span><del>-#endif // PLATFORM(MAC)
</del><span class="cx"> 
</span><ins>+static int pidOfFirstDaemonInstance(NSString *daemonExecutableName)
+{
+    auto task = adoptNS([[NSTask alloc] init]);
+    task.get().launchPath = @"/bin/ps";
+    task.get().arguments = @[
+        @"-ax",
+        @"-o",
+        @"pid,comm"
+    ];
+
+    auto taskPipe = adoptNS([[NSPipe alloc] init]);
+    [task setStandardOutput:taskPipe.get()];
+    [task launch];
+
+    auto data = adoptNS([[NSMutableData alloc] init]);
+    while ([task isRunning])
+        [data appendData:[[taskPipe fileHandleForReading] readDataToEndOfFile]];
+    [data appendData:[[taskPipe fileHandleForReading] readDataToEndOfFile]];
+
+    auto psString = adoptNS([[NSString alloc] initWithData:data.get() encoding:NSUTF8StringEncoding]);
+    NSArray<NSString *> *psEntries = [psString componentsSeparatedByString:@"\n"];
+
+    for (NSString* entry in psEntries) {
+        if (![entry hasSuffix:daemonExecutableName])
+            continue;
+        NSArray<NSString *> *components = [entry componentsSeparatedByString:@" "];
+        EXPECT_GE([components count], 2u);
+        return [[components firstObject] integerValue];
+    }
+
+    return 0;
+}
+
+void killFirstInstanceOfDaemon(NSString *daemonExecutableName)
+{
+    auto pid = pidOfFirstDaemonInstance(daemonExecutableName);
+    if (!pid)
+        return;
+
+    auto task = adoptNS([[NSTask alloc] init]);
+    task.get().launchPath = @"/bin/kill";
+    task.get().arguments = @[
+        @"-9",
+        [@(pid) stringValue]
+    ];
+
+    [task launch];
+    [task waitUntilExit];
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span><ins>+
+NS_ASSUME_NONNULL_END
+
+#endif // PLATFORM(MAC) || PLATFORM(IOS)
</ins></span></pre></div>
<a id="trunkWebKitLibrariesChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebKitLibraries/ChangeLog (285798 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitLibraries/ChangeLog  2021-11-15 04:22:34 UTC (rev 285798)
+++ trunk/WebKitLibraries/ChangeLog     2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2021-11-14  Brady Eidson  <beidson@apple.com>
+
+        Get daemon API ready to work in the iOS simulator (starting with WebPushD)
+        https://bugs.webkit.org/show_bug.cgi?id=232982
+
+        Reviewed by Geoff Garen.
+
+        * WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd: Added.
+
</ins><span class="cx"> 2021-09-24  Jonathan Bedard  <jbedard@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [iOS 15] Support building WebKit (Part 3)
</span></span></pre></div>
<a id="trunkWebKitLibrariesWebKitPrivateFrameworkStubsiOS15AppServerSupportframeworkAppServerSupporttbd"></a>
<div class="addfile"><h4>Added: trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd (0 => 285799)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd                         (rev 0)
+++ trunk/WebKitLibraries/WebKitPrivateFrameworkStubs/iOS/15/AppServerSupport.framework/AppServerSupport.tbd    2021-11-15 07:17:34 UTC (rev 285799)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+--- !tapi-tbd-v3
+archs:           [ x86_64, arm64, arm64e ]
+install-name:    '/System/Library/PrivateFrameworks/AppServerSupport.framework/AppServerSupport'
+platform: ios
+exports:
+  - archs:           [ x86_64, arm64, arm64e ]
+    objc-classes:    [ OSLaunchdJob ]
+...
</ins></span></pre>
</div>
</div>

</body>
</html>