⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 287009 in webkit


Ignore:
Timestamp:
Dec 13, 2021, 8:23:27 PM (5 years ago)
Author:
beidson@apple.com
Message:

Teach webpushtool to register and "host" the daemon.
https://bugs.webkit.org/show_bug.cgi?id=234265

Reviewed by Tim Horton.

Source/JavaScriptCore:

  • inspector/ConsoleMessage.h: Remove using JSC::MessageType because it makes it hard for others to also have a MessageType type.
  • inspector/JSGlobalObjectConsoleClient.h:
  • runtime/ConsoleTypes.h:

Source/WebCore:

  • page/PageConsoleClient.h:

Source/WebKit:

Covered by API tests verifying hosting mode operation.

As various engineers work on various parts of the project, it's become apparent that it's super useful
to have a tool handle the "setting up" of the daemon itself, to avoid launchctl, etc.

Implement that, as well as a few other niceties found while testing.

  • Configurations/webpushtool.xcconfig:
  • Resources/webpushtool.entitlements:
  • Shared/Daemon/DaemonUtilities.mm:

(WebKit::startListeningForMachServiceConnections):

  • webpushd/AppBundleRequest.mm:

(WebPushD::AppBundleRequest::start):

  • webpushd/PushClientConnection.h:
  • webpushd/PushClientConnection.mm:

(WebPushD::ClientConnection::setHostAppAuditTokenData):
(WebPushD::ClientConnection::broadcastDebugMessage):

  • webpushd/WebPushDaemon.h:
  • webpushd/WebPushDaemon.mm:

(WebPushD::Daemon::broadcastAllConnectionIdentities):

  • webpushd/webpushtool/WebPushToolConnection.h:
  • webpushd/webpushtool/WebPushToolConnection.mm:

(WebPushTool::Connection::connectToService):
(WebPushTool::Connection::connectionDropped):

  • webpushd/webpushtool/WebPushToolMain.mm:

(printUsageAndTerminate):
(registerDaemonWithLaunchD):
(main):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:

(TestWebKitAPI::shouldSetupWebPushD): Add a command line argument to skip the "install the daemon" step,

so an engineer can handle that part themselves.

(TestWebKitAPI::setUpTestWebPushD):
(TestWebKitAPI::cleanUpTestWebPushD):

Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r286994 r287009  
     12021-12-13  Brady Eidson  <beidson@apple.com>
     2
     3        Teach webpushtool to register and "host" the daemon.
     4        https://bugs.webkit.org/show_bug.cgi?id=234265
     5
     6        Reviewed by Tim Horton.
     7
     8        * inspector/ConsoleMessage.h: Remove `using JSC::MessageType` because it makes it hard for others
     9          to also have a `MessageType` type.
     10        * inspector/JSGlobalObjectConsoleClient.h:
     11        * runtime/ConsoleTypes.h:
     12
    1132021-12-13  Saam Barati  <sbarati@apple.com>
    214
  • trunk/Source/JavaScriptCore/inspector/ConsoleMessage.h

    r272499 r287009  
    4343class JSGlobalObject;
    4444}
     45
     46using JSC::MessageType;
    4547
    4648namespace Inspector {
  • trunk/Source/JavaScriptCore/inspector/JSGlobalObjectConsoleClient.h

    r262673 r287009  
    2929#include <wtf/Vector.h>
    3030#include <wtf/text/WTFString.h>
     31
     32using JSC::MessageType;
    3133
    3234namespace Inspector {
  • trunk/Source/JavaScriptCore/runtime/ConsoleTypes.h

    r271735 r287009  
    116116
    117117using JSC::MessageSource;
    118 using JSC::MessageType;
    119118using JSC::MessageLevel;
  • trunk/Source/WebCore/ChangeLog

    r287002 r287009  
     12021-12-13  Brady Eidson  <beidson@apple.com>
     2
     3        Teach webpushtool to register and "host" the daemon.
     4        https://bugs.webkit.org/show_bug.cgi?id=234265
     5
     6        Reviewed by Tim Horton.
     7
     8        * page/PageConsoleClient.h:
     9
    1102021-12-13  Commit Queue  <commit-queue@webkit.org>
    211
  • trunk/Source/WebCore/page/PageConsoleClient.h

    r260415 r287009  
    4040class CallFrame;
    4141}
     42
     43using JSC::MessageType;
    4244
    4345namespace WebCore {
  • trunk/Source/WebKit/ChangeLog

    r287002 r287009  
     12021-12-13  Brady Eidson  <beidson@apple.com>
     2
     3        Teach webpushtool to register and "host" the daemon.
     4        https://bugs.webkit.org/show_bug.cgi?id=234265
     5
     6        Reviewed by Tim Horton.
     7
     8        Covered by API tests verifying hosting mode operation.
     9
     10        As various engineers work on various parts of the project, it's become apparent that it's super useful
     11        to have a tool handle the "setting up" of the daemon itself, to avoid launchctl, etc.
     12       
     13        Implement that, as well as a few other niceties found while testing.
     14       
     15        * Configurations/webpushtool.xcconfig:
     16        * Resources/webpushtool.entitlements:
     17       
     18        * Shared/Daemon/DaemonUtilities.mm:
     19        (WebKit::startListeningForMachServiceConnections):
     20       
     21        * webpushd/AppBundleRequest.mm:
     22        (WebPushD::AppBundleRequest::start):
     23       
     24        * webpushd/PushClientConnection.h:
     25        * webpushd/PushClientConnection.mm:
     26        (WebPushD::ClientConnection::setHostAppAuditTokenData):
     27        (WebPushD::ClientConnection::broadcastDebugMessage):
     28
     29        * webpushd/WebPushDaemon.h:
     30        * webpushd/WebPushDaemon.mm:
     31        (WebPushD::Daemon::broadcastAllConnectionIdentities):
     32
     33        * webpushd/webpushtool/WebPushToolConnection.h:
     34        * webpushd/webpushtool/WebPushToolConnection.mm:
     35        (WebPushTool::Connection::connectToService):
     36        (WebPushTool::Connection::connectionDropped):
     37
     38        * webpushd/webpushtool/WebPushToolMain.mm:
     39        (printUsageAndTerminate):
     40        (registerDaemonWithLaunchD):
     41        (main):
     42
    1432021-12-13  Commit Queue  <commit-queue@webkit.org>
    244
  • trunk/Source/WebKit/Configurations/webpushtool.xcconfig

    r286832 r287009  
    3030EXCLUDED_SOURCE_FILE_NAMES[sdk=watch*] = *;
    3131
    32 OTHER_LDFLAGS = -framework Foundation -framework CoreFoundation -framework WebKit -framework JavaScriptCore
     32WK_APPSERVERSUPPORT_LDFLAGS = $(WK_APPSERVERSUPPORT_LDFLAGS_$(WK_PLATFORM_NAME));
     33WK_APPSERVERSUPPORT_LDFLAGS_macosx = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_MACOS_1200));
     34WK_APPSERVERSUPPORT_LDFLAGS_MACOS_SINCE_1200 = -framework AppServerSupport
     35WK_APPSERVERSUPPORT_LDFLAGS_iphoneos = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_IOS_15));
     36WK_APPSERVERSUPPORT_LDFLAGS_iphonesimulator = $(WK_APPSERVERSUPPORT_LDFLAGS$(WK_IOS_15));
     37WK_APPSERVERSUPPORT_LDFLAGS_IOS_SINCE_15 = -framework AppServerSupport
     38
     39OTHER_LDFLAGS = -framework Foundation -framework CoreFoundation -framework WebKit -framework JavaScriptCore $(WK_APPSERVERSUPPORT_LDFLAGS)
    3340LIBRARY_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR);
    3441
  • trunk/Source/WebKit/Resources/webpushtool.entitlements

    r286788 r287009  
    77        <key>com.apple.private.webkit.webpush.inject</key>
    88        <true/>
     9        <key>com.apple.private.xpc.launchd.job-manager</key>
     10        <string>webpushtool</string>
    911</dict>
    1012</plist>
  • trunk/Source/WebKit/Shared/Daemon/DaemonUtilities.mm

    r284823 r287009  
    5555                NSLog(@"Failed to start listening for connections to mach service %s, likely because it is not registered with launchd", serviceName);
    5656#endif
     57                NSLog(@"Removing peer connection %p", peer);
     58                connectionRemoved(peer);
     59                return;
    5760            }
    5861            if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
  • trunk/Source/WebKit/webpushd/AppBundleRequest.mm

    r286579 r287009  
    5454    if (m_connection->useMockBundlesForTesting())
    5555        m_appBundle = MockAppBundleForTesting::create(m_originString, m_connection->hostAppCodeSigningIdentifier(), *this);
    56     else
     56    else {
     57        m_connection->broadcastDebugMessage("Client is trying to initiate app bundle request without having configured mock app bundles for testing. About to crash...");
    5758        RELEASE_ASSERT_NOT_REACHED();
     59    }
    5860
    5961    startInternal();
  • trunk/Source/WebKit/webpushd/PushClientConnection.h

    r286788 r287009  
    2929#include <wtf/Deque.h>
    3030#include <wtf/Forward.h>
     31#include <wtf/Identified.h>
    3132#include <wtf/OSObjectPtr.h>
    3233#include <wtf/RefCounted.h>
     
    4647class AppBundleRequest;
    4748
    48 class ClientConnection : public RefCounted<ClientConnection>, public CanMakeWeakPtr<ClientConnection> {
     49class ClientConnection : public RefCounted<ClientConnection>, public CanMakeWeakPtr<ClientConnection>, public Identified<ClientConnection> {
    4950    WTF_MAKE_FAST_ALLOCATED;
    5051public:
  • trunk/Source/WebKit/webpushd/PushClientConnection.mm

    r286788 r287009  
    7474
    7575    m_hostAppAuditToken = WTFMove(token);
     76    Daemon::singleton().broadcastAllConnectionIdentities();
    7677}
    7778
     
    122123    auto signingIdentifer = hostAppCodeSigningIdentifier();
    123124    if (signingIdentifer.isEmpty())
    124         messageIdentifier = makeString("[(0x", hex(reinterpret_cast<uint64_t>(m_xpcConnection.get()), WTF::HexConversionMode::Lowercase), ")] ");
     125        messageIdentifier = makeString("[(0x", hex(reinterpret_cast<uint64_t>(m_xpcConnection.get()), WTF::HexConversionMode::Lowercase), ") (", String::number(identifier()), " )] ");
    125126    else
    126         messageIdentifier = makeString("[", signingIdentifer, " (0x", hex(reinterpret_cast<uint64_t>(m_xpcConnection.get()), WTF::HexConversionMode::Lowercase), ")] ");
     127        messageIdentifier = makeString("[", signingIdentifer, " (", String::number(identifier()), ")] ");
    127128
    128129    Daemon::singleton().broadcastDebugMessage(JSC::MessageLevel::Info, makeString(messageIdentifier, message));
  • trunk/Source/WebKit/webpushd/WebPushDaemon.h

    r286878 r287009  
    7171
    7272    void broadcastDebugMessage(JSC::MessageLevel, const String&);
     73    void broadcastAllConnectionIdentities();
    7374
    7475private:
  • trunk/Source/WebKit/webpushd/WebPushDaemon.mm

    r286878 r287009  
    186186}
    187187
     188void Daemon::broadcastAllConnectionIdentities()
     189{
     190    broadcastDebugMessage((JSC::MessageLevel)4, "===\nCurrent connections:");
     191    for (auto& iterator : m_connectionMap)
     192        iterator.value->broadcastDebugMessage("");
     193    broadcastDebugMessage((JSC::MessageLevel)4, "===");
     194}
     195
    188196void Daemon::connectionEventHandler(xpc_object_t request)
    189197{
  • trunk/Source/WebKit/webpushd/webpushtool/WebPushToolConnection.h

    r286788 r287009  
    4242
    4343enum class PreferTestService : bool {
     44    No,
    4445    Yes,
    45     No,
    4646};
    4747
    4848enum class Reconnect : bool {
     49    No,
    4950    Yes,
     51};
     52
     53enum class WaitForServiceToExist : bool {
    5054    No,
     55    Yes,
    5156};
    5257
     
    5762    Connection(Action, PreferTestService, Reconnect);
    5863
    59     void connectToService();
     64    void connectToService(WaitForServiceToExist);
    6065
    6166    void setPushMessage(std::unique_ptr<PushMessageForTesting>&& message) { m_pushMessage = WTFMove(message); }
  • trunk/Source/WebKit/webpushd/webpushtool/WebPushToolConnection.mm

    r286788 r287009  
    6767}
    6868
    69 void Connection::connectToService()
     69void Connection::connectToService(WaitForServiceToExist waitForServiceToExist)
    7070{
    7171    if (m_connection)
     
    100100    });
    101101
    102     auto result = maybeConnectToService(m_serviceName);
    103     if (result == MACH_PORT_NULL)
    104         printf("Waiting for service '%s' to be available\n", m_serviceName);
    105 
    106     while (result == MACH_PORT_NULL) {
    107         usleep(1000);
    108         result = maybeConnectToService(m_serviceName);
     102    if (waitForServiceToExist == WaitForServiceToExist::Yes) {
     103        auto result = maybeConnectToService(m_serviceName);
     104        if (result == MACH_PORT_NULL)
     105            printf("Waiting for service '%s' to be available\n", m_serviceName);
     106
     107        while (result == MACH_PORT_NULL) {
     108            usleep(1000);
     109            result = maybeConnectToService(m_serviceName);
     110        }
    109111    }
    110112
     
    185187        callOnMainRunLoop([this, weakThis = WeakPtr { this }] {
    186188            if (weakThis)
    187                 connectToService();
     189                connectToService(WaitForServiceToExist::Yes);
    188190        });
    189191        return;
  • trunk/Source/WebKit/webpushd/webpushtool/WebPushToolMain.mm

    r286788 r287009  
    4444    fprintf(stderr, "  --production\n");
    4545    fprintf(stderr, "    Connects to mach service \"com.apple.webkit.webpushd.service\"\n");
     46#if HAVE(OS_LAUNCHD_JOB)
     47    fprintf(stderr, "  --host\n");
     48    fprintf(stderr, "    Dynamically registers the service with launchd so it is visible to other applications\n");
     49    fprintf(stderr, "    The service name of the registration depends on either the --development or --production option chosen\n");
     50#endif
    4651    fprintf(stderr, "  --streamDebugMessages\n");
    4752    fprintf(stderr, "    Stream debug messages from webpushd\n");
     
    7782}
    7883
     84#if HAVE(OS_LAUNCHD_JOB)
     85static bool registerDaemonWithLaunchD(WebPushTool::PreferTestService preferTestService)
     86{
     87    // For now webpushtool only knows how to host webpushd when they're in the same directory
     88    // e.g. the build directory of a WebKit contributor.
     89    NSString *currentExecutablePath = [[NSBundle mainBundle] executablePath];
     90    NSURL *currentExecutableDirectoryURL = [[NSURL fileURLWithPath:currentExecutablePath isDirectory:NO] URLByDeletingLastPathComponent];
     91    NSURL *daemonExecutablePathURL = [currentExecutableDirectoryURL URLByAppendingPathComponent:@"webpushd"];
     92
     93    if (![[NSFileManager defaultManager] fileExistsAtPath:daemonExecutablePathURL.path]) {
     94        NSLog(@"Daemon executable does not exist at path %@", daemonExecutablePathURL.path);
     95        return false;
     96    }
     97
     98    const char* serviceName = (preferTestService == WebPushTool::PreferTestService::Yes) ? "org.webkit.webpushtestdaemon.service" : "com.apple.webkit.webpushd.service";
     99
     100    auto plist = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
     101    xpc_dictionary_set_string(plist.get(), "_ManagedBy", "webpushtool");
     102    xpc_dictionary_set_string(plist.get(), "Label", "org.webkit.webpushtestdaemon");
     103    xpc_dictionary_set_bool(plist.get(), "LaunchOnlyOnce", true);
     104    xpc_dictionary_set_bool(plist.get(), "RootedSimulatorPath", true);
     105
     106    {
     107        auto environmentVariables = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
     108        xpc_dictionary_set_string(environmentVariables.get(), "DYLD_FRAMEWORK_PATH", currentExecutableDirectoryURL.fileSystemRepresentation);
     109        xpc_dictionary_set_value(plist.get(), "EnvironmentVariables", environmentVariables.get());
     110    }
     111    {
     112        auto machServices = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
     113        xpc_dictionary_set_bool(machServices.get(), serviceName, true);
     114        xpc_dictionary_set_value(plist.get(), "MachServices", machServices.get());
     115    }
     116    {
     117        auto programArguments = adoptNS(xpc_array_create(nullptr, 0));
     118#if PLATFORM(MAC)
     119        xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, daemonExecutablePathURL.fileSystemRepresentation);
     120#else
     121        xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, daemonExecutablePathURL.path.fileSystemRepresentation);
     122#endif
     123        xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, "--machServiceName");
     124        xpc_array_set_string(programArguments.get(), XPC_ARRAY_APPEND, serviceName);
     125        xpc_dictionary_set_value(plist.get(), "ProgramArguments", programArguments.get());
     126    }
     127
     128    auto job = adoptNS([[OSLaunchdJob alloc] initWithPlist:plist.get()]);
     129    NSError *error = nil;
     130    [job submit:&error];
     131
     132    if (error) {
     133        NSLog(@"Error setting up service: %@", error);
     134        return false;
     135    }
     136
     137    return true;
     138}
     139#endif // #if HAVE(OS_LAUNCHD_JOB)
     140
    79141int main(int, const char **)
    80142{
     
    83145    auto preferTestService = WebPushTool::PreferTestService::Yes;
    84146    auto reconnect = WebPushTool::Reconnect::No;
     147    bool host = false;
    85148    std::optional<WebPushTool::Action> action;
    86149    std::unique_ptr<PushMessageForTesting> pushMessage;
     
    102165            else if ([argument isEqualToString:@"--reconnect"])
    103166                reconnect = WebPushTool::Reconnect::Yes;
     167#if HAVE(OS_LAUNCHD_JOB)
     168            else if ([argument isEqualToString:@"--host"])
     169                host = true;
     170#endif
    104171            else if ([argument isEqualToString:@"--push"]) {
    105172                pushMessage = pushMessageFromArguments(enumerator);
     
    116183        printUsageAndTerminate(@"No action provided");
    117184
     185#if HAVE(OS_LAUNCHD_JOB)
     186    if (host && !registerDaemonWithLaunchD(preferTestService))
     187        printUsageAndTerminate(@"Unable to install plist to host the service");
     188#endif
     189
    118190    auto connection = WebPushTool::Connection::create(*action, preferTestService, reconnect);
    119191    if (pushMessage)
    120192        connection->setPushMessage(WTFMove(pushMessage));
    121193
    122     connection->connectToService();
     194    connection->connectToService(host ? WebPushTool::WaitForServiceToExist::No : WebPushTool::WaitForServiceToExist::Yes);
    123195
    124196    CFRunLoopRun();
  • trunk/Tools/ChangeLog

    r287000 r287009  
     12021-12-13  Brady Eidson  <beidson@apple.com>
     2
     3        Teach webpushtool to register and "host" the daemon.
     4        https://bugs.webkit.org/show_bug.cgi?id=234265
     5
     6        Reviewed by Tim Horton.
     7
     8        * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
     9        (TestWebKitAPI::shouldSetupWebPushD): Add a command line argument to skip the "install the daemon" step,
     10          so an engineer can handle that part themselves.
     11        (TestWebKitAPI::setUpTestWebPushD):
     12        (TestWebKitAPI::cleanUpTestWebPushD):
     13
    1142021-12-13  Christopher Reid  <chris.reid@sony.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm

    r286788 r287009  
    126126#endif // HAVE(OS_LAUNCHD_JOB)
    127127
     128static bool shouldSetupWebPushD()
     129{
     130    static bool shouldSetup = true;
     131    static dispatch_once_t onceToken;
     132    dispatch_once(&onceToken, ^{
     133        NSArray<NSString *> *arguments = [[NSProcessInfo processInfo] arguments];
     134        if ([arguments containsObject:@"--no-webpushd"])
     135            shouldSetup = false;
     136    });
     137
     138    return shouldSetup;
     139}
     140
    128141static NSURL *setUpTestWebPushD()
    129142{
     143    if (!shouldSetupWebPushD())
     144        return nil;
     145
    130146    NSFileManager *fileManager = [NSFileManager defaultManager];
    131147    NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"WebPushDaemonTest"] isDirectory:YES];
     
    149165static void cleanUpTestWebPushD(NSURL *tempDir)
    150166{
     167    if (!shouldSetupWebPushD())
     168        return;
     169
    151170    killFirstInstanceOfDaemon(@"webpushd");
    152171
     
    243262
    244263// FIXME: Re-enable this test on Mac once webkit.org/232857 is resolved.
    245 #if PLATFORM(MAC)
     264#if PLATFORM(MAC) && !USE(APPLE_INTERNAL_SDK)
    246265TEST(WebPushD, DISABLED_BasicCommunication)
    247266#else
     
    322341
    323342// FIXME: Re-enable this test on Mac once webkit.org/232857 is resolved.
    324 #if PLATFORM(MAC)
     343#if PLATFORM(MAC) && !USE(APPLE_INTERNAL_SDK)
    325344TEST(WebPushD, DISABLED_PermissionManagement)
    326345#else
     
    455474
    456475// FIXME: Re-enable this test on Mac once webkit.org/232857 is resolved.
    457 #if PLATFORM(MAC)
     476#if PLATFORM(MAC) && !USE(APPLE_INTERNAL_SDK)
    458477TEST(WebPushD, DISABLED_HandleInjectedPush)
    459478#else
Note: See TracChangeset for help on using the changeset viewer.