Changeset 281721 in webkit
- Timestamp:
- Aug 27, 2021, 2:22:36 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 37 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/loader/PrivateClickMeasurement.cpp (modified) (1 diff)
-
Source/WebCore/loader/PrivateClickMeasurement.h (modified) (4 diffs)
-
Source/WebKit/CMakeLists.txt (modified) (1 diff)
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (modified) (27 diffs)
-
Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (modified) (7 diffs)
-
Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp (modified) (5 diffs)
-
Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h (modified) (4 diffs)
-
Source/WebKit/NetworkProcess/DatabaseUtilities.cpp (added)
-
Source/WebKit/NetworkProcess/DatabaseUtilities.h (added)
-
Source/WebKit/NetworkProcess/NetworkProcess.cpp (modified) (6 diffs)
-
Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/NetworkSession.cpp (modified) (6 diffs)
-
Source/WebKit/NetworkProcess/NetworkSession.h (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.h (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.cpp (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.h (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h (added)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp (modified) (12 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h (modified) (2 diffs)
-
Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (modified) (1 diff)
-
Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolver.h (modified) (1 diff)
-
Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp (modified) (1 diff)
-
Source/WebKit/Shared/ResourceLoadStatisticsParameters.h (modified) (4 diffs)
-
Source/WebKit/Sources.txt (modified) (2 diffs)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h (modified) (1 diff)
-
Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (modified) (3 diffs)
-
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h (modified) (2 diffs)
-
Source/WebKit/WebKit.xcodeproj/project.pbxproj (modified) (6 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm (modified) (5 diffs)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/PrivateClickMeasurement.mm (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r281714 r281721 1 2021-08-27 Alex Christensen <achristensen@webkit.org> 2 3 Separate PrivateClickMeasurement database from ResourceLoadStatistics database and add SPI to set its location 4 https://bugs.webkit.org/show_bug.cgi?id=229527 5 6 Reviewed by Kate Cheney. 7 8 * loader/PrivateClickMeasurement.cpp: 9 (WebCore::PrivateClickMeasurement::SourceSecretToken::isolatedCopy const): 10 (WebCore::PrivateClickMeasurement::EphemeralSourceNonce::isolatedCopy const): 11 (WebCore::PrivateClickMeasurement::SourceUnlinkableToken::isolatedCopy const): 12 (WebCore::PrivateClickMeasurement::isolatedCopy const): 13 * loader/PrivateClickMeasurement.h: 14 1 15 2021-08-27 Alan Bujtas <zalan@apple.com> 2 16 -
trunk/Source/WebCore/loader/PrivateClickMeasurement.cpp
r278162 r281721 60 60 } 61 61 62 PrivateClickMeasurement::SourceSecretToken PrivateClickMeasurement::SourceSecretToken::isolatedCopy() const 63 { 64 return { 65 tokenBase64URL.isolatedCopy(), 66 signatureBase64URL.isolatedCopy(), 67 keyIDBase64URL.isolatedCopy(), 68 }; 69 } 70 71 PrivateClickMeasurement::EphemeralSourceNonce PrivateClickMeasurement::EphemeralSourceNonce::isolatedCopy() const 72 { 73 return { nonce.isolatedCopy() }; 74 } 75 76 PrivateClickMeasurement::SourceUnlinkableToken PrivateClickMeasurement::SourceUnlinkableToken::isolatedCopy() const 77 { 78 return { 79 #if PLATFORM(COCOA) 80 blinder, 81 waitingToken, 82 readyToken, 83 #endif 84 valueBase64URL.isolatedCopy() 85 }; 86 } 87 88 PrivateClickMeasurement PrivateClickMeasurement::isolatedCopy() const 89 { 90 PrivateClickMeasurement copy; 91 copy.m_sourceID = m_sourceID; 92 copy.m_sourceSite = m_sourceSite.isolatedCopy(); 93 copy.m_destinationSite = m_destinationSite.isolatedCopy(); 94 copy.m_sourceDescription = m_sourceDescription.isolatedCopy(); 95 copy.m_purchaser = m_purchaser.isolatedCopy(); 96 copy.m_timeOfAdClick = m_timeOfAdClick.isolatedCopy(); 97 copy.m_isEphemeral = m_isEphemeral; 98 copy.m_attributionTriggerData = m_attributionTriggerData; 99 copy.m_timesToSend = m_timesToSend; 100 copy.m_ephemeralSourceNonce = crossThreadCopy(m_ephemeralSourceNonce); 101 copy.m_sourceUnlinkableToken = m_sourceUnlinkableToken.isolatedCopy(); 102 copy.m_sourceSecretToken = crossThreadCopy(m_sourceSecretToken); 103 return copy; 104 } 105 62 106 Expected<PrivateClickMeasurement::AttributionTriggerData, String> PrivateClickMeasurement::parseAttributionRequest(const URL& redirectURL) 63 107 { -
trunk/Source/WebCore/loader/PrivateClickMeasurement.h
r281480 r281721 355 355 String nonce; 356 356 357 EphemeralSourceNonce isolatedCopy() const; 358 357 359 WEBCORE_EXPORT bool isValid() const; 358 360 … … 370 372 String keyIDBase64URL; 371 373 374 SourceSecretToken isolatedCopy() const; 372 375 bool isValid() const; 373 376 }; … … 384 387 template<class Encoder> void encode(Encoder&) const; 385 388 template<class Decoder> static std::optional<PrivateClickMeasurement> decode(Decoder&); 389 390 WEBCORE_EXPORT PrivateClickMeasurement isolatedCopy() const; 386 391 387 392 private: … … 406 411 #endif 407 412 String valueBase64URL; 413 414 SourceUnlinkableToken isolatedCopy() const; 408 415 }; 409 416 -
trunk/Source/WebKit/CMakeLists.txt
r279971 r281721 24 24 "${WEBKIT_DIR}/NetworkProcess/FileAPI" 25 25 "${WEBKIT_DIR}/NetworkProcess/IndexedDB" 26 "${WEBKIT_DIR}/NetworkProcess/PrivateClickMeasurement" 26 27 "${WEBKIT_DIR}/NetworkProcess/ServiceWorker" 27 28 "${WEBKIT_DIR}/NetworkProcess/WebStorage" -
trunk/Source/WebKit/ChangeLog
r281706 r281721 1 2021-08-27 Alex Christensen <achristensen@webkit.org> 2 3 Separate PrivateClickMeasurement database from ResourceLoadStatistics database and add SPI to set its location 4 https://bugs.webkit.org/show_bug.cgi?id=229527 5 6 Reviewed by Kate Cheney. 7 8 This will be used by rdar://80806283 9 10 In order to do this, I moved common code to DatabaseUtilities and moved the PCM logic from ResourceLoadStatisticsDatabaseStore 11 to a new class. It puts the data in a different file in the same directory unless SPI tells it to put it in a different directory. 12 13 The biggest functional change I needed to do was to make a PCMObservedDomains table in the new DB instead of an ObservedDomains table, 14 which contained more information than I needed. I need just an index and a list of domains. 15 16 Another slight implementation change is that instead of checking isEphemeral in WebResourceLoadStatisticsStore, I just pass an empty 17 String to the Store if it's ephemeral, which causes no DB to be created, which causes equivalent behavior. 18 19 I also moved the debug message broadcasting to PrivateClickMeasurementManager::attribute in order to make the Database object not 20 need to know about the NetworkProcess and not need to keep state of whether debug mode is enabled. Database::attributePrivateClickMeasurement 21 now returns a DebugInfo object and PrivateClickMeasurementManager::attribute checks whether debug mode is enabled and broadcasts the messages. 22 23 I added a few calls to PrivateClickMeasurement::isolatedCopy when moving an PrivateClickMeasurement object to another thread. 24 25 I added a CompletionHandler to clearPrivateClickMeasurement and clearPrivateClickMeasurementForRegistrableDomain 26 so that clearing website data doesn't say it's done until it's done. 27 28 An even smaller change is I added a "ForTesting" suffix on some function names of functions that are only used in tests. 29 30 The rest of this patch just moves code from one location to another. 31 32 I still need to implement migrating data from the old DB to the new DB. I'll do that in another patch soon. 33 34 * CMakeLists.txt: 35 * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp: 36 (WebKit::expectedTableAndIndexQueries): 37 (WebKit::ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore): 38 (WebKit::ResourceLoadStatisticsDatabaseStore::openITPDatabase): 39 (WebKit::ResourceLoadStatisticsDatabaseStore::needsUpdatedSchema): 40 (WebKit::insertDistinctValuesInTableStatement): 41 (WebKit::ResourceLoadStatisticsDatabaseStore::openAndUpdateSchemaIfNecessary): 42 (WebKit::ResourceLoadStatisticsDatabaseStore::interruptAllDatabases): 43 (WebKit::ResourceLoadStatisticsDatabaseStore::createUniqueIndices): 44 (WebKit::ResourceLoadStatisticsDatabaseStore::createSchema): 45 (WebKit::ResourceLoadStatisticsDatabaseStore::destroyStatements): 46 (WebKit::ResourceLoadStatisticsDatabaseStore::clearDatabaseContents): 47 (WebKit::expectedUnattributedColumns): Deleted. 48 (WebKit::expectedAttributedColumns): Deleted. 49 (WebKit::ResourceLoadStatisticsDatabaseStore::close): Deleted. 50 (WebKit::ResourceLoadStatisticsDatabaseStore::enableForeignKeys): Deleted. 51 (WebKit::ResourceLoadStatisticsDatabaseStore::needsUpdatedPrivateClickMeasurementSchema): Deleted. 52 (WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable): Deleted. 53 (WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsIfNecessary): Deleted. 54 (WebKit::ResourceLoadStatisticsDatabaseStore::renameColumnInTable): Deleted. 55 (WebKit::ResourceLoadStatisticsDatabaseStore::renameColumnsIfNecessary): Deleted. 56 (WebKit::ResourceLoadStatisticsDatabaseStore::scopedStatement const): Deleted. 57 (WebKit::ResourceLoadStatisticsDatabaseStore::interrupt): Deleted. 58 (WebKit::ResourceLoadStatisticsDatabaseStore::buildPrivateClickMeasurementFromDatabase): Deleted. 59 (WebKit::ResourceLoadStatisticsDatabaseStore::findPrivateClickMeasurement): Deleted. 60 (WebKit::ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement): Deleted. 61 (WebKit::ResourceLoadStatisticsDatabaseStore::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting): Deleted. 62 (WebKit::ResourceLoadStatisticsDatabaseStore::removeUnattributed): Deleted. 63 (WebKit::ResourceLoadStatisticsDatabaseStore::attributePrivateClickMeasurement): Deleted. 64 (WebKit::ResourceLoadStatisticsDatabaseStore::allAttributedPrivateClickMeasurement): Deleted. 65 (WebKit::ResourceLoadStatisticsDatabaseStore::clearPrivateClickMeasurement): Deleted. 66 (WebKit::ResourceLoadStatisticsDatabaseStore::clearExpiredPrivateClickMeasurement): Deleted. 67 (WebKit::ResourceLoadStatisticsDatabaseStore::attributionToString): Deleted. 68 (WebKit::ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString): Deleted. 69 (WebKit::ResourceLoadStatisticsDatabaseStore::earliestTimesToSend): Deleted. 70 (WebKit::ResourceLoadStatisticsDatabaseStore::markReportAsSentToSource): Deleted. 71 (WebKit::ResourceLoadStatisticsDatabaseStore::markReportAsSentToDestination): Deleted. 72 (WebKit::ResourceLoadStatisticsDatabaseStore::clearSentAttribution): Deleted. 73 (WebKit::ResourceLoadStatisticsDatabaseStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting): Deleted. 74 (WebKit::ResourceLoadStatisticsDatabaseStore::beginTransactionIfNecessary): Deleted. 75 * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h: 76 * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h: 77 * NetworkProcess/Classifier/ResourceLoadStatisticsStore.h: 78 * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp: 79 (WebKit::pcmStoreDirectory): 80 (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore): 81 (WebKit::WebResourceLoadStatisticsStore::create): 82 (WebKit::WebResourceLoadStatisticsStore::didDestroyNetworkSession): 83 (WebKit::WebResourceLoadStatisticsStore::suspend): 84 (WebKit::WebResourceLoadStatisticsStore::insertPrivateClickMeasurement): Deleted. 85 (WebKit::WebResourceLoadStatisticsStore::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting): Deleted. 86 (WebKit::WebResourceLoadStatisticsStore::attributePrivateClickMeasurement): Deleted. 87 (WebKit::WebResourceLoadStatisticsStore::allAttributedPrivateClickMeasurement): Deleted. 88 (WebKit::WebResourceLoadStatisticsStore::clearPrivateClickMeasurement): Deleted. 89 (WebKit::WebResourceLoadStatisticsStore::clearPrivateClickMeasurementForRegistrableDomain): Deleted. 90 (WebKit::WebResourceLoadStatisticsStore::clearExpiredPrivateClickMeasurement): Deleted. 91 (WebKit::WebResourceLoadStatisticsStore::privateClickMeasurementToString): Deleted. 92 (WebKit::WebResourceLoadStatisticsStore::clearSentAttribution): Deleted. 93 (WebKit::WebResourceLoadStatisticsStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting): Deleted. 94 * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h: 95 * NetworkProcess/DatabaseUtilities.cpp: Added. 96 (WebKit::DatabaseUtilities::DatabaseUtilities): 97 (WebKit::DatabaseUtilities::~DatabaseUtilities): 98 (WebKit::DatabaseUtilities::scopedStatement const): 99 (WebKit::DatabaseUtilities::beginTransactionIfNecessary): 100 (WebKit::DatabaseUtilities::openDatabaseAndCreateSchemaIfNecessary): 101 (WebKit::DatabaseUtilities::enableForeignKeys): 102 (WebKit::DatabaseUtilities::close): 103 (WebKit::DatabaseUtilities::interrupt): 104 * NetworkProcess/DatabaseUtilities.h: Copied from Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolver.h. 105 * NetworkProcess/NetworkProcess.cpp: 106 (WebKit::NetworkProcess::deleteWebsiteData): 107 (WebKit::NetworkProcess::deleteWebsiteDataForOrigins): 108 (WebKit::NetworkProcess::prepareToSuspend): 109 (WebKit::NetworkProcess::resume): 110 (WebKit::NetworkProcess::clearPrivateClickMeasurement): 111 * NetworkProcess/NetworkResourceLoader.cpp: 112 (WebKit::NetworkResourceLoader::willSendRedirectedRequest): 113 (WebKit::NetworkResourceLoader::continueWillSendRedirectedRequest): 114 * NetworkProcess/NetworkSession.cpp: 115 (WebKit::NetworkSession::NetworkSession): 116 (WebKit::NetworkSession::setResourceLoadStatisticsEnabled): 117 (WebKit::NetworkSession::recreateResourceLoadStatisticStore): 118 (WebKit::NetworkSession::dumpPrivateClickMeasurement): 119 (WebKit::NetworkSession::clearPrivateClickMeasurement): 120 (WebKit::NetworkSession::clearPrivateClickMeasurementForRegistrableDomain): 121 * NetworkProcess/NetworkSession.h: 122 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp: Added. 123 (WebKit::PCM::Database::Database): 124 (WebKit::PCM::Database::~Database): 125 (WebKit::PCM::Database::interruptAllDatabases): 126 (WebKit::PCM::Database::createSchema): 127 (WebKit::PCM::Database::insertPrivateClickMeasurement): 128 (WebKit::PCM::Database::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting): 129 (WebKit::PCM::Database::findPrivateClickMeasurement): 130 (WebKit::PCM::Database::attributePrivateClickMeasurement): 131 (WebKit::PCM::Database::buildPrivateClickMeasurementFromDatabase): 132 (WebKit::PCM::Database::removeUnattributed): 133 (WebKit::PCM::Database::allAttributedPrivateClickMeasurement): 134 (WebKit::PCM::Database::privateClickMeasurementToStringForTesting): 135 (WebKit::PCM::Database::attributionToStringForTesting): 136 (WebKit::PCM::Database::markAttributedPrivateClickMeasurementsAsExpiredForTesting): 137 (WebKit::PCM::Database::clearPrivateClickMeasurement): 138 (WebKit::PCM::Database::clearExpiredPrivateClickMeasurement): 139 (WebKit::PCM::Database::clearSentAttribution): 140 (WebKit::PCM::Database::markReportAsSentToDestination): 141 (WebKit::PCM::Database::markReportAsSentToSource): 142 (WebKit::PCM::Database::earliestTimesToSend): 143 (WebKit::PCM::Database::domainID): 144 (WebKit::PCM::Database::getDomainStringFromDomainID): 145 (WebKit::PCM::Database::ensureDomainID): 146 (WebKit::PCM::Database::destroyStatements): 147 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.h: Added. 148 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.cpp: Copied from Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolver.h. 149 (WebKit::PCM::DebugInfo::isolatedCopy const): 150 (WebKit::PCM::DebugInfo::Message::isolatedCopy const): 151 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.h: Copied from Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolver.h. 152 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp: Added. 153 (WebKit::PCM::sharedWorkQueue): 154 (WebKit::PCM::Store::prepareForProcessToSuspend): 155 (WebKit::PCM::Store::processDidResume): 156 (WebKit::PCM::Store::Store): 157 (WebKit::PCM::Store::postTask): 158 (WebKit::PCM::Store::postTaskReply): 159 (WebKit::PCM::Store::insertPrivateClickMeasurement): 160 (WebKit::PCM::Store::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting): 161 (WebKit::PCM::Store::attributePrivateClickMeasurement): 162 (WebKit::PCM::Store::privateClickMeasurementToStringForTesting): 163 (WebKit::PCM::Store::allAttributedPrivateClickMeasurement): 164 (WebKit::PCM::Store::markAttributedPrivateClickMeasurementsAsExpiredForTesting): 165 (WebKit::PCM::Store::clearPrivateClickMeasurement): 166 (WebKit::PCM::Store::clearPrivateClickMeasurementForRegistrableDomain): 167 (WebKit::PCM::Store::clearExpiredPrivateClickMeasurement): 168 (WebKit::PCM::Store::clearSentAttribution): 169 (WebKit::PCM::Store::close): 170 * NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.h: Added. 171 (WebKit::PCM::Store::create): 172 * NetworkProcess/PrivateClickMeasurementManager.cpp: 173 (WebKit::PrivateClickMeasurementManager::insertPrivateClickMeasurement): 174 (WebKit::PrivateClickMeasurementManager::attribute): 175 (WebKit::PrivateClickMeasurementManager::clearSentAttribution): 176 (WebKit::PrivateClickMeasurementManager::firePendingAttributionRequests): 177 (WebKit::PrivateClickMeasurementManager::clear): 178 (WebKit::PrivateClickMeasurementManager::clearForRegistrableDomain): 179 (WebKit::PrivateClickMeasurementManager::clearExpired): 180 (WebKit::PrivateClickMeasurementManager::toStringForTesting const): 181 (WebKit::PrivateClickMeasurementManager::markAllUnattributedAsExpiredForTesting): 182 (WebKit::PrivateClickMeasurementManager::markAttributedPrivateClickMeasurementsAsExpiredForTesting): 183 (WebKit::PrivateClickMeasurementManager::toString const): Deleted. 184 * NetworkProcess/PrivateClickMeasurementManager.h: 185 * NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp: 186 (WebKit::PrivateClickMeasurementNetworkLoader::~PrivateClickMeasurementNetworkLoader): 187 (WebKit::PrivateClickMeasurementNetworkLoader::cancel): 188 (WebKit::PrivateClickMeasurementNetworkLoader::willSendRedirectedRequest): 189 * NetworkProcess/PrivateClickMeasurementNetworkLoader.h: 190 * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp: 191 * NetworkProcess/webrtc/NetworkRTCResolver.h: 192 * NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp: 193 (WebKit::resolvedName): 194 * Shared/ResourceLoadStatisticsParameters.h: 195 (WebKit::ResourceLoadStatisticsParameters::encode const): 196 (WebKit::ResourceLoadStatisticsParameters::decode): 197 * Sources.txt: 198 * UIProcess/API/Cocoa/WKWebsiteDataStore.mm: 199 (+[WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:]): 200 (+[WKWebsiteDataStore _preventNetworkProcessSuspensionForTesting]): Deleted. 201 * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h: 202 * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h: 203 * UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm: 204 (-[_WKWebsiteDataStoreConfiguration privateClickMeasurementStorageDirectory]): 205 (-[_WKWebsiteDataStoreConfiguration setPrivateClickMeasurementStorageDirectory:]): 206 * UIProcess/Network/NetworkProcessProxy.cpp: 207 (WebKit::NetworkProcessProxy::setSuspensionAllowedForTesting): 208 (WebKit::NetworkProcessProxy::sendPrepareToSuspend): 209 (WebKit::NetworkProcessProxy::preventSuspensionForTesting): Deleted. 210 * UIProcess/Network/NetworkProcessProxy.h: 211 * UIProcess/WebsiteData/WebsiteDataStore.cpp: 212 (WebKit::WebsiteDataStore::resolveDirectoriesIfNecessary): 213 (WebKit::WebsiteDataStore::parameters): 214 * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp: 215 (WebKit::WebsiteDataStoreConfiguration::copy const): 216 * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h: 217 (WebKit::WebsiteDataStoreConfiguration::privateClickMeasurementStorageDirectory const): 218 (WebKit::WebsiteDataStoreConfiguration::setPrivateClickMeasurementStorageDirectory): 219 * WebKit.xcodeproj/project.pbxproj: 220 1 221 2021-08-27 Chris Dumez <cdumez@apple.com> 2 222 -
trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp
r280934 r281721 33 33 #include "PluginProcessManager.h" 34 34 #include "PluginProcessProxy.h" 35 #include "PrivateClickMeasurementManager.h"36 35 #include "ResourceLoadStatisticsMemoryStore.h" 37 36 #include "StorageAccessStatus.h" … … 45 44 #include <WebCore/SQLiteDatabase.h> 46 45 #include <WebCore/SQLiteStatement.h> 46 #include <WebCore/SQLiteStatementAutoResetScope.h> 47 47 #include <WebCore/UserGestureIndicator.h> 48 48 #include <wtf/CallbackAggregator.h> … … 89 89 constexpr auto subresourceUnderTopFrameDomainsQuery = "INSERT OR REPLACE INTO SubresourceUnderTopFrameDomains (subresourceDomainID, lastUpdated, topFrameDomainID) SELECT ?, ?, domainID FROM ObservedDomains WHERE registrableDomain in ( "_s; 90 90 constexpr auto subresourceUniqueRedirectsToQuery = "INSERT OR REPLACE INTO SubresourceUniqueRedirectsTo (subresourceDomainID, lastUpdated, toDomainID) SELECT ?, ?, domainID FROM ObservedDomains WHERE registrableDomain in ( "_s; 91 constexpr auto insertUnattributedPrivateClickMeasurementQuery = "INSERT OR REPLACE INTO UnattributedPrivateClickMeasurement (sourceSiteDomainID, destinationSiteDomainID, "92 "sourceID, timeOfAdClick, token, signature, keyID) VALUES (?, ?, ?, ?, ?, ?, ?)"_s;93 constexpr auto insertAttributedPrivateClickMeasurementQuery = "INSERT OR REPLACE INTO AttributedPrivateClickMeasurement (sourceSiteDomainID, destinationSiteDomainID, "94 "sourceID, attributionTriggerData, priority, timeOfAdClick, earliestTimeToSendToSource, token, signature, keyID, earliestTimeToSendToDestination) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"_s;95 91 96 92 // EXISTS Queries … … 117 113 constexpr auto updateGrandfatheredQuery = "UPDATE ObservedDomains SET grandfathered = ? WHERE registrableDomain = ?"_s; 118 114 constexpr auto updateIsScheduledForAllButCookieDataRemovalQuery = "UPDATE ObservedDomains SET isScheduledForAllButCookieDataRemoval = ? WHERE registrableDomain = ?"_s; 119 constexpr auto setUnattributedPrivateClickMeasurementAsExpiredQuery = "UPDATE UnattributedPrivateClickMeasurement SET timeOfAdClick = -1.0"_s;120 constexpr auto markReportAsSentToSourceQuery = "UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToSource = null WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;121 constexpr auto markReportAsSentToDestinationQuery = "UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToDestination = null WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;122 115 123 116 // SELECT Queries … … 138 131 "UNION ALL SELECT topFrameDomainID FROM SubresourceUnderTopFrameDomains WHERE subresourceDomainID = ?" 139 132 "UNION ALL SELECT toDomainID FROM SubresourceUniqueRedirectsTo WHERE subresourceDomainID = ?"_s; 140 constexpr auto allUnattributedPrivateClickMeasurementAttributionsQuery = "SELECT * FROM UnattributedPrivateClickMeasurement"_s;141 constexpr auto allAttributedPrivateClickMeasurementQuery = "SELECT *, MIN(earliestTimeToSendToSource, earliestTimeToSendToDestination) as minVal "142 "FROM AttributedPrivateClickMeasurement WHERE earliestTimeToSendToSource IS NOT NULL AND earliestTimeToSendToDestination IS NOT NULL "143 "UNION ALL SELECT *, earliestTimeToSendToSource as minVal FROM AttributedPrivateClickMeasurement WHERE earliestTimeToSendToDestination IS NULL "144 "UNION ALL SELECT *, earliestTimeToSendToDestination as minVal FROM AttributedPrivateClickMeasurement WHERE earliestTimeToSendToSource IS NULL ORDER BY minVal"_s;145 constexpr auto findUnattributedQuery = "SELECT * FROM UnattributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;146 constexpr auto findAttributedQuery = "SELECT * FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;147 constexpr auto earliestTimesToSendQuery = "SELECT earliestTimeToSendToSource, earliestTimeToSendToDestination FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;148 133 149 134 // EXISTS for testing queries … … 157 142 // DELETE Queries 158 143 constexpr auto removeAllDataQuery = "DELETE FROM ObservedDomains WHERE domainID = ?"_s; 159 constexpr auto clearUnattributedPrivateClickMeasurementQuery = "DELETE FROM UnattributedPrivateClickMeasurement WHERE sourceSiteDomainID LIKE ? OR destinationSiteDomainID LIKE ?"_s;160 constexpr auto clearAttributedPrivateClickMeasurementQuery = "DELETE FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID LIKE ? OR destinationSiteDomainID LIKE ?"_s;161 constexpr auto clearExpiredPrivateClickMeasurementQuery = "DELETE FROM UnattributedPrivateClickMeasurement WHERE ? > timeOfAdClick"_s;162 constexpr auto removeUnattributedQuery = "DELETE FROM UnattributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s;163 144 164 145 constexpr auto createObservedDomain = "CREATE TABLE ObservedDomains (" … … 241 222 "year INTEGER NOT NULL, month INTEGER NOT NULL, monthDay INTEGER NOT NULL)"_s; 242 223 243 constexpr auto createUnattributedPrivateClickMeasurement = "CREATE TABLE UnattributedPrivateClickMeasurement ("244 "sourceSiteDomainID INTEGER NOT NULL, destinationSiteDomainID INTEGER NOT NULL, sourceID INTEGER NOT NULL, "245 "timeOfAdClick REAL NOT NULL, token TEXT, signature TEXT, keyID TEXT, FOREIGN KEY(sourceSiteDomainID) "246 "REFERENCES ObservedDomains(domainID) ON DELETE CASCADE, FOREIGN KEY(destinationSiteDomainID) REFERENCES "247 "ObservedDomains(domainID) ON DELETE CASCADE)"_s;248 249 constexpr auto createAttributedPrivateClickMeasurement = "CREATE TABLE AttributedPrivateClickMeasurement ("250 "sourceSiteDomainID INTEGER NOT NULL, destinationSiteDomainID INTEGER NOT NULL, sourceID INTEGER NOT NULL, "251 "attributionTriggerData INTEGER NOT NULL, priority INTEGER NOT NULL, timeOfAdClick REAL NOT NULL, "252 "earliestTimeToSendToSource REAL, token TEXT, signature TEXT, keyID TEXT, earliestTimeToSendToDestination REAL, "253 "FOREIGN KEY(sourceSiteDomainID) REFERENCES ObservedDomains(domainID) ON DELETE CASCADE, FOREIGN KEY(destinationSiteDomainID) REFERENCES "254 "ObservedDomains(domainID) ON DELETE CASCADE)"_s;255 256 224 // CREATE UNIQUE INDEX Queries. 257 225 constexpr auto createUniqueIndexStorageAccessUnderTopFrameDomains = "CREATE UNIQUE INDEX IF NOT EXISTS StorageAccessUnderTopFrameDomains_domainID_topLevelDomainID on StorageAccessUnderTopFrameDomains ( domainID, topLevelDomainID )"_s; … … 266 234 constexpr auto createUniqueIndexSubresourceUniqueRedirectsFrom = "CREATE UNIQUE INDEX IF NOT EXISTS SubresourceUniqueRedirectsFrom_subresourceDomainID_fromDomainID on SubresourceUniqueRedirectsFrom ( subresourceDomainID, fromDomainID )"_s; 267 235 constexpr auto createUniqueIndexOperatingDates = "CREATE UNIQUE INDEX IF NOT EXISTS OperatingDates_year_month_monthDay on OperatingDates ( year, month, monthDay )"_s; 268 constexpr auto createUniqueIndexUnattributedPrivateClickMeasurement = "CREATE UNIQUE INDEX IF NOT EXISTS UnattributedPrivateClickMeasurement_sourceSiteDomainID_destinationSiteDomainID on UnattributedPrivateClickMeasurement ( sourceSiteDomainID, destinationSiteDomainID )"_s;269 constexpr auto createUniqueIndexAttributedPrivateClickMeasurement = "CREATE UNIQUE INDEX IF NOT EXISTS AttributedPrivateClickMeasurement_sourceSiteDomainID_destinationSiteDomainID on AttributedPrivateClickMeasurement ( sourceSiteDomainID, destinationSiteDomainID )"_s;270 236 271 237 // Add one to the count of the above index queries to account for the ObservedDomains table, which has an index automatically created by SQLite because of its primary key. 272 const int expectedIndexCount = 14;238 constexpr int expectedIndexCount = 12; 273 239 274 240 static const String ObservedDomainsTableSchemaV1() … … 280 246 { 281 247 return "CREATE TABLE \"ObservedDomains\" (domainID INTEGER PRIMARY KEY, registrableDomain TEXT NOT NULL UNIQUE ON CONFLICT FAIL, lastSeen REAL NOT NULL, hadUserInteraction INTEGER NOT NULL, mostRecentUserInteractionTime REAL NOT NULL, grandfathered INTEGER NOT NULL, isPrevalent INTEGER NOT NULL, isVeryPrevalent INTEGER NOT NULL, dataRecordsRemoved INTEGER NOT NULL,timesAccessedAsFirstPartyDueToUserInteraction INTEGER NOT NULL, timesAccessedAsFirstPartyDueToStorageAccessAPI INTEGER NOT NULL,isScheduledForAllButCookieDataRemoval INTEGER NOT NULL)"_s; 282 }283 284 static const ExpectedColumns& expectedUnattributedColumns()285 {286 static const auto columns = makeNeverDestroyed(Vector<String> { "sourceSiteDomainID"_s, "destinationSiteDomainID"_s, "sourceID"_s, "timeOfAdClick"_s, "token"_s, "signature"_s, "keyID"_s });287 return columns.get();288 }289 290 static const ExpectedColumns& expectedAttributedColumns()291 {292 static const auto columns = makeNeverDestroyed(Vector<String> { "sourceSiteDomainID"_s, "destinationSiteDomainID"_s, "sourceID"_s, "attributionTriggerData"_s, "priority"_s, "timeOfAdClick"_s, "earliestTimeToSendToSource"_s, "token"_s, "signature"_s, "keyID"_s, "earliestTimeToSendToDestination"_s });293 return columns.get();294 248 } 295 249 … … 320 274 { "SubresourceUniqueRedirectsFrom"_s, std::make_pair<String, std::optional<String>>(createSubresourceUniqueRedirectsFrom, stripIndexQueryToMatchStoredValue(createUniqueIndexSubresourceUniqueRedirectsFrom)) }, 321 275 { "OperatingDates"_s, std::make_pair<String, std::optional<String>>(createOperatingDates, stripIndexQueryToMatchStoredValue(createUniqueIndexOperatingDates)) }, 322 { "UnattributedPrivateClickMeasurement"_s, std::make_pair<String, std::optional<String>>(createUnattributedPrivateClickMeasurement, stripIndexQueryToMatchStoredValue(createUniqueIndexUnattributedPrivateClickMeasurement)) },323 { "AttributedPrivateClickMeasurement"_s, std::make_pair<String, std::optional<String>>(createAttributedPrivateClickMeasurement, stripIndexQueryToMatchStoredValue(createUniqueIndexAttributedPrivateClickMeasurement)) }324 276 }); 325 277 … … 340 292 } 341 293 342 HashSet<ResourceLoadStatisticsDatabaseStore*>& ResourceLoadStatisticsDatabaseStore::allStores()294 static HashSet<ResourceLoadStatisticsDatabaseStore*>& allStores() 343 295 { 344 296 ASSERT(!RunLoop::isMain()); … … 350 302 ResourceLoadStatisticsDatabaseStore::ResourceLoadStatisticsDatabaseStore(WebResourceLoadStatisticsStore& store, SuspendableWorkQueue& workQueue, ShouldIncludeLocalhost shouldIncludeLocalhost, const String& storageDirectoryPath, PAL::SessionID sessionID) 351 303 : ResourceLoadStatisticsStore(store, workQueue, shouldIncludeLocalhost) 352 , m_storageDirectoryPath(FileSystem::pathByAppendingComponent(storageDirectoryPath, "observations.db"_s)) 353 , m_transaction(m_database) 304 , DatabaseUtilities(FileSystem::pathByAppendingComponent(storageDirectoryPath, "observations.db"_s)) 354 305 , m_sessionID(sessionID) 355 306 { … … 358 309 openAndUpdateSchemaIfNecessary(); 359 310 enableForeignKeys(); 360 361 // Since we are using a workerQueue, the sequential dispatch blocks may be called by different threads.362 m_database.disableThreadingChecks();363 311 364 312 if (!m_database.turnOnIncrementalAutoVacuum()) … … 375 323 } 376 324 377 void ResourceLoadStatisticsDatabaseStore::close()378 {379 destroyStatements();380 if (m_database.isOpen())381 m_database.close();382 }383 384 325 void ResourceLoadStatisticsDatabaseStore::openITPDatabase() 385 326 { 386 if (!FileSystem::fileExists(m_storageDirectoryPath)) { 387 if (!FileSystem::makeAllDirectories(FileSystem::parentPath(m_storageDirectoryPath))) { 388 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::open failed, error message: Failed to create directory database path: %" PUBLIC_LOG_STRING, this, m_storageDirectoryPath.utf8().data()); 389 return; 390 } 391 m_isNewResourceLoadStatisticsDatabaseFile = true; 392 } else 393 m_isNewResourceLoadStatisticsDatabaseFile = false; 394 395 if (!m_database.open(m_storageDirectoryPath)) { 396 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::open failed, error message: %" PUBLIC_LOG_STRING ", database path: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg(), m_storageDirectoryPath.utf8().data()); 397 ASSERT_NOT_REACHED(); 398 } 399 400 auto setBusyTimeout = m_database.prepareStatement("PRAGMA busy_timeout = 5000"_s); 401 if (!setBusyTimeout || setBusyTimeout->step() != SQLITE_ROW) { 402 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::setBusyTimeout failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg()); 403 ASSERT_NOT_REACHED(); 404 return; 405 } 406 407 if (m_isNewResourceLoadStatisticsDatabaseFile) { 408 if (!createSchema()) { 409 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::createSchema failed, error message: %" PUBLIC_LOG_STRING ", database path: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg(), m_storageDirectoryPath.utf8().data()); 410 ASSERT_NOT_REACHED(); 411 return; 412 } 413 } 327 m_isNewResourceLoadStatisticsDatabaseFile = openDatabaseAndCreateSchemaIfNecessary() == CreatedNewFile::Yes; 414 328 } 415 329 … … 440 354 } 441 355 442 void ResourceLoadStatisticsDatabaseStore::enableForeignKeys()443 {444 auto enableForeignKeys = m_database.prepareStatement("PRAGMA foreign_keys = ON"_s);445 if (!enableForeignKeys || enableForeignKeys->step() != SQLITE_DONE) {446 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::enableForeignKeys failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());447 ASSERT_NOT_REACHED();448 return;449 }450 }451 452 356 TableAndIndexPair ResourceLoadStatisticsDatabaseStore::currentTableAndIndexQueries(const String& tableName) 453 357 { … … 496 400 } 497 401 498 bool ResourceLoadStatisticsDatabaseStore::needsUpdatedPrivateClickMeasurementSchema()499 {500 auto currentSchema = currentTableAndIndexQueries("AttributedPrivateClickMeasurement"_s).first;501 502 if (!currentSchema.isEmpty() && currentSchema != createAttributedPrivateClickMeasurement)503 return true;504 505 return false;506 }507 508 402 bool ResourceLoadStatisticsDatabaseStore::missingUniqueIndices() 509 403 { … … 538 432 // There are 3 cases where we expect potential schema changes due to upgrades. 539 433 // All other tables should be up-to-date, so we should ASSERT that they are correct. 540 if (missingReferenceToObservedDomains() || needsUpdatedPrivateClickMeasurementSchema() ||missingUniqueIndices())434 if (missingReferenceToObservedDomains() || missingUniqueIndices()) 541 435 return true; 542 436 … … 562 456 if (table == "TopFrameLinkDecorationsFrom") 563 457 return database.prepareStatement("INSERT INTO TopFrameLinkDecorationsFrom SELECT toDomainID, MAX(lastUpdated), fromDomainID FROM _TopFrameLinkDecorationsFrom GROUP BY toDomainID, fromDomainID"_s); 564 565 if (table == "UnattributedPrivateClickMeasurement")566 return database.prepareStatement("INSERT INTO UnattributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, MAX(timeOfAdClick), token, signature, keyID FROM _UnattributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID"_s);567 568 if (table == "AttributedPrivateClickMeasurement")569 return database.prepareStatement("INSERT INTO AttributedPrivateClickMeasurement SELECT sourceSiteDomainID, destinationSiteDomainID, sourceID, attributionTriggerData, priority, MAX(timeOfAdClick), earliestTimeToSendToSource, token, signature, keyID, earliestTimeToSendToDestination FROM _AttributedPrivateClickMeasurement GROUP BY sourceSiteDomainID, destinationSiteDomainID"_s);570 458 571 459 return database.prepareStatementSlow(makeString("INSERT INTO ", table, " SELECT DISTINCT * FROM _", table)); … … 634 522 635 523 return columns; 636 }637 638 void ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable(String&& tableName, const ExistingColumns& existingColumns, const ExpectedColumns& expectedColumns)639 {640 ASSERT(existingColumns.size() <= expectedColumns.size());641 642 auto transaction = beginTransactionIfNecessary();643 644 for (auto& column : expectedColumns) {645 if (existingColumns.contains(column))646 continue;647 648 auto statement = m_database.prepareStatementSlow(makeString("ALTER TABLE ", tableName, " ADD COLUMN ", column));649 if (!statement) {650 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable Unable to prepare statement to add missing columns to table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());651 ASSERT_NOT_REACHED();652 return;653 }654 if (statement->step() != SQLITE_DONE) {655 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable error executing statement to add missing columns to table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());656 ASSERT_NOT_REACHED();657 return;658 }659 statement->reset();660 }661 }662 663 void ResourceLoadStatisticsDatabaseStore::addMissingColumnsIfNecessary()664 {665 const auto unattributedTableName = "UnattributedPrivateClickMeasurement"_s;666 const auto attributedTableName = "AttributedPrivateClickMeasurement"_s;667 668 addMissingColumnsToTable(unattributedTableName, columnsForTable(unattributedTableName), expectedUnattributedColumns());669 addMissingColumnsToTable(attributedTableName, columnsForTable(attributedTableName), expectedAttributedColumns());670 }671 672 void ResourceLoadStatisticsDatabaseStore::renameColumnInTable(String&& tableName, ExistingColumnName&& existingColumnName, ExpectedColumnName&& expectedColumnName)673 {674 auto statement = m_database.prepareStatementSlow(makeString("ALTER TABLE ", tableName, " RENAME COLUMN ", existingColumnName, " TO ", expectedColumnName));675 if (!statement) {676 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable Unable to prepare statement to rename column in table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());677 ASSERT_NOT_REACHED();678 return;679 }680 if (statement->step() != SQLITE_DONE) {681 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable error executing statement to rename column in table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());682 ASSERT_NOT_REACHED();683 return;684 }685 }686 687 void ResourceLoadStatisticsDatabaseStore::renameColumnsIfNecessary()688 {689 // Attributed Private Click Measurement case.690 const auto attributedTableName = "AttributedPrivateClickMeasurement"_s;691 const auto oldEarliestTimeToSendColumn = "earliestTimeToSend"_s;692 const auto newEarliestTimeToSendColumn = "earliestTimeToSendToSource"_s;693 const auto oldAttributionDestinationColumn = "attributeOnSiteDomainID"_s;694 const auto newAttributionDestinationColumn = "destinationSiteDomainID"_s;695 const auto foundAttributedTableColumns = columnsForTable(attributedTableName);696 697 if (foundAttributedTableColumns.contains(oldEarliestTimeToSendColumn))698 renameColumnInTable(attributedTableName, oldEarliestTimeToSendColumn, newEarliestTimeToSendColumn);699 700 if (foundAttributedTableColumns.contains(oldAttributionDestinationColumn))701 renameColumnInTable(attributedTableName, oldAttributionDestinationColumn, newAttributionDestinationColumn);702 703 // Unattributed Private Click Measurement case.704 auto unattributedTableName = "UnattributedPrivateClickMeasurement"_s;705 auto foundUnattributedTableColumns = columnsForTable(unattributedTableName);706 707 if (foundUnattributedTableColumns.contains(oldAttributionDestinationColumn))708 renameColumnInTable(unattributedTableName, oldAttributionDestinationColumn, newAttributionDestinationColumn);709 524 } 710 525 … … 749 564 LOG_ERROR("Error executing statement to fetch schema for the Observed Domains table."); 750 565 close(); 751 FileSystem::deleteFile(m_storage DirectoryPath);566 FileSystem::deleteFile(m_storageFilePath); 752 567 openITPDatabase(); 753 568 return; … … 763 578 if (currentSchema != ObservedDomainsTableSchemaV1() && currentSchema != ObservedDomainsTableSchemaV1Alternate()) { 764 579 close(); 765 FileSystem::deleteFile(m_storage DirectoryPath);580 FileSystem::deleteFile(m_storageFilePath); 766 581 openITPDatabase(); 767 582 return; … … 769 584 770 585 // Renaming and adding columns should be done before migrating to avoid mismatched or missing columns. 771 renameColumnsIfNecessary();772 addMissingColumnsIfNecessary();773 586 migrateDataToNewTablesIfNecessary(); 774 587 } 775 588 776 SQLiteStatementAutoResetScope ResourceLoadStatisticsDatabaseStore::scopedStatement(std::unique_ptr<WebCore::SQLiteStatement>& statement, ASCIILiteral query, const String& logString) const 777 { 778 if (!statement) { 779 auto statementOrError = m_database.prepareHeapStatement(query); 780 if (!statementOrError) { 781 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::%s failed to prepare statement, error message: %" PUBLIC_LOG_STRING, this, logString.ascii().data(), m_database.lastErrorMsg()); 782 ASSERT_NOT_REACHED(); 783 return SQLiteStatementAutoResetScope { }; 784 } 785 statement = statementOrError.value().moveToUniquePtr(); 786 ASSERT(m_database.isOpen()); 787 } 788 return SQLiteStatementAutoResetScope { statement.get() }; 789 } 790 791 void ResourceLoadStatisticsDatabaseStore::interrupt() 792 { 793 if (m_database.isOpen()) 794 m_database.interrupt(); 589 void ResourceLoadStatisticsDatabaseStore::interruptAllDatabases() 590 { 591 ASSERT(!RunLoop::isMain()); 592 for (auto store : allStores()) 593 store->interrupt(); 795 594 } 796 595 … … 822 621 || !m_database.executeCommand(createUniqueIndexSubresourceUniqueRedirectsFrom) 823 622 || !m_database.executeCommand(createUniqueIndexSubresourceUnderTopFrameDomains) 824 || !m_database.executeCommand(createUniqueIndexOperatingDates) 825 || !m_database.executeCommand(createUniqueIndexUnattributedPrivateClickMeasurement) 826 || !m_database.executeCommand(createUniqueIndexAttributedPrivateClickMeasurement)) { 623 || !m_database.executeCommand(createUniqueIndexOperatingDates)) { 827 624 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::createUniqueIndices failed to execute, error message: %" PUBLIC_LOG_STRING, this, m_database.lastErrorMsg()); 828 625 return false; … … 897 694 if (!m_database.executeCommand(createOperatingDates)) { 898 695 LOG_ERROR("Could not create OperatingDates table in database (%i) - %s", m_database.lastError(), m_database.lastErrorMsg()); 899 return false;900 }901 902 if (!m_database.executeCommand(createUnattributedPrivateClickMeasurement)) {903 LOG_ERROR("Could not create UnattributedPrivateClickMeasurement table in database (%i) - %s", m_database.lastError(), m_database.lastErrorMsg());904 return false;905 }906 907 if (!m_database.executeCommand(createAttributedPrivateClickMeasurement)) {908 LOG_ERROR("Could not create AttributedPrivateClickMeasurement table in database (%i) - %s", m_database.lastError(), m_database.lastErrorMsg());909 696 return false; 910 697 } … … 957 744 m_observedDomainsExistsStatement = nullptr; 958 745 m_removeAllDataStatement = nullptr; 959 m_insertUnattributedPrivateClickMeasurementStatement = nullptr;960 m_insertAttributedPrivateClickMeasurementStatement = nullptr;961 m_setUnattributedPrivateClickMeasurementAsExpiredStatement = nullptr;962 m_clearUnattributedPrivateClickMeasurementStatement = nullptr;963 m_clearAttributedPrivateClickMeasurementStatement = nullptr;964 m_clearExpiredPrivateClickMeasurementStatement = nullptr;965 m_allUnattributedPrivateClickMeasurementAttributionsStatement = nullptr;966 m_allAttributedPrivateClickMeasurementStatement = nullptr;967 m_findUnattributedStatement = nullptr;968 m_findAttributedStatement = nullptr;969 m_updateAttributionsEarliestTimeToSendStatement = nullptr;970 m_removeUnattributedStatement = nullptr;971 m_markReportAsSentToSourceStatement = nullptr;972 m_markReportAsSentToDestinationStatement = nullptr;973 m_earliestTimesToSendStatement = nullptr;974 746 } 975 747 … … 2288 2060 2289 2061 if (!createSchema()) { 2290 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::clearDatabaseContents failed, error message: %" PRIVATE_LOG_STRING ", database path: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg(), m_storage DirectoryPath.utf8().data());2062 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::clearDatabaseContents failed, error message: %" PRIVATE_LOG_STRING ", database path: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg(), m_storageFilePath.utf8().data()); 2291 2063 ASSERT_NOT_REACHED(); 2292 2064 return; … … 3156 2928 } 3157 2929 3158 PrivateClickMeasurement ResourceLoadStatisticsDatabaseStore::buildPrivateClickMeasurementFromDatabase(WebCore::SQLiteStatement* statement, PrivateClickMeasurementAttributionType attributionType)3159 {3160 auto sourceSiteDomain = getDomainStringFromDomainID(statement->columnInt(0));3161 auto destinationSiteDomain = getDomainStringFromDomainID(statement->columnInt(1));3162 auto sourceID = statement->columnInt(2);3163 auto timeOfAdClick = attributionType == PrivateClickMeasurementAttributionType::Attributed ? statement->columnDouble(5) : statement->columnDouble(3);3164 auto token = attributionType == PrivateClickMeasurementAttributionType::Attributed ? statement->columnText(7) : statement->columnText(4);3165 auto signature = attributionType == PrivateClickMeasurementAttributionType::Attributed ? statement->columnText(8) : statement->columnText(5);3166 auto keyID = attributionType == PrivateClickMeasurementAttributionType::Attributed ? statement->columnText(9) : statement->columnText(6);3167 3168 PrivateClickMeasurement attribution(WebCore::PrivateClickMeasurement::SourceID(sourceID), WebCore::PrivateClickMeasurement::SourceSite(RegistrableDomain::uncheckedCreateFromRegistrableDomainString(sourceSiteDomain)), WebCore::PrivateClickMeasurement::AttributionDestinationSite(RegistrableDomain::uncheckedCreateFromRegistrableDomainString(destinationSiteDomain)), { }, { }, WallTime::fromRawSeconds(timeOfAdClick));3169 3170 if (attributionType == PrivateClickMeasurementAttributionType::Attributed) {3171 auto attributionTriggerData = statement->columnInt(3);3172 auto priority = statement->columnInt(4);3173 auto sourceEarliestTimeToSendValue = statement->columnDouble(6);3174 auto destinationEarliestTimeToSendValue = statement->columnDouble(10);3175 3176 if (attributionTriggerData != -1)3177 attribution.setAttribution(WebCore::PrivateClickMeasurement::AttributionTriggerData { static_cast<uint32_t>(attributionTriggerData), WebCore::PrivateClickMeasurement::Priority(priority) });3178 3179 std::optional<WallTime> sourceEarliestTimeToSend;3180 std::optional<WallTime> destinationEarliestTimeToSend;3181 3182 // A value of 0.0 indicates that the report has been sent to the respective site.3183 if (sourceEarliestTimeToSendValue > 0.0)3184 sourceEarliestTimeToSend = WallTime::fromRawSeconds(sourceEarliestTimeToSendValue);3185 3186 if (destinationEarliestTimeToSendValue > 0.0)3187 destinationEarliestTimeToSend = WallTime::fromRawSeconds(destinationEarliestTimeToSendValue);3188 3189 attribution.setTimesToSend({ sourceEarliestTimeToSend, destinationEarliestTimeToSend });3190 }3191 3192 attribution.setSourceSecretToken({ token, signature, keyID });3193 3194 return attribution;3195 }3196 3197 std::pair<std::optional<UnattributedPrivateClickMeasurement>, std::optional<AttributedPrivateClickMeasurement>> ResourceLoadStatisticsDatabaseStore::findPrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite& sourceSite, const WebCore::PrivateClickMeasurement::AttributionDestinationSite& destinationSite)3198 {3199 auto sourceSiteDomainID = domainID(sourceSite.registrableDomain);3200 auto destinationSiteDomainID = domainID(destinationSite.registrableDomain);3201 3202 if (!sourceSiteDomainID || !destinationSiteDomainID)3203 return std::make_pair(std::nullopt, std::nullopt);3204 3205 auto findUnattributedScopedStatement = this->scopedStatement(m_findUnattributedStatement, findUnattributedQuery, "findPrivateClickMeasurement"_s);3206 if (!findUnattributedScopedStatement3207 || findUnattributedScopedStatement->bindInt(1, *sourceSiteDomainID) != SQLITE_OK3208 || findUnattributedScopedStatement->bindInt(2, *destinationSiteDomainID) != SQLITE_OK) {3209 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::findPrivateClickMeasurement findUnattributedQuery, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3210 ASSERT_NOT_REACHED();3211 }3212 3213 auto findAttributedScopedStatement = this->scopedStatement(m_findAttributedStatement, findAttributedQuery, "findPrivateClickMeasurement"_s);3214 if (!findAttributedScopedStatement3215 || findAttributedScopedStatement->bindInt(1, *sourceSiteDomainID) != SQLITE_OK3216 || findAttributedScopedStatement->bindInt(2, *destinationSiteDomainID) != SQLITE_OK) {3217 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::findPrivateClickMeasurement findAttributedQuery, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3218 ASSERT_NOT_REACHED();3219 }3220 3221 std::optional<UnattributedPrivateClickMeasurement> unattributedPrivateClickMeasurement;3222 if (findUnattributedScopedStatement->step() == SQLITE_ROW)3223 unattributedPrivateClickMeasurement = buildPrivateClickMeasurementFromDatabase(findUnattributedScopedStatement.get(), PrivateClickMeasurementAttributionType::Unattributed);3224 3225 std::optional<AttributedPrivateClickMeasurement> attributedPrivateClickMeasurement;3226 if (findAttributedScopedStatement->step() == SQLITE_ROW)3227 attributedPrivateClickMeasurement = buildPrivateClickMeasurementFromDatabase(findAttributedScopedStatement.get(), PrivateClickMeasurementAttributionType::Attributed);3228 3229 return std::make_pair(unattributedPrivateClickMeasurement, attributedPrivateClickMeasurement);3230 }3231 3232 void ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement(PrivateClickMeasurement&& attribution, PrivateClickMeasurementAttributionType attributionType)3233 {3234 auto transactionScope = beginTransactionIfNecessary();3235 3236 auto sourceData = ensureResourceStatisticsForRegistrableDomain(attribution.sourceSite().registrableDomain);3237 auto attributionDestinationData = ensureResourceStatisticsForRegistrableDomain(attribution.destinationSite().registrableDomain);3238 3239 if (!sourceData.second || !attributionDestinationData.second)3240 return;3241 3242 auto& sourceUnlinkableToken = attribution.sourceUnlinkableToken();3243 if (attributionType == PrivateClickMeasurementAttributionType::Attributed) {3244 auto attributionTriggerData = attribution.attributionTriggerData() ? attribution.attributionTriggerData().value().data : -1;3245 auto priority = attribution.attributionTriggerData() ? attribution.attributionTriggerData().value().priority : -1;3246 auto sourceEarliestTimeToSend = attribution.timesToSend().sourceEarliestTimeToSend ? attribution.timesToSend().sourceEarliestTimeToSend.value().secondsSinceEpoch().value() : -1;3247 auto destinationEarliestTimeToSend = attribution.timesToSend().destinationEarliestTimeToSend ? attribution.timesToSend().destinationEarliestTimeToSend.value().secondsSinceEpoch().value() : -1;3248 3249 // We should never be inserting an attributed private click measurement value into the database without valid report times.3250 ASSERT(sourceEarliestTimeToSend != -1 && destinationEarliestTimeToSend != -1);3251 3252 auto statement = m_database.prepareStatement(insertAttributedPrivateClickMeasurementQuery);3253 if (!statement3254 || statement->bindInt(1, *sourceData.second) != SQLITE_OK3255 || statement->bindInt(2, *attributionDestinationData.second) != SQLITE_OK3256 || statement->bindInt(3, attribution.sourceID().id) != SQLITE_OK3257 || statement->bindInt(4, attributionTriggerData) != SQLITE_OK3258 || statement->bindInt(5, priority) != SQLITE_OK3259 || statement->bindDouble(6, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK3260 || statement->bindDouble(7, sourceEarliestTimeToSend) != SQLITE_OK3261 || statement->bindText(8, sourceUnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK3262 || statement->bindText(9, sourceUnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK3263 || statement->bindText(10, sourceUnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK3264 || statement->bindDouble(11, destinationEarliestTimeToSend) != SQLITE_OK3265 || statement->step() != SQLITE_DONE) {3266 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement insertAttributedPrivateClickMeasurementQuery, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3267 ASSERT_NOT_REACHED();3268 }3269 return;3270 }3271 3272 auto statement = m_database.prepareStatement(insertUnattributedPrivateClickMeasurementQuery);3273 if (!statement3274 || statement->bindInt(1, *sourceData.second) != SQLITE_OK3275 || statement->bindInt(2, *attributionDestinationData.second) != SQLITE_OK3276 || statement->bindInt(3, attribution.sourceID().id) != SQLITE_OK3277 || statement->bindDouble(4, attribution.timeOfAdClick().secondsSinceEpoch().value()) != SQLITE_OK3278 || statement->bindText(5, sourceUnlinkableToken ? sourceUnlinkableToken->tokenBase64URL : emptyString()) != SQLITE_OK3279 || statement->bindText(6, sourceUnlinkableToken ? sourceUnlinkableToken->signatureBase64URL : emptyString()) != SQLITE_OK3280 || statement->bindText(7, sourceUnlinkableToken ? sourceUnlinkableToken->keyIDBase64URL : emptyString()) != SQLITE_OK3281 || statement->step() != SQLITE_DONE) {3282 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement insertUnattributedPrivateClickMeasurementQuery, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3283 ASSERT_NOT_REACHED();3284 }3285 }3286 3287 void ResourceLoadStatisticsDatabaseStore::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting()3288 {3289 auto scopedStatement = this->scopedStatement(m_setUnattributedPrivateClickMeasurementAsExpiredStatement, setUnattributedPrivateClickMeasurementAsExpiredQuery, "markAllUnattributedPrivateClickMeasurementAsExpiredForTesting"_s);3290 3291 if (!scopedStatement || scopedStatement->step() != SQLITE_DONE) {3292 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3293 ASSERT_NOT_REACHED();3294 }3295 }3296 3297 void ResourceLoadStatisticsDatabaseStore::removeUnattributed(PrivateClickMeasurement& attribution)3298 {3299 auto sourceSiteDomainID = domainID(attribution.sourceSite().registrableDomain);3300 auto destinationSiteDomainID = domainID(attribution.destinationSite().registrableDomain);3301 3302 if (!sourceSiteDomainID || !destinationSiteDomainID)3303 return;3304 3305 auto scopedStatement = this->scopedStatement(m_removeUnattributedStatement, removeUnattributedQuery, "removeUnattributed"_s);3306 3307 if (!scopedStatement3308 || scopedStatement->bindInt(1, *sourceSiteDomainID) != SQLITE_OK3309 || scopedStatement->bindInt(2, *destinationSiteDomainID) != SQLITE_OK3310 || scopedStatement->step() != SQLITE_DONE) {3311 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::removeUnattributed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3312 ASSERT_NOT_REACHED();3313 }3314 }3315 3316 std::optional<PrivateClickMeasurement::AttributionSecondsUntilSendData> ResourceLoadStatisticsDatabaseStore::attributePrivateClickMeasurement(const SourceSite& sourceSite, const AttributionDestinationSite& destinationSite, AttributionTriggerData&& attributionTriggerData)3317 {3318 // We should always clear expired clicks from the database before scheduling an attribution.3319 clearExpiredPrivateClickMeasurement();3320 3321 if (!attributionTriggerData.isValid()) {3322 if (UNLIKELY(debugModeEnabled())) {3323 RELEASE_LOG_INFO(PrivateClickMeasurement, "Got an invalid attribution.");3324 debugBroadcastConsoleMessage(MessageSource::PrivateClickMeasurement, MessageLevel::Error, "[Private Click Measurement] Got an invalid attribution."_s);3325 }3326 return std::nullopt;3327 }3328 3329 auto data = attributionTriggerData.data;3330 auto priority = attributionTriggerData.priority;3331 3332 if (UNLIKELY(debugModeEnabled())) {3333 RELEASE_LOG_INFO(PrivateClickMeasurement, "Got an attribution with attribution trigger data: %{public}u and priority: %{public}u.", data, priority);3334 debugBroadcastConsoleMessage(MessageSource::PrivateClickMeasurement, MessageLevel::Info, makeString("[Private Click Measurement] Got an attribution with attribution trigger data: '"_s, data, "' and priority: '"_s, priority, "'."_s));3335 }3336 3337 PrivateClickMeasurement::AttributionSecondsUntilSendData secondsUntilSend { std::nullopt, std::nullopt };3338 3339 auto attribution = findPrivateClickMeasurement(sourceSite, destinationSite);3340 auto& previouslyUnattributed = attribution.first;3341 auto& previouslyAttributed = attribution.second;3342 3343 if (previouslyUnattributed) {3344 // Always convert the pending attribution and remove it from the unattributed map.3345 removeUnattributed(*previouslyUnattributed);3346 secondsUntilSend = previouslyUnattributed.value().attributeAndGetEarliestTimeToSend(WTFMove(attributionTriggerData));3347 3348 // We should always have a valid secondsUntilSend value for a previouslyUnattributed value because there can be no previous attribution with a higher priority.3349 if (!secondsUntilSend.hasValidSecondsUntilSendValues()) {3350 ASSERT_NOT_REACHED();3351 return std::nullopt;3352 }3353 3354 if (UNLIKELY(debugModeEnabled())) {3355 RELEASE_LOG_INFO(PrivateClickMeasurement, "Converted a stored ad click with attribution trigger data: %{public}u and priority: %{public}u.", data, priority);3356 debugBroadcastConsoleMessage(MessageSource::PrivateClickMeasurement, MessageLevel::Info, makeString("[Private Click Measurement] Converted a stored ad click with attribution trigger data: '"_s, data, "' and priority: '"_s, priority, "'."_s));3357 }3358 3359 // If there is no previous attribution, or the new attribution has higher priority, insert/update the database.3360 if (!previouslyAttributed || previouslyUnattributed.value().hasHigherPriorityThan(*previouslyAttributed)) {3361 insertPrivateClickMeasurement(WTFMove(*previouslyUnattributed), PrivateClickMeasurementAttributionType::Attributed);3362 3363 if (UNLIKELY(debugModeEnabled())) {3364 RELEASE_LOG_INFO(PrivateClickMeasurement, "Replaced a previously converted ad click with a new one with attribution data: %{public}u and priority: %{public}u because it had higher priority.", data, priority);3365 debugBroadcastConsoleMessage(MessageSource::PrivateClickMeasurement, MessageLevel::Info, makeString("[Private Click Measurement] Replaced a previously converted ad click with a new one with attribution trigger data: '"_s, data, "' and priority: '"_s, priority, "' because it had higher priority."_s));3366 }3367 }3368 } else if (previouslyAttributed) {3369 // If we have no new attribution, re-attribute the old one to respect the new priority, but only if this report has3370 // not been sent to the source or destination site yet.3371 if (!previouslyAttributed.value().hasPreviouslyBeenReported()) {3372 auto secondsUntilSend = previouslyAttributed.value().attributeAndGetEarliestTimeToSend(WTFMove(attributionTriggerData));3373 if (!secondsUntilSend.hasValidSecondsUntilSendValues())3374 return std::nullopt;3375 3376 insertPrivateClickMeasurement(WTFMove(*previouslyAttributed), PrivateClickMeasurementAttributionType::Attributed);3377 3378 if (UNLIKELY(debugModeEnabled())) {3379 RELEASE_LOG_INFO(PrivateClickMeasurement, "Re-converted an ad click with a new one with attribution trigger data: %{public}u and priority: %{public}u because it had higher priority.", data, priority);3380 debugBroadcastConsoleMessage(MessageSource::PrivateClickMeasurement, MessageLevel::Info, makeString("[Private Click Measurement] Re-converted an ad click with a new one with attribution trigger data: '"_s, data, "' and priority: '"_s, priority, "'' because it had higher priority."_s));3381 }3382 }3383 }3384 3385 if (!secondsUntilSend.hasValidSecondsUntilSendValues())3386 return std::nullopt;3387 3388 return secondsUntilSend;3389 }3390 3391 Vector<WebCore::PrivateClickMeasurement> ResourceLoadStatisticsDatabaseStore::allAttributedPrivateClickMeasurement()3392 {3393 auto attributedScopedStatement = this->scopedStatement(m_allAttributedPrivateClickMeasurementStatement, allAttributedPrivateClickMeasurementQuery, "privateClickMeasurementToString"_s);3394 3395 if (!attributedScopedStatement) {3396 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3397 ASSERT_NOT_REACHED();3398 return { };3399 }3400 3401 Vector<WebCore::PrivateClickMeasurement> attributions;3402 while (attributedScopedStatement->step() == SQLITE_ROW)3403 attributions.append(buildPrivateClickMeasurementFromDatabase(attributedScopedStatement.get(), PrivateClickMeasurementAttributionType::Attributed));3404 3405 return attributions;3406 }3407 3408 void ResourceLoadStatisticsDatabaseStore::clearPrivateClickMeasurement(std::optional<RegistrableDomain> domain)3409 {3410 // Default to clear all entries if no domain is specified.3411 String bindParameter = "%";3412 if (domain) {3413 auto domainIDToMatch = domainID(*domain);3414 if (!domainIDToMatch)3415 return;3416 3417 bindParameter = String::number(*domainIDToMatch);3418 }3419 3420 auto transactionScope = beginTransactionIfNecessary();3421 3422 auto clearUnattributedScopedStatement = this->scopedStatement(m_clearUnattributedPrivateClickMeasurementStatement, clearUnattributedPrivateClickMeasurementQuery, "clearPrivateClickMeasurement"_s);3423 3424 if (!clearUnattributedScopedStatement3425 || clearUnattributedScopedStatement->bindText(1, bindParameter) != SQLITE_OK3426 || clearUnattributedScopedStatement->bindText(2, bindParameter) != SQLITE_OK3427 || clearUnattributedScopedStatement->step() != SQLITE_DONE) {3428 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearPrivateClickMeasurement clearUnattributedScopedStatement, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3429 ASSERT_NOT_REACHED();3430 }3431 3432 auto clearAttributedScopedStatement = this->scopedStatement(m_clearAttributedPrivateClickMeasurementStatement, clearAttributedPrivateClickMeasurementQuery, "clearPrivateClickMeasurement"_s);3433 3434 if (!clearAttributedScopedStatement3435 || clearAttributedScopedStatement->bindText(1, bindParameter) != SQLITE_OK3436 || clearAttributedScopedStatement->bindText(2, bindParameter) != SQLITE_OK3437 || clearAttributedScopedStatement->step() != SQLITE_DONE) {3438 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearPrivateClickMeasurement clearAttributedScopedStatement, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3439 ASSERT_NOT_REACHED();3440 }3441 }3442 3443 void ResourceLoadStatisticsDatabaseStore::clearExpiredPrivateClickMeasurement()3444 {3445 auto expirationTimeFrame = WallTime::now() - WebCore::PrivateClickMeasurement::maxAge();3446 auto scopedStatement = this->scopedStatement(m_clearExpiredPrivateClickMeasurementStatement, clearExpiredPrivateClickMeasurementQuery, "clearExpiredPrivateClickMeasurement"_s);3447 3448 if (!scopedStatement3449 || scopedStatement->bindDouble(1, expirationTimeFrame.secondsSinceEpoch().value()) != SQLITE_OK3450 || scopedStatement->step() != SQLITE_DONE) {3451 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearExpiredPrivateClickMeasurement, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3452 ASSERT_NOT_REACHED();3453 }3454 }3455 3456 String ResourceLoadStatisticsDatabaseStore::attributionToString(WebCore::SQLiteStatement* statement, PrivateClickMeasurementAttributionType attributionType)3457 {3458 auto sourceSiteDomain = getDomainStringFromDomainID(statement->columnInt(0));3459 auto destinationSiteDomain = getDomainStringFromDomainID(statement->columnInt(1));3460 auto sourceID = statement->columnInt(2);3461 3462 StringBuilder builder;3463 builder.append("Source site: ", sourceSiteDomain, "\nAttribute on site: ", destinationSiteDomain, "\nSource ID: ", sourceID);3464 3465 if (attributionType == PrivateClickMeasurementAttributionType::Attributed) {3466 auto attributionTriggerData = statement->columnInt(3);3467 auto priority = statement->columnInt(4);3468 auto earliestTimeToSend = statement->columnInt(6);3469 3470 if (attributionTriggerData != -1) {3471 builder.append("\nAttribution trigger data: ", attributionTriggerData, "\nAttribution priority: ", priority, "\nAttribution earliest time to send: ");3472 if (earliestTimeToSend == -1)3473 builder.append("Not set");3474 else {3475 auto secondsUntilSend = WallTime::fromRawSeconds(earliestTimeToSend) - WallTime::now();3476 builder.append((secondsUntilSend >= 24_h && secondsUntilSend <= 48_h) ? "Within 24-48 hours" : "Outside 24-48 hours");3477 }3478 } else3479 builder.append("\nNo attribution trigger data.");3480 } else3481 builder.append("\nNo attribution trigger data.");3482 builder.append('\n');3483 3484 return builder.toString();3485 }3486 3487 String ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString()3488 {3489 auto privateClickMeasurementDataExists = m_database.prepareStatement("SELECT (SELECT COUNT(*) FROM UnattributedPrivateClickMeasurement) as cnt1, (SELECT COUNT(*) FROM AttributedPrivateClickMeasurement) as cnt2"_s);3490 if (!privateClickMeasurementDataExists || privateClickMeasurementDataExists->step() != SQLITE_ROW) {3491 RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3492 ASSERT_NOT_REACHED();3493 return { };3494 }3495 3496 if (!privateClickMeasurementDataExists->columnInt(0) && !privateClickMeasurementDataExists->columnInt(1))3497 return "\nNo stored Private Click Measurement data.\n"_s;3498 3499 auto unattributedScopedStatement = this->scopedStatement(m_allUnattributedPrivateClickMeasurementAttributionsStatement, allUnattributedPrivateClickMeasurementAttributionsQuery, "privateClickMeasurementToString"_s);3500 3501 if (!unattributedScopedStatement) {3502 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3503 ASSERT_NOT_REACHED();3504 }3505 3506 unsigned unattributedNumber = 0;3507 StringBuilder builder;3508 while (unattributedScopedStatement->step() == SQLITE_ROW) {3509 const char* prefix = unattributedNumber ? "" : "Unattributed Private Click Measurements:";3510 builder.append(prefix, "\nWebCore::PrivateClickMeasurement ", ++unattributedNumber, '\n',3511 attributionToString(unattributedScopedStatement.get(), PrivateClickMeasurementAttributionType::Unattributed));3512 }3513 3514 auto attributedScopedStatement = this->scopedStatement(m_allAttributedPrivateClickMeasurementStatement, allAttributedPrivateClickMeasurementQuery, "privateClickMeasurementToString"_s);3515 3516 if (!attributedScopedStatement) {3517 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::privateClickMeasurementToString, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3518 ASSERT_NOT_REACHED();3519 }3520 3521 unsigned attributedNumber = 0;3522 while (attributedScopedStatement->step() == SQLITE_ROW) {3523 if (!attributedNumber)3524 builder.append(unattributedNumber ? "\n" : "", "Attributed Private Click Measurements:");3525 builder.append("\nWebCore::PrivateClickMeasurement ", ++attributedNumber + unattributedNumber, '\n',3526 attributionToString(attributedScopedStatement.get(), PrivateClickMeasurementAttributionType::Attributed));3527 }3528 return builder.toString();3529 }3530 3531 std::pair<std::optional<SourceEarliestTimeToSend>, std::optional<DestinationEarliestTimeToSend>> ResourceLoadStatisticsDatabaseStore::earliestTimesToSend(const WebCore::PrivateClickMeasurement& attribution)3532 {3533 auto sourceSiteDomainID = domainID(attribution.sourceSite().registrableDomain);3534 auto destinationSiteDomainID = domainID(attribution.destinationSite().registrableDomain);3535 3536 if (!sourceSiteDomainID || !destinationSiteDomainID)3537 return std::make_pair(std::nullopt, std::nullopt);3538 3539 auto scopedStatement = this->scopedStatement(m_earliestTimesToSendStatement, earliestTimesToSendQuery, "earliestTimesToSend"_s);3540 3541 if (!scopedStatement3542 || scopedStatement->bindInt(1, *sourceSiteDomainID) != SQLITE_OK3543 || scopedStatement->bindInt(2, *destinationSiteDomainID) != SQLITE_OK3544 || scopedStatement->step() != SQLITE_ROW) {3545 RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::earliestTimesToSend, error message: %" PUBLIC_LOG_STRING, m_database.lastErrorMsg());3546 ASSERT_NOT_REACHED();3547 }3548 3549 std::optional<SourceEarliestTimeToSend> earliestTimeToSendToSource;3550 std::optional<DestinationEarliestTimeToSend> earliestTimeToSendToDestination;3551 3552 // A value of 0.0 indicates that the report has been sent to the respective site.3553 if (scopedStatement->columnDouble(0) > 0.0)3554 earliestTimeToSendToSource = scopedStatement->columnDouble(0);3555 3556 if (scopedStatement->columnDouble(1) > 0.0)3557 earliestTimeToSendToDestination = scopedStatement->columnDouble(1);3558 3559 return std::make_pair(earliestTimeToSendToSource, earliestTimeToSendToDestination);3560 }3561 3562 void ResourceLoadStatisticsDatabaseStore::markReportAsSentToSource(SourceDomainID sourceSiteDomainID, DestinationDomainID destinationSiteDomainID)3563 {3564 auto scopedStatement = this->scopedStatement(m_markReportAsSentToSourceStatement, markReportAsSentToSourceQuery, "markReportAsSentToSource"_s);3565 3566 if (!scopedStatement3567 || scopedStatement->bindInt(1, sourceSiteDomainID) != SQLITE_OK3568 || scopedStatement->bindInt(2, destinationSiteDomainID) != SQLITE_OK3569 || scopedStatement->step() != SQLITE_DONE) {3570 RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::markReportAsSentToSource, error message: %" PUBLIC_LOG_STRING, m_database.lastErrorMsg());3571 ASSERT_NOT_REACHED();3572 }3573 }3574 3575 void ResourceLoadStatisticsDatabaseStore::markReportAsSentToDestination(SourceDomainID sourceSiteDomainID, DestinationDomainID destinationSiteDomainID)3576 {3577 auto scopedStatement = this->scopedStatement(m_markReportAsSentToDestinationStatement, markReportAsSentToDestinationQuery, "markReportAsSentToDestination"_s);3578 3579 if (!scopedStatement3580 || scopedStatement->bindInt(1, sourceSiteDomainID) != SQLITE_OK3581 || scopedStatement->bindInt(2, destinationSiteDomainID) != SQLITE_OK3582 || scopedStatement->step() != SQLITE_DONE) {3583 RELEASE_LOG_ERROR(Network, "ResourceLoadStatisticsDatabaseStore::markReportAsSentToDestination, error message: %" PUBLIC_LOG_STRING, m_database.lastErrorMsg());3584 ASSERT_NOT_REACHED();3585 }3586 }3587 3588 void ResourceLoadStatisticsDatabaseStore::clearSentAttribution(WebCore::PrivateClickMeasurement&& attribution, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)3589 {3590 auto timesToSend = earliestTimesToSend(attribution);3591 auto sourceEarliestTimeToSend = timesToSend.first;3592 auto destinationEarliestTimeToSend = timesToSend.second;3593 3594 auto sourceSiteDomainID = domainID(attribution.sourceSite().registrableDomain);3595 auto destinationSiteDomainID = domainID(attribution.destinationSite().registrableDomain);3596 3597 if (!sourceSiteDomainID || !destinationSiteDomainID)3598 return;3599 3600 switch (attributionReportEndpoint) {3601 case PrivateClickMeasurement::AttributionReportEndpoint::Source:3602 if (!sourceEarliestTimeToSend) {3603 ASSERT_NOT_REACHED();3604 return;3605 }3606 markReportAsSentToSource(*sourceSiteDomainID, *destinationSiteDomainID);3607 sourceEarliestTimeToSend = std::nullopt;3608 break;3609 case PrivateClickMeasurement::AttributionReportEndpoint::Destination:3610 if (!destinationEarliestTimeToSend) {3611 ASSERT_NOT_REACHED();3612 return;3613 }3614 markReportAsSentToDestination(*sourceSiteDomainID, *destinationSiteDomainID);3615 destinationEarliestTimeToSend = std::nullopt;3616 }3617 3618 // Don't clear the attribute from the database unless it has been reported both to the source and destination site.3619 if (destinationEarliestTimeToSend || sourceEarliestTimeToSend)3620 return;3621 3622 auto clearAttributedStatement = m_database.prepareStatement("DELETE FROM AttributedPrivateClickMeasurement WHERE sourceSiteDomainID = ? AND destinationSiteDomainID = ?"_s);3623 if (!clearAttributedStatement3624 || clearAttributedStatement->bindInt(1, *sourceSiteDomainID) != SQLITE_OK3625 || clearAttributedStatement->bindInt(2, *destinationSiteDomainID) != SQLITE_OK3626 || clearAttributedStatement->step() != SQLITE_DONE) {3627 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearSentAttribution failed to step, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3628 ASSERT_NOT_REACHED();3629 }3630 }3631 3632 void ResourceLoadStatisticsDatabaseStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting()3633 {3634 auto expiredTimeToSend = WallTime::now() - 1_h;3635 3636 auto transactionScope = beginTransactionIfNecessary();3637 3638 auto earliestTimeToSendToSourceStatement = m_database.prepareStatement("UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToSource = ?"_s);3639 auto earliestTimeToSendToDestinationStatement = m_database.prepareStatement("UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToDestination = null"_s);3640 3641 if (!earliestTimeToSendToSourceStatement3642 || earliestTimeToSendToSourceStatement->bindInt(1, expiredTimeToSend.secondsSinceEpoch().value()) != SQLITE_OK3643 || earliestTimeToSendToSourceStatement->step() != SQLITE_DONE) {3644 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3645 ASSERT_NOT_REACHED();3646 }3647 3648 if (!earliestTimeToSendToDestinationStatement || earliestTimeToSendToDestinationStatement->step() != SQLITE_DONE) {3649 ITP_RELEASE_LOG_ERROR(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());3650 ASSERT_NOT_REACHED();3651 }3652 }3653 3654 ScopeExit<Function<void()>> ResourceLoadStatisticsDatabaseStore::beginTransactionIfNecessary()3655 {3656 if (m_transaction.inProgress())3657 return makeScopeExit(Function<void()> { [] { } });3658 3659 m_transaction.begin();3660 return makeScopeExit(Function<void()> { [this] {3661 m_transaction.commit();3662 } });3663 }3664 3665 2930 } // namespace WebKit 3666 2931 -
trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h
r280934 r281721 28 28 #if ENABLE(RESOURCE_LOAD_STATISTICS) 29 29 30 #include "DatabaseUtilities.h" 30 31 #include "ResourceLoadStatisticsStore.h" 31 32 #include "WebResourceLoadStatisticsStore.h" 32 #include <WebCore/SQLiteDatabase.h>33 33 #include <WebCore/SQLiteStatement.h> 34 #include <WebCore/SQLiteStatementAutoResetScope.h>35 #include <WebCore/SQLiteTransaction.h>36 34 #include <pal/SessionID.h> 37 35 #include <wtf/CompletionHandler.h> 38 #include <wtf/Scope.h>39 36 #include <wtf/StdSet.h> 40 37 #include <wtf/Vector.h> 41 38 42 39 namespace WebCore { 43 class SQLiteDatabase;44 class SQLiteStatement;45 40 enum class StorageAccessPromptWasShown : bool; 46 41 enum class StorageAccessWasGranted : bool; … … 57 52 class PrivateClickMeasurementManager; 58 53 59 using AttributedPrivateClickMeasurement = WebCore::PrivateClickMeasurement;60 using UnattributedPrivateClickMeasurement = WebCore::PrivateClickMeasurement;61 54 using SourceSite = WebCore::PrivateClickMeasurement::SourceSite; 62 55 using AttributionDestinationSite = WebCore::PrivateClickMeasurement::AttributionDestinationSite; 63 56 using AttributionTriggerData = WebCore::PrivateClickMeasurement::AttributionTriggerData; 64 using ExistingColumns = Vector<String>;65 using ExpectedColumns = Vector<String>;66 using ExistingColumnName = String;67 using ExpectedColumnName = String;68 using SourceEarliestTimeToSend = double;69 using DestinationEarliestTimeToSend = double;70 using SourceDomainID = unsigned;71 using DestinationDomainID = unsigned;72 57 73 58 typedef std::pair<String, std::optional<String>> TableAndIndexPair; 74 59 75 60 // This is always constructed / used / destroyed on the WebResourceLoadStatisticsStore's statistics queue. 76 class ResourceLoadStatisticsDatabaseStore final : public ResourceLoadStatisticsStore {61 class ResourceLoadStatisticsDatabaseStore final : public ResourceLoadStatisticsStore, public DatabaseUtilities { 77 62 public: 78 63 ResourceLoadStatisticsDatabaseStore(WebResourceLoadStatisticsStore&, SuspendableWorkQueue&, ShouldIncludeLocalhost, const String& storageDirectoryPath, PAL::SessionID); 79 64 ~ResourceLoadStatisticsDatabaseStore(); 80 65 81 static HashSet<ResourceLoadStatisticsDatabaseStore*>& allStores();82 66 void populateFromMemoryStore(const ResourceLoadStatisticsMemoryStore&); 83 67 void mergeStatistics(Vector<ResourceLoadStatistics>&&) override; 84 68 void clear(CompletionHandler<void()>&&) override; 85 69 bool isEmpty() const override; 86 void close();87 70 88 71 Vector<WebResourceLoadStatisticsStore::ThirdPartyData> aggregatedThirdPartyData() const override; … … 141 124 std::optional<Vector<String>> checkForMissingTablesInSchema(); 142 125 void insertExpiredStatisticForTesting(const RegistrableDomain&, unsigned numberOfOperatingDaysPassed, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent) override; 143 void interrupt(); 144 145 // Private Click Measurement. 146 void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) override; 147 void markAllUnattributedPrivateClickMeasurementAsExpiredForTesting() override; 148 std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData> attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&) override; 149 Vector<WebCore::PrivateClickMeasurement> allAttributedPrivateClickMeasurement() override; 150 void clearPrivateClickMeasurement(std::optional<RegistrableDomain>) override; 151 void clearExpiredPrivateClickMeasurement() override; 152 String privateClickMeasurementToString() override; 153 void clearSentAttribution(WebCore::PrivateClickMeasurement&&, WebCore::PrivateClickMeasurement::AttributionReportEndpoint) override; 154 void markAttributedPrivateClickMeasurementsAsExpiredForTesting() override; 126 static void interruptAllDatabases(); 127 155 128 Vector<String> columnsForTable(const String&); 156 129 … … 165 138 bool missingUniqueIndices(); 166 139 bool needsUpdatedSchema(); 167 bool needsUpdatedPrivateClickMeasurementSchema();168 void renameColumnInTable(String&&, ExistingColumnName&&, ExpectedColumnName&&);169 void addMissingColumnsToTable(String&&, const ExistingColumns&, const ExpectedColumns&);170 void addMissingColumnsIfNecessary();171 void renameColumnsIfNecessary();172 void renameColumnInTable();173 140 TableAndIndexPair currentTableAndIndexQueries(const String&); 174 void updatePrivateClickMeasurementSchemaIfNecessary();175 void enableForeignKeys();176 141 bool missingReferenceToObservedDomains(); 177 142 void migrateDataToNewTablesIfNecessary(); 178 void destroyStatements(); 179 WebCore::SQLiteStatementAutoResetScope scopedStatement(std::unique_ptr<WebCore::SQLiteStatement>&, ASCIILiteral, const String&) const; 143 void destroyStatements() final; 180 144 181 145 bool hasStorageAccess(const TopFrameDomain&, const SubFrameDomain&) const; … … 202 166 HashMap<TopFrameDomain, SubResourceDomain> domainsWithStorageAccess() const; 203 167 204 void markReportAsSentToDestination(SourceDomainID, DestinationDomainID);205 void markReportAsSentToSource(SourceDomainID, DestinationDomainID);206 std::pair<std::optional<SourceEarliestTimeToSend>, std::optional<DestinationEarliestTimeToSend>> earliestTimesToSend(const WebCore::PrivateClickMeasurement&);207 208 168 struct DomainData { 209 169 unsigned domainID; … … 254 214 255 215 bool createUniqueIndices(); 256 bool createSchema() ;216 bool createSchema() final; 257 217 String ensureAndMakeDomainList(const HashSet<RegistrableDomain>&); 258 218 std::optional<WallTime> mostRecentUserInteractionTime(const DomainData&); 259 260 void removeUnattributed(WebCore::PrivateClickMeasurement&); 261 WebCore::PrivateClickMeasurement buildPrivateClickMeasurementFromDatabase(WebCore::SQLiteStatement*, PrivateClickMeasurementAttributionType); 262 String attributionToString(WebCore::SQLiteStatement*, PrivateClickMeasurementAttributionType); 263 std::pair<std::optional<UnattributedPrivateClickMeasurement>, std::optional<AttributedPrivateClickMeasurement>> findPrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&); 264 265 ScopeExit<Function<void()>> WARN_UNUSED_RETURN beginTransactionIfNecessary(); 266 267 const String m_storageDirectoryPath; 268 mutable WebCore::SQLiteDatabase m_database; 269 mutable WebCore::SQLiteTransaction m_transaction; 219 270 220 mutable std::unique_ptr<WebCore::SQLiteStatement> m_observedDomainCountStatement; 271 221 std::unique_ptr<WebCore::SQLiteStatement> m_insertObservedDomainStatement; … … 305 255 mutable std::unique_ptr<WebCore::SQLiteStatement> m_observedDomainsExistsStatement; 306 256 mutable std::unique_ptr<WebCore::SQLiteStatement> m_removeAllDataStatement; 307 mutable std::unique_ptr<WebCore::SQLiteStatement> m_earliestTimesToSendStatement;308 std::unique_ptr<WebCore::SQLiteStatement> m_insertUnattributedPrivateClickMeasurementStatement;309 std::unique_ptr<WebCore::SQLiteStatement> m_insertAttributedPrivateClickMeasurementStatement;310 std::unique_ptr<WebCore::SQLiteStatement> m_setUnattributedPrivateClickMeasurementAsExpiredStatement;311 std::unique_ptr<WebCore::SQLiteStatement> m_clearUnattributedPrivateClickMeasurementStatement;312 std::unique_ptr<WebCore::SQLiteStatement> m_clearAttributedPrivateClickMeasurementStatement;313 std::unique_ptr<WebCore::SQLiteStatement> m_clearExpiredPrivateClickMeasurementStatement;314 std::unique_ptr<WebCore::SQLiteStatement> m_allUnattributedPrivateClickMeasurementAttributionsStatement;315 std::unique_ptr<WebCore::SQLiteStatement> m_allAttributedPrivateClickMeasurementStatement;316 std::unique_ptr<WebCore::SQLiteStatement> m_findUnattributedStatement;317 std::unique_ptr<WebCore::SQLiteStatement> m_findAttributedStatement;318 std::unique_ptr<WebCore::SQLiteStatement> m_updateAttributionsEarliestTimeToSendStatement;319 std::unique_ptr<WebCore::SQLiteStatement> m_removeUnattributedStatement;320 std::unique_ptr<WebCore::SQLiteStatement> m_markReportAsSentToSourceStatement;321 std::unique_ptr<WebCore::SQLiteStatement> m_markReportAsSentToDestinationStatement;322 257 323 258 PAL::SessionID m_sessionID; -
trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.h
r280934 r281721 108 108 void insertExpiredStatisticForTesting(const RegistrableDomain&, unsigned numberOfOperatingDaysPassed, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent) override; 109 109 110 // Private Click Measurement is not implemented in the ITP memory store.111 void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) override { };112 void markAllUnattributedPrivateClickMeasurementAsExpiredForTesting() override { };113 std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&) override { return { }; };114 Vector<WebCore::PrivateClickMeasurement> allAttributedPrivateClickMeasurement() override { return { }; };115 void clearPrivateClickMeasurement(std::optional<RegistrableDomain>) override { };116 void clearExpiredPrivateClickMeasurement() override { };117 String privateClickMeasurementToString() override { return String(); };118 void clearSentAttribution(WebCore::PrivateClickMeasurement&&, WebCore::PrivateClickMeasurement::AttributionReportEndpoint) override { };119 void markAttributedPrivateClickMeasurementsAsExpiredForTesting() override { };120 121 110 private: 122 111 void includeTodayAsOperatingDateIfNecessary() override; -
trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.h
r280934 r281721 203 203 virtual bool hasStatisticsExpired(WallTime mostRecentUserInteractionTime, OperatingDatesWindow) const = 0; 204 204 virtual void insertExpiredStatisticForTesting(const RegistrableDomain&, unsigned numberOfOperatingDaysPassed, bool hasUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool) = 0; 205 206 // Private Click Measurement.207 virtual void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType) = 0;208 virtual void markAllUnattributedPrivateClickMeasurementAsExpiredForTesting() = 0;209 virtual std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData> attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&) = 0;210 virtual Vector<WebCore::PrivateClickMeasurement> allAttributedPrivateClickMeasurement() = 0;211 virtual void clearPrivateClickMeasurement(std::optional<RegistrableDomain>) = 0;212 virtual void clearExpiredPrivateClickMeasurement() = 0;213 virtual String privateClickMeasurementToString() = 0;214 virtual void clearSentAttribution(WebCore::PrivateClickMeasurement&&, WebCore::PrivateClickMeasurement::AttributionReportEndpoint) = 0;215 virtual void markAttributedPrivateClickMeasurementsAsExpiredForTesting() = 0;216 205 217 206 protected: -
trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp
r281480 r281721 151 151 } 152 152 153 WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory, ShouldIncludeLocalhost shouldIncludeLocalhost, ResourceLoadStatistics::IsEphemeral isEphemeral) 153 static String pcmStoreDirectory(const NetworkSession& session, const String& resourceLoadStatisticsDirectory, const String& privateClickMeasurementStorageDirectory) 154 { 155 if (session.sessionID().isEphemeral()) 156 return { }; 157 158 if (!privateClickMeasurementStorageDirectory.isEmpty()) 159 return privateClickMeasurementStorageDirectory; 160 161 return resourceLoadStatisticsDirectory; 162 } 163 164 WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory, const String& privateClickMeasurementStorageDirectory, ShouldIncludeLocalhost shouldIncludeLocalhost, ResourceLoadStatistics::IsEphemeral isEphemeral) 154 165 : m_networkSession(makeWeakPtr(networkSession)) 155 166 , m_statisticsQueue(sharedStatisticsQueue()) 156 167 , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks) 157 168 , m_isEphemeral(isEphemeral) 169 , m_pcmStore(PCM::Store::create(pcmStoreDirectory(networkSession, resourceLoadStatisticsDirectory, privateClickMeasurementStorageDirectory))) 158 170 { 159 171 RELEASE_ASSERT(RunLoop::isMain()); … … 187 199 } 188 200 189 Ref<WebResourceLoadStatisticsStore> WebResourceLoadStatisticsStore::create(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory, ShouldIncludeLocalhost shouldIncludeLocalhost, WebCore::ResourceLoadStatistics::IsEphemeral isEphemeral)190 { 191 return adoptRef(*new WebResourceLoadStatisticsStore(networkSession, resourceLoadStatisticsDirectory, shouldIncludeLocalhost, isEphemeral));201 Ref<WebResourceLoadStatisticsStore> WebResourceLoadStatisticsStore::create(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory, const String& privateClickMeasurementStorageDirectory, ShouldIncludeLocalhost shouldIncludeLocalhost, WebCore::ResourceLoadStatistics::IsEphemeral isEphemeral) 202 { 203 return adoptRef(*new WebResourceLoadStatisticsStore(networkSession, resourceLoadStatisticsDirectory, privateClickMeasurementStorageDirectory, shouldIncludeLocalhost, isEphemeral)); 192 204 } 193 205 … … 202 214 m_networkSession = nullptr; 203 215 destroyResourceLoadStatisticsStore([callbackAggregator] { }); 216 privateClickMeasurementStore().close([callbackAggregator] { }); 204 217 } 205 218 … … 1447 1460 { 1448 1461 ASSERT(RunLoop::isMain()); 1449 1450 sharedStatisticsQueue()->suspend([]() mutable { 1451 for (auto& databaseStore : ResourceLoadStatisticsDatabaseStore::allStores()) 1452 databaseStore->interrupt(); 1453 }, WTFMove(completionHandler)); 1462 sharedStatisticsQueue()->suspend(ResourceLoadStatisticsDatabaseStore::interruptAllDatabases, WTFMove(completionHandler)); 1454 1463 } 1455 1464 … … 1468 1477 if (m_statisticsStore) 1469 1478 m_statisticsStore->insertExpiredStatisticForTesting(WTFMove(domain), numberOfOperatingDaysPassed, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent); 1470 postTaskReply(WTFMove(completionHandler));1471 });1472 }1473 1474 void WebResourceLoadStatisticsStore::insertPrivateClickMeasurement(PrivateClickMeasurement&& attribution, PrivateClickMeasurementAttributionType attributionType)1475 {1476 ASSERT(RunLoop::isMain());1477 1478 if (isEphemeral())1479 return;1480 1481 postTask([this, attribution = WTFMove(attribution), attributionType]() mutable {1482 if (!m_statisticsStore)1483 return;1484 1485 m_statisticsStore->insertPrivateClickMeasurement(WTFMove(attribution), attributionType);1486 });1487 }1488 1489 void WebResourceLoadStatisticsStore::markAllUnattributedPrivateClickMeasurementAsExpiredForTesting()1490 {1491 ASSERT(RunLoop::isMain());1492 1493 if (isEphemeral())1494 return;1495 1496 postTask([this]() {1497 if (!m_statisticsStore)1498 return;1499 1500 m_statisticsStore->markAllUnattributedPrivateClickMeasurementAsExpiredForTesting();1501 });1502 }1503 1504 void WebResourceLoadStatisticsStore::attributePrivateClickMeasurement(const PrivateClickMeasurement::SourceSite& sourceSite, const PrivateClickMeasurement::AttributionDestinationSite& destinationSite, PrivateClickMeasurement::AttributionTriggerData&& attributionTriggerData, std::optional<PrivateClickMeasurement>&& ephemeralMeasurement, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&& completionHandler)1505 {1506 ASSERT(RunLoop::isMain());1507 1508 if (isEphemeral()) {1509 completionHandler({ });1510 return;1511 }1512 1513 postTask([this, sourceSite = sourceSite.isolatedCopy(), destinationSite = destinationSite.isolatedCopy(), attributionTriggerData = WTFMove(attributionTriggerData), ephemeralMeasurement = WTFMove(ephemeralMeasurement), completionHandler = WTFMove(completionHandler)]() mutable {1514 if (!m_statisticsStore) {1515 postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {1516 completionHandler(std::nullopt);1517 });1518 return;1519 }1520 1521 // Insert ephemeral measurement right before attribution.1522 if (ephemeralMeasurement) {1523 RELEASE_ASSERT(ephemeralMeasurement->isEphemeral());1524 m_statisticsStore->insertPrivateClickMeasurement(WTFMove(*ephemeralMeasurement), PrivateClickMeasurementAttributionType::Unattributed);1525 }1526 1527 auto seconds = m_statisticsStore->attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData));1528 postTaskReply([seconds, completionHandler = WTFMove(completionHandler)]() mutable {1529 completionHandler(seconds);1530 });1531 });1532 }1533 1534 void WebResourceLoadStatisticsStore::allAttributedPrivateClickMeasurement(CompletionHandler<void(Vector<PrivateClickMeasurement>&&)>&& completionHandler)1535 {1536 ASSERT(RunLoop::isMain());1537 1538 if (isEphemeral()) {1539 completionHandler({ });1540 return;1541 }1542 1543 postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {1544 if (!m_statisticsStore) {1545 postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {1546 completionHandler({ });1547 });1548 return;1549 }1550 1551 auto convertedAttributions = m_statisticsStore->allAttributedPrivateClickMeasurement();1552 postTaskReply([convertedAttributions = WTFMove(convertedAttributions), completionHandler = WTFMove(completionHandler)]() mutable {1553 completionHandler(WTFMove(convertedAttributions));1554 });1555 });1556 }1557 1558 void WebResourceLoadStatisticsStore::clearPrivateClickMeasurement()1559 {1560 ASSERT(RunLoop::isMain());1561 1562 if (isEphemeral())1563 return;1564 1565 postTask([this]() {1566 if (!m_statisticsStore)1567 return;1568 1569 m_statisticsStore->clearPrivateClickMeasurement(std::nullopt);1570 });1571 }1572 1573 void WebResourceLoadStatisticsStore::clearPrivateClickMeasurementForRegistrableDomain(const RegistrableDomain& domain)1574 {1575 ASSERT(RunLoop::isMain());1576 1577 if (isEphemeral())1578 return;1579 1580 postTask([this, domain = domain.isolatedCopy()]() mutable {1581 if (!m_statisticsStore)1582 return;1583 1584 m_statisticsStore->clearPrivateClickMeasurement(domain);1585 });1586 }1587 1588 void WebResourceLoadStatisticsStore::clearExpiredPrivateClickMeasurement()1589 {1590 ASSERT(RunLoop::isMain());1591 1592 if (isEphemeral())1593 return;1594 1595 postTask([this]() {1596 if (!m_statisticsStore)1597 return;1598 1599 m_statisticsStore->clearExpiredPrivateClickMeasurement();1600 });1601 }1602 1603 void WebResourceLoadStatisticsStore::privateClickMeasurementToString(CompletionHandler<void(String)>&& completionHandler)1604 {1605 ASSERT(RunLoop::isMain());1606 1607 if (isEphemeral()) {1608 completionHandler("\nNo stored Private Click Measurement data.\n"_s);1609 return;1610 }1611 1612 postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {1613 if (!m_statisticsStore) {1614 postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {1615 completionHandler({ });1616 });1617 return;1618 }1619 1620 auto result = m_statisticsStore->privateClickMeasurementToString();1621 postTaskReply([result = result.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {1622 completionHandler(result);1623 });1624 });1625 }1626 1627 void WebResourceLoadStatisticsStore::clearSentAttribution(WebCore::PrivateClickMeasurement&& attributionToClear, PrivateClickMeasurement::AttributionReportEndpoint attributionReportEndpoint)1628 {1629 ASSERT(RunLoop::isMain());1630 1631 if (isEphemeral())1632 return;1633 1634 postTask([this, attributionToClear = WTFMove(attributionToClear), attributionReportEndpoint]() mutable {1635 if (!m_statisticsStore)1636 return;1637 1638 m_statisticsStore->clearSentAttribution(WTFMove(attributionToClear), attributionReportEndpoint);1639 });1640 }1641 1642 void WebResourceLoadStatisticsStore::markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&& completionHandler)1643 {1644 ASSERT(RunLoop::isMain());1645 1646 if (isEphemeral()) {1647 completionHandler();1648 return;1649 }1650 1651 postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {1652 if (m_statisticsStore)1653 m_statisticsStore->markAttributedPrivateClickMeasurementsAsExpiredForTesting();1654 1655 1479 postTaskReply(WTFMove(completionHandler)); 1656 1480 }); -
trunk/Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h
r281480 r281721 31 31 #include "Decoder.h" 32 32 #include "Encoder.h" 33 #include "PrivateClickMeasurementStore.h" 33 34 #include "StorageAccessStatus.h" 34 35 #include "WebPageProxyIdentifier.h" … … 109 110 using RequestStorageAccessResult = WebCore::RequestStorageAccessResult; 110 111 111 static Ref<WebResourceLoadStatisticsStore> create(NetworkSession&, const String& resourceLoadStatisticsDirectory, ShouldIncludeLocalhost, ResourceLoadStatistics::IsEphemeral);112 static Ref<WebResourceLoadStatisticsStore> create(NetworkSession&, const String& resourceLoadStatisticsDirectory, const String& privateClickMeasurementStorageDirectory, ShouldIncludeLocalhost, ResourceLoadStatistics::IsEphemeral); 112 113 113 114 ~WebResourceLoadStatisticsStore(); … … 240 241 void insertExpiredStatisticForTesting(const RegistrableDomain&, unsigned numberOfOperatingDaysPassed, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&&); 241 242 242 // Private Click Measurement. 243 void insertPrivateClickMeasurement(WebCore::PrivateClickMeasurement&&, PrivateClickMeasurementAttributionType); 244 void markAllUnattributedPrivateClickMeasurementAsExpiredForTesting(); 245 void attributePrivateClickMeasurement(const WebCore::PrivateClickMeasurement::SourceSite&, const WebCore::PrivateClickMeasurement::AttributionDestinationSite&, WebCore::PrivateClickMeasurement::AttributionTriggerData&&, std::optional<WebCore::PrivateClickMeasurement>&& ephemeralMeasurement, CompletionHandler<void(std::optional<WebCore::PrivateClickMeasurement::AttributionSecondsUntilSendData>)>&&); 246 void allAttributedPrivateClickMeasurement(CompletionHandler<void(Vector<WebCore::PrivateClickMeasurement>&&)>&&); 247 void clearPrivateClickMeasurement(); 248 void clearPrivateClickMeasurementForRegistrableDomain(const WebCore::RegistrableDomain&); 249 void clearExpiredPrivateClickMeasurement(); 250 void privateClickMeasurementToString(CompletionHandler<void(String)>&&); 251 void clearSentAttribution(WebCore::PrivateClickMeasurement&&, WebCore::PrivateClickMeasurement::AttributionReportEndpoint); 252 void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&); 253 243 PCM::Store& privateClickMeasurementStore() { return m_pcmStore.get(); } 254 244 private: 255 explicit WebResourceLoadStatisticsStore(NetworkSession&, const String&, ShouldIncludeLocalhost, WebCore::ResourceLoadStatistics::IsEphemeral);245 explicit WebResourceLoadStatisticsStore(NetworkSession&, const String&, const String&, ShouldIncludeLocalhost, WebCore::ResourceLoadStatistics::IsEphemeral); 256 246 257 247 void postTask(WTF::Function<void()>&&); … … 288 278 289 279 bool m_firstNetworkProcessCreated { false }; 280 281 Ref<PCM::Store> m_pcmStore; 290 282 }; 291 283 -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r281706 r281721 49 49 #include "NetworkSessionCreationParameters.h" 50 50 #include "PreconnectTask.h" 51 #include "PrivateClickMeasurementStore.h" 51 52 #include "RemoteNetworkingContext.h" 52 53 #include "ShouldGrandfatherStatistics.h" … … 1615 1616 1616 1617 if (websiteDataTypes.contains(WebsiteDataType::DiskCache) && !sessionID.isEphemeral()) 1617 clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { });1618 clearDiskCache(modifiedSince, [clearTasksHandler] { }); 1618 1619 1619 1620 if (websiteDataTypes.contains(WebsiteDataType::PrivateClickMeasurements)) { 1620 1621 if (auto* networkSession = this->networkSession(sessionID)) 1621 networkSession->clearPrivateClickMeasurement( );1622 networkSession->clearPrivateClickMeasurement([clearTasksHandler] { }); 1622 1623 } 1623 1624 … … 1678 1679 #endif 1679 1680 1681 auto clearTasksHandler = WTF::CallbackAggregator::create(WTFMove(completionHandler)); 1682 1680 1683 if (websiteDataTypes.contains(WebsiteDataType::PrivateClickMeasurements)) { 1681 1684 if (auto* networkSession = this->networkSession(sessionID)) { 1682 1685 for (auto& originData : originDatas) 1683 networkSession->clearPrivateClickMeasurementForRegistrableDomain(RegistrableDomain::uncheckedCreateFromHost(originData.host) );1686 networkSession->clearPrivateClickMeasurementForRegistrableDomain(RegistrableDomain::uncheckedCreateFromHost(originData.host), [clearTasksHandler] { }); 1684 1687 } 1685 1688 } 1686 1687 auto clearTasksHandler = WTF::CallbackAggregator::create(WTFMove(completionHandler));1688 1689 1689 1690 if (websiteDataTypes.contains(WebsiteDataType::DOMCache)) { … … 2246 2247 WebResourceLoadStatisticsStore::suspend([callbackAggregator] { }); 2247 2248 #endif 2249 PCM::Store::prepareForProcessToSuspend([callbackAggregator] { }); 2248 2250 2249 2251 forEachNetworkSession([&] (auto& networkSession) { … … 2288 2290 WebResourceLoadStatisticsStore::resume(); 2289 2291 #endif 2290 2292 PCM::Store::processDidResume(); 2293 2291 2294 #if ENABLE(SERVICE_WORKER) 2292 2295 for (auto& server : m_swServers.values()) … … 2570 2573 { 2571 2574 if (auto* session = networkSession(sessionID)) 2572 session->clearPrivateClickMeasurement( );2573 2574 completionHandler();2575 session->clearPrivateClickMeasurement(WTFMove(completionHandler)); 2576 else 2577 completionHandler(); 2575 2578 } 2576 2579 -
trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp
r281706 r281721 878 878 m_redirectResponse = redirectResponse; 879 879 880 std::optional< PrivateClickMeasurement::AttributionTriggerData> privateClickMeasurementAttributionTriggerData;880 std::optional<WebCore::PrivateClickMeasurement::AttributionTriggerData> privateClickMeasurementAttributionTriggerData; 881 881 if (!sessionID().isEphemeral()) { 882 if (auto result = PrivateClickMeasurement::parseAttributionRequest(redirectRequest.url()))882 if (auto result = WebCore::PrivateClickMeasurement::parseAttributionRequest(redirectRequest.url())) 883 883 privateClickMeasurementAttributionTriggerData = result.value(); 884 884 else if (!result.error().isEmpty()) … … 941 941 } 942 942 943 void NetworkResourceLoader::continueWillSendRedirectedRequest(ResourceRequest&& request, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse, std::optional< PrivateClickMeasurement::AttributionTriggerData>&& privateClickMeasurementAttributionTriggerData)943 void NetworkResourceLoader::continueWillSendRedirectedRequest(ResourceRequest&& request, ResourceRequest&& redirectRequest, ResourceResponse&& redirectResponse, std::optional<WebCore::PrivateClickMeasurement::AttributionTriggerData>&& privateClickMeasurementAttributionTriggerData) 944 944 { 945 945 redirectRequest.setIsAppInitiated(request.isAppInitiated()); -
trunk/Source/WebKit/NetworkProcess/NetworkSession.cpp
r281706 r281721 85 85 , m_networkProcess(networkProcess) 86 86 #if ENABLE(RESOURCE_LOAD_STATISTICS) 87 , m_privateClickMeasurementStorageDirectory(parameters.resourceLoadStatisticsParameters.privateClickMeasurementStorageDirectory) 87 88 , m_resourceLoadStatisticsDirectory(parameters.resourceLoadStatisticsParameters.directory) 88 89 , m_shouldIncludeLocalhostInResourceLoadStatistics(parameters.resourceLoadStatisticsParameters.shouldIncludeLocalhost ? ShouldIncludeLocalhost::Yes : ShouldIncludeLocalhost::No) … … 120 121 if (!parameters.resourceLoadStatisticsParameters.directory.isEmpty()) 121 122 SandboxExtension::consumePermanently(parameters.resourceLoadStatisticsParameters.directoryExtensionHandle); 123 if (!parameters.resourceLoadStatisticsParameters.privateClickMeasurementStorageDirectory.isEmpty()) 124 SandboxExtension::consumePermanently(parameters.resourceLoadStatisticsParameters.privateClickMeasurementStorageDirectoryExtensionHandle); 122 125 } 123 126 … … 128 131 m_privateClickMeasurement = makeUnique<PrivateClickMeasurementManager>(*this, networkProcess, parameters.sessionID, [weakThis = makeWeakPtr(this)] (auto&& loadParameters, auto&& completionHandler) { 129 132 if (!weakThis) 130 return ;133 return completionHandler(ResourceError(ResourceError::Type::Cancellation), { }, { }); 131 134 132 135 PrivateClickMeasurementNetworkLoader::start(*weakThis, WTFMove(loadParameters), WTFMove(completionHandler)); … … 182 185 return; 183 186 184 m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory, m_ shouldIncludeLocalhostInResourceLoadStatistics, (m_sessionID.isEphemeral() ? ResourceLoadStatistics::IsEphemeral::Yes : ResourceLoadStatistics::IsEphemeral::No));187 m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory, m_privateClickMeasurementStorageDirectory, m_shouldIncludeLocalhostInResourceLoadStatistics, (m_sessionID.isEphemeral() ? ResourceLoadStatistics::IsEphemeral::Yes : ResourceLoadStatistics::IsEphemeral::No)); 185 188 if (!m_sessionID.isEphemeral()) 186 189 m_resourceLoadStatistics->populateMemoryStoreFromDisk([] { }); … … 199 202 if (!weakThis) 200 203 return completionHandler(); 201 m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory, m_ shouldIncludeLocalhostInResourceLoadStatistics, (m_sessionID.isEphemeral() ? ResourceLoadStatistics::IsEphemeral::Yes : ResourceLoadStatistics::IsEphemeral::No));204 m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory, m_privateClickMeasurementStorageDirectory, m_shouldIncludeLocalhostInResourceLoadStatistics, (m_sessionID.isEphemeral() ? ResourceLoadStatistics::IsEphemeral::Yes : ResourceLoadStatistics::IsEphemeral::No)); 202 205 forwardResourceLoadStatisticsSettings(); 203 206 if (!m_sessionID.isEphemeral()) … … 321 324 void NetworkSession::dumpPrivateClickMeasurement(CompletionHandler<void(String)>&& completionHandler) 322 325 { 323 privateClickMeasurement().toString (WTFMove(completionHandler));324 } 325 326 void NetworkSession::clearPrivateClickMeasurement( )327 { 328 privateClickMeasurement().clear( );329 } 330 331 void NetworkSession::clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&& domain )332 { 333 privateClickMeasurement().clearForRegistrableDomain(WTFMove(domain) );326 privateClickMeasurement().toStringForTesting(WTFMove(completionHandler)); 327 } 328 329 void NetworkSession::clearPrivateClickMeasurement(CompletionHandler<void()>&& completionHandler) 330 { 331 privateClickMeasurement().clear(WTFMove(completionHandler)); 332 } 333 334 void NetworkSession::clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&& domain, CompletionHandler<void()>&& completionHandler) 335 { 336 privateClickMeasurement().clearForRegistrableDomain(WTFMove(domain), WTFMove(completionHandler)); 334 337 } 335 338 -
trunk/Source/WebKit/NetworkProcess/NetworkSession.h
r281706 r281721 127 127 void handlePrivateClickMeasurementConversion(WebCore::PrivateClickMeasurement::AttributionTriggerData&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest); 128 128 void dumpPrivateClickMeasurement(CompletionHandler<void(String)>&&); 129 void clearPrivateClickMeasurement( );130 void clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&& );129 void clearPrivateClickMeasurement(CompletionHandler<void()>&&); 130 void clearPrivateClickMeasurementForRegistrableDomain(WebCore::RegistrableDomain&&, CompletionHandler<void()>&&); 131 131 void setPrivateClickMeasurementOverrideTimerForTesting(bool value); 132 132 void markAttributedPrivateClickMeasurementsAsExpiredForTesting(CompletionHandler<void()>&&); … … 196 196 WeakHashSet<NetworkDataTask> m_dataTaskSet; 197 197 #if ENABLE(RESOURCE_LOAD_STATISTICS) 198 String m_privateClickMeasurementStorageDirectory; 198 199 String m_resourceLoadStatisticsDirectory; 199 200 RefPtr<WebResourceLoadStatisticsStore> m_resourceLoadStatistics; -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.cpp
r281480 r281721 29 29 #include "Logging.h" 30 30 #include "NetworkSession.h" 31 #include "PrivateClickMeasurementDebugInfo.h" 31 32 #include <JavaScriptCore/ConsoleTypes.h> 32 33 #include <WebCore/FetchOptions.h> … … 251 252 #if ENABLE(RESOURCE_LOAD_STATISTICS) 252 253 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 253 resourceLoadStatistics-> insertPrivateClickMeasurement(WTFMove(measurement), type);254 resourceLoadStatistics->privateClickMeasurementStore().insertPrivateClickMeasurement(WTFMove(measurement), type); 254 255 #endif 255 256 } … … 298 299 299 300 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) { 300 resourceLoadStatistics-> attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), std::exchange(m_ephemeralMeasurement, std::nullopt), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData) {301 resourceLoadStatistics->privateClickMeasurementStore().attributePrivateClickMeasurement(sourceSite, destinationSite, WTFMove(attributionTriggerData), std::exchange(m_ephemeralMeasurement, std::nullopt), [this, weakThis = makeWeakPtr(*this)] (auto attributionSecondsUntilSendData, auto debugInfo) { 301 302 if (!weakThis) 302 303 return; … … 304 305 if (!attributionSecondsUntilSendData) 305 306 return; 307 308 if (UNLIKELY(debugModeEnabled())) { 309 for (auto& message : debugInfo.messages) 310 m_networkProcess->broadcastConsoleMessage(m_sessionID, MessageSource::PrivateClickMeasurement, message.messageLevel, message.message); 311 } 306 312 307 313 if (attributionSecondsUntilSendData.value().hasValidSecondsUntilSendValues()) { … … 396 402 397 403 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 398 resourceLoadStatistics-> clearSentAttribution(WTFMove(sentConversion), attributionReportEndpoint);404 resourceLoadStatistics->privateClickMeasurementStore().clearSentAttribution(WTFMove(sentConversion), attributionReportEndpoint); 399 405 #endif 400 406 } … … 410 416 return; 411 417 412 resourceLoadStatistics-> allAttributedPrivateClickMeasurement([this, weakThis = makeWeakPtr(*this)] (auto&& attributions) {418 resourceLoadStatistics->privateClickMeasurementStore().allAttributedPrivateClickMeasurement([this, weakThis = makeWeakPtr(*this)] (auto&& attributions) { 413 419 if (!weakThis) 414 420 return; … … 463 469 } 464 470 465 void PrivateClickMeasurementManager::clear( )471 void PrivateClickMeasurementManager::clear(CompletionHandler<void()>&& completionHandler) 466 472 { 467 473 m_firePendingAttributionRequestsTimer.stop(); … … 471 477 #if ENABLE(RESOURCE_LOAD_STATISTICS) 472 478 if (!featureEnabled()) 473 return ;479 return completionHandler(); 474 480 475 481 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 476 resourceLoadStatistics->clearPrivateClickMeasurement(); 477 #endif 478 } 479 480 void PrivateClickMeasurementManager::clearForRegistrableDomain(const RegistrableDomain& domain) 481 { 482 #if ENABLE(RESOURCE_LOAD_STATISTICS) 483 if (!featureEnabled()) 484 return; 482 return resourceLoadStatistics->privateClickMeasurementStore().clearPrivateClickMeasurement(WTFMove(completionHandler)); 483 #endif 484 completionHandler(); 485 } 486 487 void PrivateClickMeasurementManager::clearForRegistrableDomain(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler) 488 { 489 #if ENABLE(RESOURCE_LOAD_STATISTICS) 490 if (!featureEnabled()) 491 return completionHandler(); 485 492 486 493 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 487 resourceLoadStatistics->clearPrivateClickMeasurementForRegistrableDomain(domain); 488 #endif 494 return resourceLoadStatistics->privateClickMeasurementStore().clearPrivateClickMeasurementForRegistrableDomain(domain, WTFMove(completionHandler)); 495 #endif 496 completionHandler(); 489 497 } 490 498 … … 496 504 497 505 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 498 resourceLoadStatistics-> clearExpiredPrivateClickMeasurement();499 #endif 500 } 501 502 void PrivateClickMeasurementManager::toString (CompletionHandler<void(String)>&& completionHandler) const506 resourceLoadStatistics->privateClickMeasurementStore().clearExpiredPrivateClickMeasurement(); 507 #endif 508 } 509 510 void PrivateClickMeasurementManager::toStringForTesting(CompletionHandler<void(String)>&& completionHandler) const 503 511 { 504 512 #if ENABLE(RESOURCE_LOAD_STATISTICS) … … 509 517 510 518 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) { 511 resourceLoadStatistics->privateClickMeasurement ToString(WTFMove(completionHandler));519 resourceLoadStatistics->privateClickMeasurementStore().privateClickMeasurementToStringForTesting(WTFMove(completionHandler)); 512 520 return; 513 521 } … … 546 554 547 555 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) 548 resourceLoadStatistics-> markAllUnattributedPrivateClickMeasurementAsExpiredForTesting();556 resourceLoadStatistics->privateClickMeasurementStore().markAllUnattributedPrivateClickMeasurementAsExpiredForTesting(); 549 557 #endif 550 558 } … … 576 584 577 585 if (auto* resourceLoadStatistics = m_networkSession->resourceLoadStatistics()) { 578 resourceLoadStatistics-> markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler));586 resourceLoadStatistics->privateClickMeasurementStore().markAttributedPrivateClickMeasurementsAsExpiredForTesting(WTFMove(completionHandler)); 579 587 return; 580 588 } -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementManager.h
r281480 r281721 57 57 void storeUnattributed(PrivateClickMeasurement&&); 58 58 void handleAttribution(AttributionTriggerData&&, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest); 59 void clear( );60 void clearForRegistrableDomain(const RegistrableDomain& );61 void toString (CompletionHandler<void(String)>&&) const;59 void clear(CompletionHandler<void()>&&); 60 void clearForRegistrableDomain(const RegistrableDomain&, CompletionHandler<void()>&&); 61 void toStringForTesting(CompletionHandler<void(String)>&&) const; 62 62 void setOverrideTimerForTesting(bool value) { m_isRunningTest = value; } 63 63 void setTokenPublicKeyURLForTesting(URL&&); -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp
r275484 r281721 52 52 } 53 53 54 PrivateClickMeasurementNetworkLoader::~PrivateClickMeasurementNetworkLoader() 55 { 56 cancel(); 57 } 58 54 59 void PrivateClickMeasurementNetworkLoader::fail(ResourceError&& error) 55 60 { … … 61 66 } 62 67 68 void PrivateClickMeasurementNetworkLoader::cancel() 69 { 70 fail(ResourceError { ResourceError::Type::Cancellation }); 71 } 72 63 73 void PrivateClickMeasurementNetworkLoader::willSendRedirectedRequest(ResourceRequest&&, ResourceRequest&&, ResourceResponse&&) 64 74 { 65 fail(ResourceError { ResourceError::Type::Cancellation });75 cancel(); 66 76 } 67 77 -
trunk/Source/WebKit/NetworkProcess/PrivateClickMeasurementNetworkLoader.h
r275260 r281721 43 43 static void start(NetworkSession&, NetworkLoadParameters&&, Callback&&); 44 44 45 ~PrivateClickMeasurementNetworkLoader(); 46 45 47 private: 46 48 PrivateClickMeasurementNetworkLoader(NetworkSession&, NetworkLoadParameters&&, Callback&&); … … 57 59 58 60 void fail(WebCore::ResourceError&&); 61 void cancel(); 59 62 void didComplete(); 60 63 -
trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp
r279750 r281721 33 33 #include "NetworkCacheSpeculativeLoad.h" 34 34 #include "NetworkCacheSubresourcesEntry.h" 35 #include "NetworkLoadParameters.h" 35 36 #include "NetworkProcess.h" 36 37 #include "PreconnectTask.h" -
trunk/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolver.h
r256185 r281721 28 28 #if USE(LIBWEBRTC) 29 29 30 #include "LibWebRTCResolverIdentifier.h" 30 31 #include "RTCNetwork.h" 31 32 #include <WebCore/DNS.h> -
trunk/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp
r259338 r281721 56 56 for (size_t index = 0; index < count; ++index) { 57 57 CFDataRef data = (CFDataRef)CFArrayGetValueAtIndex(resolvedAddresses, index); 58 if (auto address = IPAddress::fromSockAddrIn6(*reinterpret_cast<const struct sockaddr_in6*>(CFDataGetBytePtr(data))))58 if (auto address = WebCore::IPAddress::fromSockAddrIn6(*reinterpret_cast<const struct sockaddr_in6*>(CFDataGetBytePtr(data)))) 59 59 addresses.uncheckedAppend(*address); 60 60 } -
trunk/Source/WebKit/Shared/ResourceLoadStatisticsParameters.h
r278253 r281721 38 38 String directory; 39 39 SandboxExtension::Handle directoryExtensionHandle; 40 String privateClickMeasurementStorageDirectory; 41 SandboxExtension::Handle privateClickMeasurementStorageDirectoryExtensionHandle; 40 42 bool enabled { false }; 41 43 bool isItpStateExplicitlySet { false }; … … 56 58 encoder << directory; 57 59 encoder << directoryExtensionHandle; 60 encoder << privateClickMeasurementStorageDirectory; 61 encoder << privateClickMeasurementStorageDirectoryExtensionHandle; 58 62 encoder << enabled; 59 63 encoder << isItpStateExplicitlySet; … … 82 86 if (!directoryExtensionHandle) 83 87 return std::nullopt; 88 89 std::optional<String> privateClickMeasurementStorageDirectory; 90 decoder >> privateClickMeasurementStorageDirectory; 91 if (!privateClickMeasurementStorageDirectory) 92 return std::nullopt; 84 93 94 std::optional<SandboxExtension::Handle> privateClickMeasurementStorageDirectoryExtensionHandle; 95 decoder >> privateClickMeasurementStorageDirectoryExtensionHandle; 96 if (!privateClickMeasurementStorageDirectoryExtensionHandle) 97 return std::nullopt; 98 85 99 std::optional<bool> enabled; 86 100 decoder >> enabled; … … 143 157 WTFMove(*directory), 144 158 WTFMove(*directoryExtensionHandle), 159 WTFMove(*privateClickMeasurementStorageDirectory), 160 WTFMove(*privateClickMeasurementStorageDirectoryExtensionHandle), 145 161 WTFMove(*enabled), 146 162 WTFMove(*isItpStateExplicitlySet), -
trunk/Source/WebKit/Sources.txt
r281365 r281721 58 58 GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp 59 59 60 NetworkProcess/DatabaseUtilities.cpp 60 61 NetworkProcess/PrivateClickMeasurementManager.cpp 61 62 NetworkProcess/PrivateClickMeasurementNetworkLoader.cpp … … 98 99 NetworkProcess/IndexedDB/WebIDBConnectionToClient.cpp 99 100 NetworkProcess/IndexedDB/WebIDBServer.cpp 101 102 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDatabase.cpp 103 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementDebugInfo.cpp 104 NetworkProcess/PrivateClickMeasurement/PrivateClickMeasurementStore.cpp 100 105 101 106 NetworkProcess/ServiceWorker/ServiceWorkerFetchTask.cpp @no-unify -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm
r281349 r281721 732 732 } 733 733 734 + (void)_ preventNetworkProcessSuspensionForTesting735 { 736 WebKit::NetworkProcessProxy:: preventSuspensionForTesting();734 + (void)_setNetworkProcessSuspensionAllowedForTesting:(BOOL)allowed 735 { 736 WebKit::NetworkProcessProxy::setSuspensionAllowedForTesting(allowed); 737 737 } 738 738 -
trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h
r281349 r281721 96 96 - (void)_sendNetworkProcessWillSuspendImminently WK_API_AVAILABLE(macos(12.0), ios(15.0)); 97 97 - (void)_sendNetworkProcessDidResume WK_API_AVAILABLE(macos(12.0), ios(15.0)); 98 + (void)_ preventNetworkProcessSuspensionForTestingWK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));98 + (void)_setNetworkProcessSuspensionAllowedForTesting:(BOOL)allowed WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 99 99 - (void)_synthesizeAppIsBackground:(BOOL)background WK_API_AVAILABLE(macos(12.0), ios(15.0)); 100 100 - (pid_t)_networkProcessIdentifier WK_API_AVAILABLE(macos(12.0), ios(15.0)); -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.h
r280015 r281721 61 61 @property (nonatomic, copy, setter=_setCookieStorageFile:) NSURL *_cookieStorageFile; 62 62 @property (nonatomic, copy, setter=_setResourceLoadStatisticsDirectory:) NSURL *_resourceLoadStatisticsDirectory WK_API_AVAILABLE(macos(10.13.4), ios(11.3)); 63 @property (nonatomic, nullable, copy) NSURL *privateClickMeasurementStorageDirectory WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA)); 63 64 @property (nonatomic, copy, setter=_setCacheStorageDirectory:) NSURL *_cacheStorageDirectory WK_API_AVAILABLE(macos(10.13.4), ios(11.3)); 64 65 @property (nonatomic, copy, setter=_setServiceWorkerRegistrationDirectory:) NSURL *_serviceWorkerRegistrationDirectory WK_API_AVAILABLE(macos(10.13.4), ios(11.3)); -
trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebsiteDataStoreConfiguration.mm
r280015 r281721 187 187 } 188 188 189 - (NSURL *)privateClickMeasurementStorageDirectory 190 { 191 auto& directory = _configuration->privateClickMeasurementStorageDirectory(); 192 if (directory.isNull()) 193 return nil; 194 return [NSURL fileURLWithPath:directory isDirectory:YES]; 195 } 196 197 - (void)setPrivateClickMeasurementStorageDirectory:(NSURL *)url 198 { 199 if (!_configuration->isPersistent()) 200 [NSException raise:NSInvalidArgumentException format:@"Cannot set privateClickMeasurementStorageDirectory on a non-persistent _WKWebsiteDataStoreConfiguration."]; 201 checkURLArgument(url); 202 _configuration->setPrivateClickMeasurementStorageDirectory(url.path); 203 } 204 189 205 - (NSURL *)_cacheStorageDirectory 190 206 { -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
r281706 r281721 1263 1263 } 1264 1264 1265 static bool s_suspension PreventedForTesting { false };1266 void NetworkProcessProxy:: preventSuspensionForTesting()1267 { 1268 s_suspension PreventedForTesting = true;1265 static bool s_suspensionAllowedForTesting { true }; 1266 void NetworkProcessProxy::setSuspensionAllowedForTesting(bool allowed) 1267 { 1268 s_suspensionAllowedForTesting = allowed; 1269 1269 } 1270 1270 1271 1271 void NetworkProcessProxy::sendPrepareToSuspend(IsSuspensionImminent isSuspensionImminent, CompletionHandler<void()>&& completionHandler) 1272 1272 { 1273 if ( s_suspensionPreventedForTesting)1273 if (!s_suspensionAllowedForTesting) 1274 1274 return completionHandler(); 1275 1275 sendWithAsyncReply(Messages::NetworkProcess::PrepareToSuspend(isSuspensionImminent == IsSuspensionImminent::Yes), WTFMove(completionHandler), 0, { }, ShouldStartProcessThrottlerActivity::No); -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
r281706 r281721 235 235 ASCIILiteral clientName() const final { return "NetworkProcess"_s; } 236 236 237 static void preventSuspensionForTesting();237 static void setSuspensionAllowedForTesting(bool); 238 238 void sendProcessWillSuspendImminentlyForTesting(); 239 239 -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
r281199 r281721 262 262 if (!m_configuration->resourceLoadStatisticsDirectory().isEmpty()) 263 263 m_resolvedConfiguration->setResourceLoadStatisticsDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->resourceLoadStatisticsDirectory())); 264 if (!m_configuration->privateClickMeasurementStorageDirectory().isEmpty()) 265 m_resolvedConfiguration->setPrivateClickMeasurementStorageDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->privateClickMeasurementStorageDirectory())); 264 266 if (!m_configuration->serviceWorkerRegistrationDirectory().isEmpty() && m_resolvedConfiguration->serviceWorkerRegistrationDirectory().isEmpty()) 265 267 m_resolvedConfiguration->setServiceWorkerRegistrationDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->serviceWorkerRegistrationDirectory())); … … 1965 1967 resolveDirectoriesIfNecessary(); 1966 1968 1967 auto resourceLoadStatisticsDirectory = m_ configuration->resourceLoadStatisticsDirectory();1969 auto resourceLoadStatisticsDirectory = m_resolvedConfiguration->resourceLoadStatisticsDirectory(); 1968 1970 SandboxExtension::Handle resourceLoadStatisticsDirectoryHandle; 1969 1971 if (!resourceLoadStatisticsDirectory.isEmpty()) { 1970 1972 if (auto handle = SandboxExtension::createHandleForReadWriteDirectory(resourceLoadStatisticsDirectory)) 1971 1973 resourceLoadStatisticsDirectoryHandle = WTFMove(*handle); 1974 } 1975 1976 auto privateClickMeasurementStorageDirectory = m_resolvedConfiguration->privateClickMeasurementStorageDirectory(); 1977 SandboxExtension::Handle privateClickMeasurementStorageDirectoryHandle; 1978 if (!privateClickMeasurementStorageDirectory.isEmpty()) { 1979 if (auto handle = SandboxExtension::createHandleForReadWriteDirectory(privateClickMeasurementStorageDirectory)) 1980 privateClickMeasurementStorageDirectoryHandle = WTFMove(*handle); 1972 1981 } 1973 1982 … … 2001 2010 WTFMove(resourceLoadStatisticsDirectory), 2002 2011 WTFMove(resourceLoadStatisticsDirectoryHandle), 2012 WTFMove(privateClickMeasurementStorageDirectory), 2013 WTFMove(privateClickMeasurementStorageDirectoryHandle), 2003 2014 resourceLoadStatisticsEnabled(), 2004 2015 #if ENABLE(RESOURCE_LOAD_STATISTICS) -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.cpp
r280015 r281721 77 77 copy->m_deviceIdHashSaltsStorageDirectory = this->m_deviceIdHashSaltsStorageDirectory; 78 78 copy->m_resourceLoadStatisticsDirectory = this->m_resourceLoadStatisticsDirectory; 79 copy->m_privateClickMeasurementStorageDirectory = this->m_privateClickMeasurementStorageDirectory; 79 80 copy->m_javaScriptConfigurationDirectory = this->m_javaScriptConfigurationDirectory; 80 81 copy->m_cookieStorageFile = this->m_cookieStorageFile; -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h
r280015 r281721 118 118 void setResourceLoadStatisticsDirectory(String&& directory) { m_resourceLoadStatisticsDirectory = WTFMove(directory); } 119 119 120 const String& privateClickMeasurementStorageDirectory() const { return m_privateClickMeasurementStorageDirectory; } 121 void setPrivateClickMeasurementStorageDirectory(String&& directory) { m_privateClickMeasurementStorageDirectory = WTFMove(directory); } 122 120 123 const String& networkCacheDirectory() const { return m_networkCacheDirectory; } 121 124 void setNetworkCacheDirectory(String&& directory) { m_networkCacheDirectory = WTFMove(directory); } … … 202 205 String m_deviceIdHashSaltsStorageDirectory; 203 206 String m_resourceLoadStatisticsDirectory; 207 String m_privateClickMeasurementStorageDirectory; 204 208 String m_javaScriptConfigurationDirectory; 205 209 String m_cookieStorageFile; -
trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj
r281365 r281721 1272 1272 5C795D71229F3757003FF1C4 /* WKContextMenuElementInfoPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CE0C36A229F2D4A003695F0 /* WKContextMenuElementInfoPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1273 1273 5C7FB47021E97DC5009E3241 /* WebCookieJar.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C7FB46F21E97C0C009E3241 /* WebCookieJar.h */; }; 1274 5C826D6B26D482EF008AEC91 /* PrivateClickMeasurementStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C826D6826D46B44008AEC91 /* PrivateClickMeasurementStore.h */; }; 1275 5C826D6C26D482F2008AEC91 /* PrivateClickMeasurementDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C826D6926D482EA008AEC91 /* PrivateClickMeasurementDatabase.h */; }; 1274 1276 5C8BC797218CBB4800813886 /* SafeBrowsing.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5C8BC796218CB58A00813886 /* SafeBrowsing.xcassets */; }; 1275 1277 5C8DD3801FE4521600F2A556 /* WebsiteAutoplayPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C8DD37F1FE4519200F2A556 /* WebsiteAutoplayPolicy.h */; }; … … 4510 4512 5C80B3DB23690D8D0086E6DE /* ServiceWorkerInitializationData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServiceWorkerInitializationData.h; sourceTree = "<group>"; }; 4511 4513 5C80B3DD23690F100086E6DE /* ServiceWorkerInitializationData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ServiceWorkerInitializationData.cpp; sourceTree = "<group>"; }; 4514 5C826D6726D46B43008AEC91 /* PrivateClickMeasurementStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementStore.cpp; sourceTree = "<group>"; }; 4515 5C826D6826D46B44008AEC91 /* PrivateClickMeasurementStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementStore.h; sourceTree = "<group>"; }; 4516 5C826D6926D482EA008AEC91 /* PrivateClickMeasurementDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementDatabase.h; sourceTree = "<group>"; }; 4517 5C826D6A26D482EA008AEC91 /* PrivateClickMeasurementDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementDatabase.cpp; sourceTree = "<group>"; }; 4518 5C826D6E26D58A16008AEC91 /* DatabaseUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseUtilities.cpp; sourceTree = "<group>"; }; 4519 5C826D6F26D58A16008AEC91 /* DatabaseUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseUtilities.h; sourceTree = "<group>"; }; 4512 4520 5C84CF901F96AC4E00B6705A /* NetworkSessionCreationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkSessionCreationParameters.h; sourceTree = "<group>"; }; 4513 4521 5C85C7861C3F23C50061A4FA /* PendingDownload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PendingDownload.cpp; sourceTree = "<group>"; }; … … 4547 4555 5CBC9B891C6524A500A8FDCF /* NetworkDataTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkDataTask.h; sourceTree = "<group>"; }; 4548 4556 5CBC9B8B1C65257300A8FDCF /* NetworkDataTaskCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkDataTaskCocoa.mm; sourceTree = "<group>"; }; 4557 5CBE908F26D7FB62005A2E95 /* PrivateClickMeasurementDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateClickMeasurementDebugInfo.h; sourceTree = "<group>"; }; 4558 5CBE909026D7FB7C005A2E95 /* PrivateClickMeasurementDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrivateClickMeasurementDebugInfo.cpp; sourceTree = "<group>"; }; 4549 4559 5CC5DB9121488E16006CB8A8 /* SharedBufferCopy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferCopy.h; sourceTree = "<group>"; }; 4550 4560 5CD286491E722F440094FDC8 /* _WKUserContentFilterPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKUserContentFilterPrivate.h; sourceTree = "<group>"; }; … … 8673 8683 2DA944BB188511DD00ED86DB /* ios */, 8674 8684 510CC7DC16138E2900D03ED3 /* mac */, 8685 5C01BC3526D46AD400FEB42F /* PrivateClickMeasurement */, 8675 8686 93BA04D92151ADCD007F455F /* ServiceWorker */, 8676 8687 413075971DE84ED70039EC69 /* webrtc */, 8677 8688 93B26143227D143100B97A76 /* WebStorage */, 8689 5C826D6E26D58A16008AEC91 /* DatabaseUtilities.cpp */, 8690 5C826D6F26D58A16008AEC91 /* DatabaseUtilities.h */, 8678 8691 53F3CAA5206C443E0086490E /* NetworkActivityTracker.cpp */, 8679 8692 535BCB902069C49C00CCCE02 /* NetworkActivityTracker.h */, … … 9242 9255 ); 9243 9256 path = SOAuthorization; 9257 sourceTree = "<group>"; 9258 }; 9259 5C01BC3526D46AD400FEB42F /* PrivateClickMeasurement */ = { 9260 isa = PBXGroup; 9261 children = ( 9262 5C826D6A26D482EA008AEC91 /* PrivateClickMeasurementDatabase.cpp */, 9263 5C826D6926D482EA008AEC91 /* PrivateClickMeasurementDatabase.h */, 9264 5CBE909026D7FB7C005A2E95 /* PrivateClickMeasurementDebugInfo.cpp */, 9265 5CBE908F26D7FB62005A2E95 /* PrivateClickMeasurementDebugInfo.h */, 9266 5C826D6726D46B43008AEC91 /* PrivateClickMeasurementStore.cpp */, 9267 5C826D6826D46B44008AEC91 /* PrivateClickMeasurementStore.h */, 9268 ); 9269 path = PrivateClickMeasurement; 9244 9270 sourceTree = "<group>"; 9245 9271 }; … … 12307 12333 AAB145E6223F931200E489D8 /* PrefetchCache.h in Headers */, 12308 12334 E1CC1B9012D7EADF00625838 /* PrintInfo.h in Headers */, 12335 5C826D6C26D482F2008AEC91 /* PrivateClickMeasurementDatabase.h in Headers */, 12309 12336 6BD05865220CE8C2000BED5C /* PrivateClickMeasurementManager.h in Headers */, 12310 12337 57FE688C260ABB3D00BF45E4 /* PrivateClickMeasurementNetworkLoader.h in Headers */, 12338 5C826D6B26D482EF008AEC91 /* PrivateClickMeasurementStore.h in Headers */, 12311 12339 86F9536518FF58F5001DB2EF /* ProcessAssertion.h in Headers */, 12312 12340 BC1A7C581136E19C00FB7167 /* ProcessLauncher.h in Headers */, -
trunk/Tools/ChangeLog
r281709 r281721 1 2021-08-27 Alex Christensen <achristensen@webkit.org> 2 3 Separate PrivateClickMeasurement database from ResourceLoadStatistics database and add SPI to set its location 4 https://bugs.webkit.org/show_bug.cgi?id=229527 5 6 Reviewed by Kate Cheney. 7 8 * TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm: 9 (TestWebKitAPI::runBasicEventAttributionTest): 10 (TestWebKitAPI::TEST): 11 * TestWebKitAPI/Tests/WebKitCocoa/PrivateClickMeasurement.mm: 12 (TEST): 13 1 14 2021-08-27 Chris Dumez <cdumez@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/EventAttribution.mm
r281349 r281721 29 29 #import "PlatformUtilities.h" 30 30 #import "TestNavigationDelegate.h" 31 #import "TestWKWebView.h" 31 32 #import "Utilities.h" 32 33 #import <WebKit/WKWebViewPrivate.h> 33 34 #import <WebKit/WKWebViewPrivateForTesting.h> 34 35 #import <WebKit/WKWebsiteDataStorePrivate.h> 36 #import <WebKit/_WKWebsiteDataStoreConfiguration.h> 35 37 36 38 #if HAVE(RSA_BSSA) … … 79 81 } 80 82 81 void runBasicEventAttributionTest( Function<void(WKWebView *, const HTTPServer&)>&& addAttributionToWebView)82 { 83 [WKWebsiteDataStore _ preventNetworkProcessSuspensionForTesting];83 void runBasicEventAttributionTest(WKWebViewConfiguration *configuration, Function<void(WKWebView *, const HTTPServer&)>&& addAttributionToWebView) 84 { 85 [WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:NO]; 84 86 bool done = false; 85 87 HTTPServer server([&done, connectionCount = 0] (Connection connection) mutable { … … 114 116 NSURL *serverURL = server.request().URL; 115 117 116 auto webView = adoptNS([WKWebView new]);118 auto webView = configuration ? adoptNS([[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration]) : adoptNS([WKWebView new]); 117 119 addAttributionToWebView(webView.get(), server); 118 120 [[webView configuration].websiteDataStore _setResourceLoadStatisticsEnabled:YES]; … … 130 132 TEST(EventAttribution, FraudPrevention) 131 133 { 132 [WKWebsiteDataStore _ preventNetworkProcessSuspensionForTesting];134 [WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:NO]; 133 135 bool done = false; 134 136 … … 283 285 TEST(EventAttribution, Basic) 284 286 { 285 runBasicEventAttributionTest( [](WKWebView *webView, const HTTPServer& server) {287 runBasicEventAttributionTest(nil, [](WKWebView *webView, const HTTPServer& server) { 286 288 [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil]; 287 289 }); 288 290 } 289 291 292 TEST(EventAttribution, DatabaseLocation) 293 { 294 NSFileManager *fileManager = [NSFileManager defaultManager]; 295 NSURL *tempDir = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"EventAttributionDatabaseLocationTest"] isDirectory:YES]; 296 if ([fileManager fileExistsAtPath:tempDir.path]) 297 [fileManager removeItemAtURL:tempDir error:nil]; 298 299 auto webViewToKeepNetworkProcessAlive = adoptNS([TestWKWebView new]); 300 [webViewToKeepNetworkProcessAlive synchronouslyLoadHTMLString:@"start network process"]; 301 302 pid_t originalNetworkProcessPid = 0; 303 @autoreleasepool { 304 auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]); 305 dataStoreConfiguration.get().privateClickMeasurementStorageDirectory = tempDir; 306 auto viewConfiguration = adoptNS([WKWebViewConfiguration new]); 307 auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]); 308 viewConfiguration.get().websiteDataStore = dataStore.get(); 309 runBasicEventAttributionTest(viewConfiguration.get(), [](WKWebView *webView, const HTTPServer& server) { 310 [webView _addEventAttributionWithSourceID:42 destinationURL:exampleURL() sourceDescription:@"test source description" purchaser:@"test purchaser" reportEndpoint:server.request().URL optionalNonce:nil]; 311 }); 312 originalNetworkProcessPid = [dataStore _networkProcessIdentifier]; 313 EXPECT_GT(originalNetworkProcessPid, 0); 314 315 __block bool suspended = false; 316 [WKWebsiteDataStore _setNetworkProcessSuspensionAllowedForTesting:YES]; 317 [dataStore _sendNetworkProcessPrepareToSuspend:^{ 318 suspended = true; 319 [dataStore _sendNetworkProcessDidResume]; 320 }]; 321 Util::run(&suspended); 322 Util::spinRunLoop(10); 323 } 324 Util::spinRunLoop(10); 325 usleep(100000); 326 Util::spinRunLoop(10); 327 328 EXPECT_TRUE([fileManager fileExistsAtPath:tempDir.path]); 329 EXPECT_TRUE([fileManager fileExistsAtPath:[tempDir.path stringByAppendingPathComponent:@"pcm.db"]]); 330 331 [webViewToKeepNetworkProcessAlive synchronouslyLoadHTMLString:@"start network process again if it crashed during teardown"]; 332 EXPECT_EQ(webViewToKeepNetworkProcessAlive.get().configuration.websiteDataStore._networkProcessIdentifier, originalNetworkProcessPid); 333 } 334 335 // FIXME: Write a test that verifies that data is migrated from old ResourceLoadStatistics databases to the new PCM database. 336 290 337 #if HAVE(UI_EVENT_ATTRIBUTION) 291 338 292 339 TEST(EventAttribution, BasicWithIOSSPI) 293 340 { 294 runBasicEventAttributionTest( [](WKWebView *webView, const HTTPServer& server) {341 runBasicEventAttributionTest(nil, [](WKWebView *webView, const HTTPServer& server) { 295 342 auto attribution = adoptNS([[MockEventAttribution alloc] initWithReportEndpoint:server.request().URL destinationURL:exampleURL()]); 296 343 webView._uiEventAttribution = (UIEventAttribution *)attribution.get(); -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/PrivateClickMeasurement.mm
r275106 r281721 33 33 #import <wtf/RetainPtr.h> 34 34 35 // FIXME: Implement migration from older databases and get these tests working as they should again. 36 35 37 TEST(PrivateClickMeasurement, AddMissingPCMFraudPreventionColumns) 36 38 { … … 63 65 __block bool doneFlag = false; 64 66 [dataStore _statisticsDatabaseColumnsForTable:@"UnattributedPrivateClickMeasurement" completionHandler:^(NSArray<NSString *> *tableSchema) { 65 EXPECT_ TRUE([tableSchema containsObject:@"token"]);66 EXPECT_ TRUE([tableSchema containsObject:@"keyID"]);67 EXPECT_ TRUE([tableSchema containsObject:@"signature"]);67 EXPECT_FALSE([tableSchema containsObject:@"token"]); 68 EXPECT_FALSE([tableSchema containsObject:@"keyID"]); 69 EXPECT_FALSE([tableSchema containsObject:@"signature"]); 68 70 doneFlag = true; 69 71 }]; … … 73 75 doneFlag = false; 74 76 [dataStore _statisticsDatabaseColumnsForTable:@"AttributedPrivateClickMeasurement" completionHandler:^(NSArray<NSString *> *tableSchema) { 75 EXPECT_ TRUE([tableSchema containsObject:@"token"]);76 EXPECT_ TRUE([tableSchema containsObject:@"keyID"]);77 EXPECT_ TRUE([tableSchema containsObject:@"signature"]);77 EXPECT_FALSE([tableSchema containsObject:@"token"]); 78 EXPECT_FALSE([tableSchema containsObject:@"keyID"]); 79 EXPECT_FALSE([tableSchema containsObject:@"signature"]); 78 80 doneFlag = true; 79 81 }]; … … 112 114 __block bool doneFlag = false; 113 115 [dataStore _statisticsDatabaseColumnsForTable:@"AttributedPrivateClickMeasurement" completionHandler:^(NSArray<NSString *> *tableSchema) { 114 EXPECT_ TRUE([tableSchema containsObject:@"earliestTimeToSendToSource"]);115 EXPECT_ TRUE([tableSchema containsObject:@"earliestTimeToSendToDestination"]);116 EXPECT_FALSE([tableSchema containsObject:@"earliestTimeToSendToSource"]); 117 EXPECT_FALSE([tableSchema containsObject:@"earliestTimeToSendToDestination"]); 116 118 doneFlag = true; 117 119 }]; … … 150 152 __block bool doneFlag = false; 151 153 [dataStore _statisticsDatabaseColumnsForTable:@"AttributedPrivateClickMeasurement" completionHandler:^(NSArray<NSString *> *tableSchema) { 152 EXPECT_ TRUE([tableSchema containsObject:@"destinationSiteDomainID"]);154 EXPECT_FALSE([tableSchema containsObject:@"destinationSiteDomainID"]); 153 155 doneFlag = true; 154 156 }];
Note:
See TracChangeset
for help on using the changeset viewer.