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

Changeset 286614 in webkit


Ignore:
Timestamp:
Dec 7, 2021, 1:19:42 PM (5 years ago)
Author:
Russell Epstein
Message:

Cherry-pick r286355. rdar://problem/86052131

Add WKWebsiteDataStore configuration option to enable Mock app bundle testing.
https://bugs.webkit.org/show_bug.cgi?id=233679

Reviewed by Tim Horton.

Source/WebKit:

Covered by API tests.

We're about to land actual implementations of app permissions bundles.
But the mock bundles still have a place for testing.
We need a way to switch between Mock and Native.

This patch takes the opportunity to plumb out a WebPushDaemonConnectionConfiguration object
that can easily be augmented in future patches to add new options without messing with messaging directly.

  • NetworkProcess/NetworkSession.h: (WebKit::NetworkSession::webpushdUsesMockBundlesForTesting const):
  • NetworkProcess/NetworkSessionCreationParameters.cpp: (WebKit::NetworkSessionCreationParameters::encode const): (WebKit::NetworkSessionCreationParameters::decode):
  • NetworkProcess/NetworkSessionCreationParameters.h:
  • NetworkProcess/Notifications/NetworkNotificationManager.cpp: (WebKit::NetworkNotificationManager::maybeSendConnectionConfiguration const): (WebKit::NetworkNotificationManager::sendMessage const): (WebKit::NetworkNotificationManager::sendMessageWithReply const): (WebKit::NetworkNotificationManager::maybeSendHostAppAuditToken const): Deleted.
  • NetworkProcess/Notifications/NetworkNotificationManager.h:
  • NetworkProcess/cocoa/NetworkSessionCocoa.h:
  • NetworkProcess/cocoa/NetworkSessionCocoa.mm: (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
  • Shared/WebPushDaemonConnectionConfiguration.h: Copied from Source/WebKit/Shared/WebPushDaemonConstants.h. (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::encode const): (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::decode):
  • Shared/WebPushDaemonConstants.h: (WebKit::WebPushD::messageTypeSendsReply):
  • UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
  • UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm: (-[_WKWebsiteDataStoreConfiguration webpushdUsesMockBundlesForTesting]): (-[_WKWebsiteDataStoreConfiguration setWebpushdUsesMockBundlesForTesting:]):
  • UIProcess/WebsiteData/WebsiteDataStore.cpp: (WebKit::WebsiteDataStore::parameters):
  • UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp: (WebKit::WebsiteDataStoreConfiguration::copy const): (WebKit::WebsiteDataStoreConfiguration::webPushDaemonConnectionConfiguration const):
  • UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h: (WebKit::WebsiteDataStoreConfiguration::webpushdUsesMockBundlesForTesting const): (WebKit::WebsiteDataStoreConfiguration::setWebpushdUsesMockBundlesForTesting):
  • WebKit.xcodeproj/project.pbxproj:
  • webpushd/AppBundleRequest.mm: (WebPushD::AppBundleRequest::AppBundleRequest): (WebPushD::AppBundleRequest::start):
  • webpushd/PushClientConnection.h: (WebPushD::ClientConnection::hasHostAppAuditToken const): (WebPushD::ClientConnection::useMockBundlesForTesting const):
  • webpushd/PushClientConnection.mm: (WebPushD::ClientConnection::updateConnectionConfiguration): (WebPushD::ClientConnection::setHostAppAuditTokenData):
  • webpushd/WebPushDaemon.h:
  • webpushd/WebPushDaemon.mm: (WebPushD::Daemon::decodeAndHandleMessage): (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions): (WebPushD::Daemon::setDebugModeIsEnabled): (WebPushD::Daemon::updateConnectionConfiguration): (WebPushD::Daemon::setHostAppAuditToken): Deleted.

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286355 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-613.1.10-branch
Files:
22 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/safari-613.1.10-branch/Source/WebKit/ChangeLog

    r286613 r286614  
     12021-12-06  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r286355. rdar://problem/86052131
     4
     5    Add WKWebsiteDataStore configuration option to enable Mock app bundle testing.
     6    https://bugs.webkit.org/show_bug.cgi?id=233679
     7   
     8    Reviewed by Tim Horton.
     9   
     10    Source/WebKit:
     11   
     12    Covered by API tests.
     13   
     14    We're about to land actual implementations of app permissions bundles.
     15    But the mock bundles still have a place for testing.
     16    We need a way to switch between Mock and Native.
     17   
     18    This patch takes the opportunity to plumb out a WebPushDaemonConnectionConfiguration object
     19    that can easily be augmented in future patches to add new options without messing with messaging directly.
     20   
     21    * NetworkProcess/NetworkSession.h:
     22    (WebKit::NetworkSession::webpushdUsesMockBundlesForTesting const):
     23   
     24    * NetworkProcess/NetworkSessionCreationParameters.cpp:
     25    (WebKit::NetworkSessionCreationParameters::encode const):
     26    (WebKit::NetworkSessionCreationParameters::decode):
     27    * NetworkProcess/NetworkSessionCreationParameters.h:
     28   
     29    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
     30    (WebKit::NetworkNotificationManager::maybeSendConnectionConfiguration const):
     31    (WebKit::NetworkNotificationManager::sendMessage const):
     32    (WebKit::NetworkNotificationManager::sendMessageWithReply const):
     33    (WebKit::NetworkNotificationManager::maybeSendHostAppAuditToken const): Deleted.
     34    * NetworkProcess/Notifications/NetworkNotificationManager.h:
     35   
     36    * NetworkProcess/cocoa/NetworkSessionCocoa.h:
     37    * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     38    (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
     39   
     40    * Shared/WebPushDaemonConnectionConfiguration.h: Copied from Source/WebKit/Shared/WebPushDaemonConstants.h.
     41    (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::encode const):
     42    (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::decode):
     43   
     44    * Shared/WebPushDaemonConstants.h:
     45    (WebKit::WebPushD::messageTypeSendsReply):
     46   
     47    * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
     48    * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
     49    (-[_WKWebsiteDataStoreConfiguration webpushdUsesMockBundlesForTesting]):
     50    (-[_WKWebsiteDataStoreConfiguration setWebpushdUsesMockBundlesForTesting:]):
     51   
     52    * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     53    (WebKit::WebsiteDataStore::parameters):
     54   
     55    * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
     56    (WebKit::WebsiteDataStoreConfiguration::copy const):
     57    (WebKit::WebsiteDataStoreConfiguration::webPushDaemonConnectionConfiguration const):
     58    * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
     59    (WebKit::WebsiteDataStoreConfiguration::webpushdUsesMockBundlesForTesting const):
     60    (WebKit::WebsiteDataStoreConfiguration::setWebpushdUsesMockBundlesForTesting):
     61   
     62    * WebKit.xcodeproj/project.pbxproj:
     63   
     64    * webpushd/AppBundleRequest.mm:
     65    (WebPushD::AppBundleRequest::AppBundleRequest):
     66    (WebPushD::AppBundleRequest::start):
     67   
     68    * webpushd/PushClientConnection.h:
     69    (WebPushD::ClientConnection::hasHostAppAuditToken const):
     70    (WebPushD::ClientConnection::useMockBundlesForTesting const):
     71    * webpushd/PushClientConnection.mm:
     72    (WebPushD::ClientConnection::updateConnectionConfiguration):
     73    (WebPushD::ClientConnection::setHostAppAuditTokenData):
     74   
     75    * webpushd/WebPushDaemon.h:
     76    * webpushd/WebPushDaemon.mm:
     77    (WebPushD::Daemon::decodeAndHandleMessage):
     78    (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
     79    (WebPushD::Daemon::setDebugModeIsEnabled):
     80    (WebPushD::Daemon::updateConnectionConfiguration):
     81    (WebPushD::Daemon::setHostAppAuditToken): Deleted.
     82   
     83    Tools:
     84   
     85    * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
     86   
     87    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286355 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     88
     89    2021-12-01  Brady Eidson  <beidson@apple.com>
     90
     91            Add WKWebsiteDataStore configuration option to enable Mock app bundle testing.
     92            https://bugs.webkit.org/show_bug.cgi?id=233679
     93
     94            Reviewed by Tim Horton.
     95
     96            Covered by API tests.
     97
     98            We're about to land actual implementations of app permissions bundles.
     99            But the mock bundles still have a place for testing.
     100            We need a way to switch between Mock and Native.
     101
     102            This patch takes the opportunity to plumb out a WebPushDaemonConnectionConfiguration object
     103            that can easily be augmented in future patches to add new options without messing with messaging directly.
     104
     105            * NetworkProcess/NetworkSession.h:
     106            (WebKit::NetworkSession::webpushdUsesMockBundlesForTesting const):
     107
     108            * NetworkProcess/NetworkSessionCreationParameters.cpp:
     109            (WebKit::NetworkSessionCreationParameters::encode const):
     110            (WebKit::NetworkSessionCreationParameters::decode):
     111            * NetworkProcess/NetworkSessionCreationParameters.h:
     112
     113            * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
     114            (WebKit::NetworkNotificationManager::maybeSendConnectionConfiguration const):
     115            (WebKit::NetworkNotificationManager::sendMessage const):
     116            (WebKit::NetworkNotificationManager::sendMessageWithReply const):
     117            (WebKit::NetworkNotificationManager::maybeSendHostAppAuditToken const): Deleted.
     118            * NetworkProcess/Notifications/NetworkNotificationManager.h:
     119
     120            * NetworkProcess/cocoa/NetworkSessionCocoa.h:
     121            * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     122            (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
     123
     124            * Shared/WebPushDaemonConnectionConfiguration.h: Copied from Source/WebKit/Shared/WebPushDaemonConstants.h.
     125            (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::encode const):
     126            (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::decode):
     127
     128            * Shared/WebPushDaemonConstants.h:
     129            (WebKit::WebPushD::messageTypeSendsReply):
     130
     131            * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
     132            * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
     133            (-[_WKWebsiteDataStoreConfiguration webpushdUsesMockBundlesForTesting]):
     134            (-[_WKWebsiteDataStoreConfiguration setWebpushdUsesMockBundlesForTesting:]):
     135
     136            * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     137            (WebKit::WebsiteDataStore::parameters):
     138
     139            * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
     140            (WebKit::WebsiteDataStoreConfiguration::copy const):
     141            (WebKit::WebsiteDataStoreConfiguration::webPushDaemonConnectionConfiguration const):
     142            * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
     143            (WebKit::WebsiteDataStoreConfiguration::webpushdUsesMockBundlesForTesting const):
     144            (WebKit::WebsiteDataStoreConfiguration::setWebpushdUsesMockBundlesForTesting):
     145
     146            * WebKit.xcodeproj/project.pbxproj:
     147
     148            * webpushd/AppBundleRequest.mm:
     149            (WebPushD::AppBundleRequest::AppBundleRequest):
     150            (WebPushD::AppBundleRequest::start):
     151
     152            * webpushd/PushClientConnection.h:
     153            (WebPushD::ClientConnection::hasHostAppAuditToken const):
     154            (WebPushD::ClientConnection::useMockBundlesForTesting const):
     155            * webpushd/PushClientConnection.mm:
     156            (WebPushD::ClientConnection::updateConnectionConfiguration):
     157            (WebPushD::ClientConnection::setHostAppAuditTokenData):
     158
     159            * webpushd/WebPushDaemon.h:
     160            * webpushd/WebPushDaemon.mm:
     161            (WebPushD::Daemon::decodeAndHandleMessage):
     162            (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
     163            (WebPushD::Daemon::setDebugModeIsEnabled):
     164            (WebPushD::Daemon::updateConnectionConfiguration):
     165            (WebPushD::Daemon::setHostAppAuditToken): Deleted.
     166
    11672021-12-06  Russell Epstein  <repstein@apple.com>
    2168
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/NetworkSession.h

    r285121 r286614  
    128128    virtual void clearAppBoundSession() { }
    129129#endif
     130
     131    virtual bool webPushDaemonUsesMockBundlesForTesting() const { return false; }
     132
    130133    void storePrivateClickMeasurement(WebCore::PrivateClickMeasurement&&);
    131134    void handlePrivateClickMeasurementConversion(WebCore::PrivateClickMeasurement::AttributionTriggerData&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest, String&& attributedBundleIdentifier);
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp

    r284591 r286614  
    7575    encoder << deviceManagementRestrictionsEnabled;
    7676    encoder << allLoadsBlockedByDeviceManagementRestrictionsForTesting;
     77    encoder << webPushDaemonConnectionConfiguration;
    7778    encoder << dataConnectionServiceType;
    7879    encoder << fastServerTrustEvaluationEnabled;
     
    234235        return std::nullopt;
    235236
     237    std::optional<WebPushD::WebPushDaemonConnectionConfiguration> webPushDaemonConnectionConfiguration;
     238    decoder >> webPushDaemonConnectionConfiguration;
     239    if (!webPushDaemonConnectionConfiguration)
     240        return std::nullopt;
     241
    236242    std::optional<String> dataConnectionServiceType;
    237243    decoder >> dataConnectionServiceType;
     
    357363        , WTFMove(*deviceManagementRestrictionsEnabled)
    358364        , WTFMove(*allLoadsBlockedByDeviceManagementRestrictionsForTesting)
     365        , WTFMove(*webPushDaemonConnectionConfiguration)
    359366        , WTFMove(*networkCacheDirectory)
    360367        , WTFMove(*networkCacheDirectoryExtensionHandle)
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h

    r284591 r286614  
    2727
    2828#include "ResourceLoadStatisticsParameters.h"
     29#include "WebPushDaemonConnectionConfiguration.h"
    2930#include <WebCore/NetworkStorageSession.h>
    3031#include <pal/SessionID.h>
     
    8788    bool deviceManagementRestrictionsEnabled { false };
    8889    bool allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
     90    WebPushD::WebPushDaemonConnectionConfiguration webPushDaemonConnectionConfiguration;
    8991
    9092    String networkCacheDirectory;
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp

    r286075 r286614  
    3232#include "DaemonEncoder.h"
    3333#include "NetworkSession.h"
     34#include "WebPushDaemonConnectionConfiguration.h"
    3435#include <WebCore/SecurityOriginData.h>
    3536
     
    4445}
    4546
    46 void NetworkNotificationManager::maybeSendHostAppAuditToken() const
    47 {
    48     if (m_sentHostAppAuditToken)
    49         return;
    50     m_sentHostAppAuditToken = true;
     47void NetworkNotificationManager::maybeSendConnectionConfiguration() const
     48{
     49    if (m_sentConnectionConfiguration)
     50        return;
     51    m_sentConnectionConfiguration = true;
     52
     53    WebPushD::WebPushDaemonConnectionConfiguration configuration;
     54    configuration.useMockBundlesForTesting = m_networkSession.webPushDaemonUsesMockBundlesForTesting();
    5155
    5256#if PLATFORM(COCOA)
    53         auto token = m_networkSession.networkProcess().parentProcessConnection()->getAuditToken();
    54         if (!token)
    55             return;
    56 
     57    auto token = m_networkSession.networkProcess().parentProcessConnection()->getAuditToken();
     58    if (token) {
    5759        Vector<uint8_t> auditTokenData;
    5860        auditTokenData.resize(sizeof(*token));
    5961        memcpy(auditTokenData.data(), &(*token), sizeof(*token));
    60 
    61         sendMessage<WebPushD::MessageType::SetHostAppAuditToken>(auditTokenData);
     62        configuration.hostAppAuditTokenData = WTFMove(auditTokenData);
     63    }
    6264#endif
     65
     66    sendMessage<WebPushD::MessageType::UpdateConnectionConfiguration>(configuration);
    6367}
    6468
     
    124128    RELEASE_ASSERT(m_connection);
    125129
    126     maybeSendHostAppAuditToken();
     130    maybeSendConnectionConfiguration();
    127131
    128132    Daemon::Encoder encoder;
     
    188192    RELEASE_ASSERT(m_connection);
    189193
    190     maybeSendHostAppAuditToken();
     194    maybeSendConnectionConfiguration();
    191195
    192196    Daemon::Encoder encoder;
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h

    r286075 r286614  
    6363    void didDestroyNotification(uint64_t notificationID) final;
    6464
    65     void maybeSendHostAppAuditToken() const;
     65    void maybeSendConnectionConfiguration() const;
    6666
    6767    NetworkSession& m_networkSession;
    6868    std::unique_ptr<WebPushD::Connection> m_connection;
    69     mutable bool m_sentHostAppAuditToken { false };
     69    mutable bool m_sentConnectionConfiguration { false };
    7070
    7171    template<WebPushD::MessageType messageType, typename... Args>
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.h

    r285726 r286614  
    122122    bool deviceManagementRestrictionsEnabled() const { return m_deviceManagementRestrictionsEnabled; }
    123123    bool allLoadsBlockedByDeviceManagementRestrictionsForTesting() const { return m_allLoadsBlockedByDeviceManagementRestrictionsForTesting; }
     124    bool webPushDaemonUsesMockBundlesForTesting() const final { return m_webPushDaemonUsesMockBundlesForTesting; }
     125
    124126    DMFWebsitePolicyMonitor *deviceManagementPolicyMonitor();
    125127
     
    181183    bool m_deviceManagementRestrictionsEnabled { false };
    182184    bool m_allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
     185    bool m_webPushDaemonUsesMockBundlesForTesting { false };
    183186    bool m_shouldLogCookieInformation { false };
    184187    bool m_fastServerTrustEvaluationEnabled { false };
  • branches/safari-613.1.10-branch/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r285726 r286614  
    13481348    m_deviceManagementRestrictionsEnabled = parameters.deviceManagementRestrictionsEnabled;
    13491349    m_allLoadsBlockedByDeviceManagementRestrictionsForTesting = parameters.allLoadsBlockedByDeviceManagementRestrictionsForTesting;
     1350    m_webPushDaemonUsesMockBundlesForTesting = parameters.webPushDaemonConnectionConfiguration.useMockBundlesForTesting;
    13501351
    13511352#if ENABLE(APP_BOUND_DOMAINS)
  • branches/safari-613.1.10-branch/Source/WebKit/Shared/WebPushDaemonConnectionConfiguration.h

    r286613 r286614  
    2626#pragma once
    2727
     28#include <optional>
     29#include <wtf/Vector.h>
     30
    2831namespace WebKit::WebPushD {
    2932
    30 constexpr const char* protocolVersionKey = "protocol version";
    31 constexpr uint64_t protocolVersionValue = 1;
    32 constexpr const char* protocolEncodedMessageKey = "encoded message";
     33struct WebPushDaemonConnectionConfiguration {
     34    template<class Encoder> void encode(Encoder&) const;
     35    template<class Decoder> static std::optional<WebPushDaemonConnectionConfiguration> decode(Decoder&);
    3336
    34 constexpr const char* protocolDebugMessageKey { "debug message" };
    35 constexpr const char* protocolDebugMessageLevelKey { "debug message level" };
    36 
    37 constexpr const char* protocolMessageTypeKey { "message type" };
    38 enum class MessageType : uint8_t {
    39     EchoTwice = 1,
    40     RequestSystemNotificationPermission,
    41     DeletePushAndNotificationRegistration,
    42     GetOriginsWithPushAndNotificationPermissions,
    43     SetHostAppAuditToken,
    44     SetDebugModeIsEnabled,
     37    bool useMockBundlesForTesting { false };
     38    std::optional<Vector<uint8_t>> hostAppAuditTokenData;
    4539};
    4640
    47 inline bool messageTypeSendsReply(MessageType messageType)
     41template<class Encoder>
     42void WebPushDaemonConnectionConfiguration::encode(Encoder& encoder) const
    4843{
    49     switch (messageType) {
    50     case MessageType::EchoTwice:
    51     case MessageType::GetOriginsWithPushAndNotificationPermissions:
    52     case MessageType::DeletePushAndNotificationRegistration:
    53     case MessageType::RequestSystemNotificationPermission:
    54         return true;
    55     case MessageType::SetHostAppAuditToken:
    56     case MessageType::SetDebugModeIsEnabled:
    57         return false;
    58     }
    59     ASSERT_NOT_REACHED();
    60     return false;
     44    encoder << useMockBundlesForTesting << hostAppAuditTokenData;
     45}
     46
     47template<class Decoder>
     48std::optional<WebPushDaemonConnectionConfiguration> WebPushDaemonConnectionConfiguration::decode(Decoder& decoder)
     49{
     50    std::optional<bool> useMockBundlesForTesting;
     51    decoder >> useMockBundlesForTesting;
     52    if (!useMockBundlesForTesting)
     53        return std::nullopt;
     54
     55    std::optional<std::optional<Vector<uint8_t>>> hostAppAuditTokenData;
     56    decoder >> hostAppAuditTokenData;
     57    if (!hostAppAuditTokenData)
     58        return std::nullopt;
     59
     60    return { {
     61        WTFMove(*useMockBundlesForTesting),
     62        WTFMove(*hostAppAuditTokenData)
     63    } };
    6164}
    6265
  • branches/safari-613.1.10-branch/Source/WebKit/Shared/WebPushDaemonConstants.h

    r286075 r286614  
    4141    DeletePushAndNotificationRegistration,
    4242    GetOriginsWithPushAndNotificationPermissions,
    43     SetHostAppAuditToken,
    4443    SetDebugModeIsEnabled,
     44    UpdateConnectionConfiguration,
    4545};
    4646
     
    5353    case MessageType::RequestSystemNotificationPermission:
    5454        return true;
    55     case MessageType::SetHostAppAuditToken:
    5655    case MessageType::SetDebugModeIsEnabled:
     56    case MessageType::UpdateConnectionConfiguration:
    5757        return false;
    5858    }
  • branches/safari-613.1.10-branch/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h

    r285746 r286614  
    8787// Testing only.
    8888@property (nonatomic) BOOL allLoadsBlockedByDeviceManagementRestrictionsForTesting WK_API_AVAILABLE(macos(10.15), ios(13.0));
     89@property (nonatomic) BOOL webPushDaemonUsesMockBundlesForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    8990
    9091@end
  • branches/safari-613.1.10-branch/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm

    r284591 r286614  
    562562}
    563563
     564- (BOOL)webPushDaemonUsesMockBundlesForTesting
     565{
     566    return _configuration->webPushDaemonUsesMockBundlesForTesting();
     567}
     568
     569- (void)setWebPushDaemonUsesMockBundlesForTesting:(BOOL)usesMockBundles
     570{
     571    _configuration->setWebPushDaemonUsesMockBundlesForTesting(usesMockBundles);
     572}
     573
    564574- (API::Object&)_apiObject
    565575{
  • branches/safari-613.1.10-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r285267 r286614  
    18591859    networkSessionParameters.deviceManagementRestrictionsEnabled = m_configuration->deviceManagementRestrictionsEnabled();
    18601860    networkSessionParameters.allLoadsBlockedByDeviceManagementRestrictionsForTesting = m_configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting();
     1861    networkSessionParameters.webPushDaemonConnectionConfiguration = m_configuration->webPushDaemonConnectionConfiguration();
    18611862    networkSessionParameters.networkCacheDirectory = WTFMove(networkCacheDirectory);
    18621863    networkSessionParameters.networkCacheDirectoryExtensionHandle = WTFMove(networkCacheDirectoryExtensionHandle);
  • branches/safari-613.1.10-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp

    r284887 r286614  
    2727#include "WebsiteDataStoreConfiguration.h"
    2828
     29#include "WebPushDaemonConnectionConfiguration.h"
    2930#include "WebsiteDataStore.h"
    3031
     
    9192    copy->m_deviceManagementRestrictionsEnabled = this->m_deviceManagementRestrictionsEnabled;
    9293    copy->m_allLoadsBlockedByDeviceManagementRestrictionsForTesting = this->m_allLoadsBlockedByDeviceManagementRestrictionsForTesting;
     94    copy->m_webPushDaemonUsesMockBundlesForTesting = this->m_webPushDaemonUsesMockBundlesForTesting;
    9395    copy->m_boundInterfaceIdentifier = this->m_boundInterfaceIdentifier;
    9496    copy->m_allowsCellularAccess = this->m_allowsCellularAccess;
     
    118120}
    119121
     122WebPushD::WebPushDaemonConnectionConfiguration WebsiteDataStoreConfiguration::webPushDaemonConnectionConfiguration() const
     123{
     124    return { m_webPushDaemonUsesMockBundlesForTesting, { } };
     125}
     126
    120127} // namespace WebKit
  • branches/safari-613.1.10-branch/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h

    r284591 r286614  
    3333namespace WebKit {
    3434
     35namespace WebPushD {
     36struct WebPushDaemonConnectionConfiguration;
     37}
     38
    3539enum class IsPersistent : bool { No, Yes };
    3640enum class WillCopyPathsFromExistingConfiguration : bool { No, Yes };
     
    156160    bool allLoadsBlockedByDeviceManagementRestrictionsForTesting() const { return m_allLoadsBlockedByDeviceManagementRestrictionsForTesting; }
    157161    void setAllLoadsBlockedByDeviceManagementRestrictionsForTesting(bool blocked) { m_allLoadsBlockedByDeviceManagementRestrictionsForTesting = blocked; }
     162
     163    bool webPushDaemonUsesMockBundlesForTesting() const { return m_webPushDaemonUsesMockBundlesForTesting; }
     164    void setWebPushDaemonUsesMockBundlesForTesting(bool usesMockBundles) { m_webPushDaemonUsesMockBundlesForTesting = usesMockBundles; }
     165    WebPushD::WebPushDaemonConnectionConfiguration webPushDaemonConnectionConfiguration() const;
    158166
    159167    const String& dataConnectionServiceType() const { return m_dataConnectionServiceType; }
     
    229237    bool m_deviceManagementRestrictionsEnabled { false };
    230238    bool m_allLoadsBlockedByDeviceManagementRestrictionsForTesting { false };
     239    bool m_webPushDaemonUsesMockBundlesForTesting { false };
    231240    bool m_allowsCellularAccess { true };
    232241    bool m_legacyTLSEnabled { true };
  • branches/safari-613.1.10-branch/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r286613 r286614  
    10201020                517A530F1F47A86200DCDC0A /* WebSWClientConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517A530E1F47A84300DCDC0A /* WebSWClientConnectionMessageReceiver.cpp */; };
    10211021                517A53101F47A86200DCDC0A /* WebSWClientConnectionMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A530D1F47A84300DCDC0A /* WebSWClientConnectionMessages.h */; };
     1022                517B5F2E2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 517B5F2D2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h */; };
     1023                517B5F2F2757382B002DC22D /* WebPushDaemonConnectionConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 517B5F2D2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h */; };
    10221024                517CF0E3163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */; };
    10231025                517CF0E3163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */; };
     
    43184320                517A530D1F47A84300DCDC0A /* WebSWClientConnectionMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebSWClientConnectionMessages.h; path = DerivedSources/WebKit2/WebSWClientConnectionMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
    43194321                517A530E1F47A84300DCDC0A /* WebSWClientConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebSWClientConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/WebSWClientConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
     4322                517B5F2D2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPushDaemonConnectionConfiguration.h; sourceTree = "<group>"; };
    43204323                517CF0E1163A486C00C2950E /* NetworkProcessConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkProcessConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkProcessConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
    43214324                517CF0E1163A486C00C2950F /* CacheStorageEngineConnectionMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheStorageEngineConnectionMessageReceiver.cpp; path = DerivedSources/WebKit2/CacheStorageEngineConnectionMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
     
    71147117                                BC306822125A6B9400E71278 /* WebProcessCreationParameters.h */,
    71157118                                467E43E72243FF6D00B13924 /* WebProcessDataStoreParameters.h */,
     7119                                517B5F2D2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h */,
    71167120                                512CD6992721F04900F7F8EC /* WebPushDaemonConstants.h */,
    71177121                                5C8DD37F1FE4519200F2A556 /* WebsiteAutoplayPolicy.h */,
     
    1236812372                                5C1579FC2717AF5000ED5280 /* DaemonUtilities.h in Headers */,
    1236912373                                5160E956274B887200567388 /* AppBundleRequest.h in Headers */,
     12374                                517B5F2F2757382B002DC22D /* WebPushDaemonConnectionConfiguration.h in Headers */,
    1237012375                                512CD69F2723393A00F7F8EC /* WebPushDaemon.h in Headers */,
    1237112376                                51F7BB77274498BB00C45A72 /* MockAppBundleForTesting.h in Headers */,
     
    1346713472                                5C795D71229F3757003FF1C4 /* WKContextMenuElementInfoPrivate.h in Headers */,
    1346813473                                51A555F6128C6C47009ABCEC /* WKContextMenuItem.h in Headers */,
     13474                                517B5F2E2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h in Headers */,
    1346913475                                51A55601128C6D92009ABCEC /* WKContextMenuItemTypes.h in Headers */,
    1347013476                                A1EA02381DABFF7E0096021F /* WKContextMenuListener.h in Headers */,
  • branches/safari-613.1.10-branch/Source/WebKit/webpushd/AppBundleRequest.mm

    r286613 r286614  
    3434
    3535AppBundleRequest::AppBundleRequest(ClientConnection& connection, const String& originString)
    36     : m_connection(&connection)
     36    : m_connection(connection)
    3737    , m_originString(originString)
    3838{
     
    5050    m_transaction = adoptOSObject(os_transaction_create(transactionDescription()));
    5151
    52     m_appBundle = MockAppBundleForTesting::create(m_originString, m_connection->hostAppCodeSigningIdentifier(), *this);
     52    if (m_connection->useMockBundlesForTesting())
     53        m_appBundle = MockAppBundleForTesting::create(m_originString, m_connection->hostAppCodeSigningIdentifier(), *this);
     54    else
     55        RELEASE_ASSERT_NOT_REACHED();
     56
    5357    startInternal();
    5458}
  • branches/safari-613.1.10-branch/Source/WebKit/webpushd/PushClientConnection.h

    r286613 r286614  
    3535#include <wtf/text/WTFString.h>
    3636
     37namespace WebKit {
     38namespace WebPushD {
     39struct WebPushDaemonConnectionConfiguration;
     40}
     41}
     42using WebKit::WebPushD::WebPushDaemonConnectionConfiguration;
     43
    3744namespace WebPushD {
    3845
     
    4451    static Ref<ClientConnection> create(xpc_connection_t);
    4552
     53    void updateConnectionConfiguration(const WebPushDaemonConnectionConfiguration&);
     54
    4655    bool hasHostAppAuditToken() const { return !!m_hostAppAuditToken; }
    47     void setHostAppAuditTokenData(const Vector<uint8_t>&);
    4856
    4957    const String& hostAppCodeSigningIdentifier();
     
    5260    bool debugModeIsEnabled() const { return m_debugModeEnabled; }
    5361    void setDebugModeIsEnabled(bool);
     62
     63    bool useMockBundlesForTesting() const { return m_useMockBundlesForTesting; }
    5464
    5565    void enqueueAppBundleRequest(std::unique_ptr<AppBundleRequest>&&);
     
    6272
    6373    void maybeStartNextAppBundleRequest();
    64    
     74    void setHostAppAuditTokenData(const Vector<uint8_t>&);
     75
    6576    OSObjectPtr<xpc_connection_t> m_xpcConnection;
    6677
     
    7384
    7485    bool m_debugModeEnabled { false };
     86    bool m_useMockBundlesForTesting { false };
    7587};
    7688
  • branches/safari-613.1.10-branch/Source/WebKit/webpushd/PushClientConnection.mm

    r286613 r286614  
    3030#import "CodeSigning.h"
    3131#import "WebPushDaemon.h"
     32#import "WebPushDaemonConnectionConfiguration.h"
    3233#import <JavaScriptCore/ConsoleTypes.h>
    3334#import <wtf/Vector.h>
     
    4647}
    4748
     49void ClientConnection::updateConnectionConfiguration(const WebPushDaemonConnectionConfiguration& configuration)
     50{
     51    if (configuration.hostAppAuditTokenData)
     52        setHostAppAuditTokenData(*configuration.hostAppAuditTokenData);
     53
     54    m_useMockBundlesForTesting = configuration.useMockBundlesForTesting;
     55}
     56
    4857void ClientConnection::setHostAppAuditTokenData(const Vector<uint8_t>& tokenData)
    4958{
    50     RELEASE_ASSERT(!hasHostAppAuditToken());
    51 
    5259    audit_token_t token;
    5360    if (tokenData.size() != sizeof(token)) {
     
    5764
    5865    memcpy(&token, tokenData.data(), tokenData.size());
     66
     67    if (hasHostAppAuditToken()) {
     68        // Verify the token being set is equivalent to the last one set
     69        audit_token_t& existingAuditToken = *m_hostAppAuditToken;
     70        RELEASE_ASSERT(!memcmp(&existingAuditToken, &token, sizeof(token)));
     71        return;
     72    }
     73
    5974    m_hostAppAuditToken = WTFMove(token);
    6075}
  • branches/safari-613.1.10-branch/Source/WebKit/webpushd/WebPushDaemon.h

    r286613 r286614  
    2727
    2828#include "PushClientConnection.h"
     29#include "WebPushDaemonConnectionConfiguration.h"
    2930#include "WebPushDaemonConstants.h"
    3031#include <wtf/Forward.h>
     
    3940enum class MessageLevel : uint8_t;
    4041}
     42
     43using WebKit::WebPushD::WebPushDaemonConnectionConfiguration;
    4144
    4245namespace WebPushD {
     
    5861    void getOriginsWithPushAndNotificationPermissions(ClientConnection*, CompletionHandler<void(const Vector<String>&)>&& replySender);
    5962    void deletePushAndNotificationRegistration(ClientConnection*, const String& originString, CompletionHandler<void(const String&)>&& replySender);
    60     void setHostAppAuditToken(ClientConnection*, const Vector<uint8_t>&);
    6163    void setDebugModeIsEnabled(ClientConnection*, bool);
     64    void updateConnectionConfiguration(ClientConnection*, const WebPushDaemonConnectionConfiguration&);
    6265
    6366    void broadcastDebugMessage(JSC::MessageLevel, const String&);
  • branches/safari-613.1.10-branch/Source/WebKit/webpushd/WebPushDaemon.mm

    r286613 r286614  
    3333#import "HandleMessage.h"
    3434#import "MockAppBundleRegistry.h"
    35 #import "WebPushDaemonConstants.h"
    3635
    3736#import <wtf/CompletionHandler.h>
     
    7170END
    7271
    73 FUNCTION(setHostAppAuditToken)
    74 ARGUMENTS(Vector<uint8_t>)
    75 END
    76 
    7772FUNCTION(setDebugModeIsEnabled)
    7873ARGUMENTS(bool)
     74END
     75
     76FUNCTION(updateConnectionConfiguration)
     77ARGUMENTS(WebPushDaemonConnectionConfiguration)
    7978END
    8079
     
    226225        handleWebPushDMessageWithReply<MessageInfo::requestSystemNotificationPermission>(clientConnection, encodedMessage, WTFMove(replySender));
    227226        break;
    228     case MessageType::SetHostAppAuditToken:
    229         handleWebPushDMessage<MessageInfo::setHostAppAuditToken>(clientConnection, encodedMessage);
    230         break;
    231227    case MessageType::SetDebugModeIsEnabled:
    232228        handleWebPushDMessage<MessageInfo::setDebugModeIsEnabled>(clientConnection, encodedMessage);
     229        break;
     230    case MessageType::UpdateConnectionConfiguration:
     231        handleWebPushDMessage<MessageInfo::updateConnectionConfiguration>(clientConnection, encodedMessage);
    233232        break;
    234233    }
     
    267266    }
    268267
     268    if (connection->useMockBundlesForTesting()) {
     269        replySender(MockAppBundleRegistry::singleton().getOriginsWithRegistrations(connection->hostAppCodeSigningIdentifier()));
     270        return;
     271    }
     272
    269273    // FIXME: This will need platform-specific implementations for real world bundles once implemented.
    270     replySender(MockAppBundleRegistry::singleton().getOriginsWithRegistrations(connection->hostAppCodeSigningIdentifier()));
     274    replySender({ });
    271275}
    272276
     
    281285}
    282286
    283 void Daemon::setHostAppAuditToken(ClientConnection* clientConnection, const Vector<uint8_t>& tokenData)
    284 {
    285     clientConnection->setHostAppAuditTokenData(tokenData);
    286 }
    287 
    288287void Daemon::setDebugModeIsEnabled(ClientConnection* clientConnection, bool enabled)
    289288{
    290289    clientConnection->setDebugModeIsEnabled(enabled);
     290}
     291
     292void Daemon::updateConnectionConfiguration(ClientConnection* clientConnection, const WebPushDaemonConnectionConfiguration& configuration)
     293{
     294    clientConnection->updateConnectionConfiguration(configuration);
    291295}
    292296
  • branches/safari-613.1.10-branch/Tools/ChangeLog

    r286204 r286614  
     12021-12-06  Russell Epstein  <repstein@apple.com>
     2
     3        Cherry-pick r286355. rdar://problem/86052131
     4
     5    Add WKWebsiteDataStore configuration option to enable Mock app bundle testing.
     6    https://bugs.webkit.org/show_bug.cgi?id=233679
     7   
     8    Reviewed by Tim Horton.
     9   
     10    Source/WebKit:
     11   
     12    Covered by API tests.
     13   
     14    We're about to land actual implementations of app permissions bundles.
     15    But the mock bundles still have a place for testing.
     16    We need a way to switch between Mock and Native.
     17   
     18    This patch takes the opportunity to plumb out a WebPushDaemonConnectionConfiguration object
     19    that can easily be augmented in future patches to add new options without messing with messaging directly.
     20   
     21    * NetworkProcess/NetworkSession.h:
     22    (WebKit::NetworkSession::webpushdUsesMockBundlesForTesting const):
     23   
     24    * NetworkProcess/NetworkSessionCreationParameters.cpp:
     25    (WebKit::NetworkSessionCreationParameters::encode const):
     26    (WebKit::NetworkSessionCreationParameters::decode):
     27    * NetworkProcess/NetworkSessionCreationParameters.h:
     28   
     29    * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
     30    (WebKit::NetworkNotificationManager::maybeSendConnectionConfiguration const):
     31    (WebKit::NetworkNotificationManager::sendMessage const):
     32    (WebKit::NetworkNotificationManager::sendMessageWithReply const):
     33    (WebKit::NetworkNotificationManager::maybeSendHostAppAuditToken const): Deleted.
     34    * NetworkProcess/Notifications/NetworkNotificationManager.h:
     35   
     36    * NetworkProcess/cocoa/NetworkSessionCocoa.h:
     37    * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     38    (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
     39   
     40    * Shared/WebPushDaemonConnectionConfiguration.h: Copied from Source/WebKit/Shared/WebPushDaemonConstants.h.
     41    (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::encode const):
     42    (WebKit::WebPushD::WebPushDaemonConnectionConfiguration::decode):
     43   
     44    * Shared/WebPushDaemonConstants.h:
     45    (WebKit::WebPushD::messageTypeSendsReply):
     46   
     47    * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h:
     48    * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm:
     49    (-[_WKWebsiteDataStoreConfiguration webpushdUsesMockBundlesForTesting]):
     50    (-[_WKWebsiteDataStoreConfiguration setWebpushdUsesMockBundlesForTesting:]):
     51   
     52    * UIProcess/WebsiteData/WebsiteDataStore.cpp:
     53    (WebKit::WebsiteDataStore::parameters):
     54   
     55    * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp:
     56    (WebKit::WebsiteDataStoreConfiguration::copy const):
     57    (WebKit::WebsiteDataStoreConfiguration::webPushDaemonConnectionConfiguration const):
     58    * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h:
     59    (WebKit::WebsiteDataStoreConfiguration::webpushdUsesMockBundlesForTesting const):
     60    (WebKit::WebsiteDataStoreConfiguration::setWebpushdUsesMockBundlesForTesting):
     61   
     62    * WebKit.xcodeproj/project.pbxproj:
     63   
     64    * webpushd/AppBundleRequest.mm:
     65    (WebPushD::AppBundleRequest::AppBundleRequest):
     66    (WebPushD::AppBundleRequest::start):
     67   
     68    * webpushd/PushClientConnection.h:
     69    (WebPushD::ClientConnection::hasHostAppAuditToken const):
     70    (WebPushD::ClientConnection::useMockBundlesForTesting const):
     71    * webpushd/PushClientConnection.mm:
     72    (WebPushD::ClientConnection::updateConnectionConfiguration):
     73    (WebPushD::ClientConnection::setHostAppAuditTokenData):
     74   
     75    * webpushd/WebPushDaemon.h:
     76    * webpushd/WebPushDaemon.mm:
     77    (WebPushD::Daemon::decodeAndHandleMessage):
     78    (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
     79    (WebPushD::Daemon::setDebugModeIsEnabled):
     80    (WebPushD::Daemon::updateConnectionConfiguration):
     81    (WebPushD::Daemon::setHostAppAuditToken): Deleted.
     82   
     83    Tools:
     84   
     85    * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
     86   
     87    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286355 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     88
     89    2021-12-01  Brady Eidson  <beidson@apple.com>
     90
     91            Add WKWebsiteDataStore configuration option to enable Mock app bundle testing.
     92            https://bugs.webkit.org/show_bug.cgi?id=233679
     93
     94            Reviewed by Tim Horton.
     95
     96            * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
     97
    1982021-11-29  Nikolas Zimmermann  <nzimmermann@igalia.com>
    299
  • branches/safari-613.1.10-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm

    r286613 r286614  
    266266    auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);
    267267    dataStoreConfiguration.get().webPushMachServiceName = @"org.webkit.webpushtestdaemon.service";
     268    dataStoreConfiguration.get().webPushDaemonUsesMockBundlesForTesting = YES;
    268269    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);
    269270
Note: See TracChangeset for help on using the changeset viewer.