Diff
Modified: trunk/Source/WebKit2/CMakeLists.txt (219452 => 219453)
--- trunk/Source/WebKit2/CMakeLists.txt 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/CMakeLists.txt 2017-07-13 17:52:43 UTC (rev 219453)
@@ -434,6 +434,7 @@
UIProcess/Storage/LocalStorageDatabase.cpp
UIProcess/Storage/LocalStorageDatabaseTracker.cpp
+ UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp
UIProcess/UserContent/WebScriptMessageHandler.cpp
UIProcess/UserContent/WebUserContentControllerProxy.cpp
Modified: trunk/Source/WebKit2/ChangeLog (219452 => 219453)
--- trunk/Source/WebKit2/ChangeLog 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/ChangeLog 2017-07-13 17:52:43 UTC (rev 219453)
@@ -1,3 +1,44 @@
+2017-07-13 Chris Dumez <cdu...@apple.com>
+
+ Moved filesystem code out of WebResourceLoadStatisticsStore class
+ https://bugs.webkit.org/show_bug.cgi?id=174435
+
+ Reviewed by Brent Fulgham.
+
+ Moved filesystem code out of WebResourceLoadStatisticsStore class and into
+ a new ResourceLoadStatisticsPersistentStorage class to decrease complexity.
+
+ * CMakeLists.txt:
+ * UIProcess/Cocoa/WebResourceLoadStatisticsStoreCocoa.mm:
+ * UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp: Added.
+ (WebKit::hasFileChangedSince):
+ (WebKit::createDecoderForFile):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::ResourceLoadStatisticsPersistentStorage):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::~ResourceLoadStatisticsPersistentStorage):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::storageDirectoryPath):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::resourceLogFilePath):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::startMonitoringDisk):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::stopMonitoringDisk):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::scheduleOrWriteMemoryStore):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::clear):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::finishAllPendingWorkSynchronously):
+ (WebKit::ResourceLoadStatisticsPersistentStorage::excludeFromBackup):
+ * UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h: Added.
+ * UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm: Added.
+ (WebKit::ResourceLoadStatisticsPersistentStorage::excludeFromBackup):
+ * UIProcess/WebResourceLoadStatisticsStore.cpp:
+ (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+ (WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords):
+ (WebKit::WebResourceLoadStatisticsStore::grandfatherExistingWebsiteData):
+ (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate):
+ (WebKit::WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent):
+ (WebKit::WebResourceLoadStatisticsStore::resetDataFromDecoder):
+ * UIProcess/WebResourceLoadStatisticsStore.h:
+ * WebKit2.xcodeproj/project.pbxproj:
+
2017-07-12 Carlos Garcia Campos <cgar...@igalia.com>
Web Automation: evaluateJavaScriptFunction should start the callback timeout after the function is applied
Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebResourceLoadStatisticsStoreCocoa.mm (219452 => 219453)
--- trunk/Source/WebKit2/UIProcess/Cocoa/WebResourceLoadStatisticsStoreCocoa.mm 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebResourceLoadStatisticsStoreCocoa.mm 2017-07-13 17:52:43 UTC (rev 219453)
@@ -32,13 +32,6 @@
namespace WebKit {
-void WebResourceLoadStatisticsStore::platformExcludeFromBackup() const
-{
-#if PLATFORM(IOS)
- [[NSURL fileURLWithPath:(NSString *)m_statisticsStoragePath] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
-#endif
-}
-
void WebResourceLoadStatisticsStore::registerUserDefaultsIfNeeded()
{
static dispatch_once_t initOnce;
Added: trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp (0 => 219453)
--- trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp 2017-07-13 17:52:43 UTC (rev 219453)
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ResourceLoadStatisticsPersistentStorage.h"
+
+#include "Logging.h"
+#include "WebResourceLoadStatisticsStore.h"
+#include <WebCore/FileMonitor.h>
+#include <WebCore/FileSystem.h>
+#include <WebCore/KeyedCoding.h>
+#include <WebCore/SharedBuffer.h>
+#include <wtf/RunLoop.h>
+#include <wtf/WorkQueue.h>
+#include <wtf/threads/BinarySemaphore.h>
+
+namespace WebKit {
+
+constexpr Seconds minimumWriteInterval { 5_min };
+
+using namespace WebCore;
+
+static bool hasFileChangedSince(const String& path, WallTime since)
+{
+ ASSERT(!RunLoop::isMain());
+ time_t modificationTime;
+ if (!getFileModificationTime(path, modificationTime))
+ return true;
+
+ return WallTime::fromRawSeconds(modificationTime) > since;
+}
+
+static std::unique_ptr<KeyedDecoder> createDecoderForFile(const String& path)
+{
+ ASSERT(!RunLoop::isMain());
+ auto handle = openAndLockFile(path, OpenForRead);
+ if (handle == invalidPlatformFileHandle)
+ return nullptr;
+
+ long long fileSize = 0;
+ if (!getFileSize(handle, fileSize)) {
+ unlockAndCloseFile(handle);
+ return nullptr;
+ }
+
+ size_t bytesToRead;
+ if (!WTF::convertSafely(fileSize, bytesToRead)) {
+ unlockAndCloseFile(handle);
+ return nullptr;
+ }
+
+ Vector<char> buffer(bytesToRead);
+ size_t totalBytesRead = readFromFile(handle, buffer.data(), buffer.size());
+
+ unlockAndCloseFile(handle);
+
+ if (totalBytesRead != bytesToRead)
+ return nullptr;
+
+ return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
+}
+
+ResourceLoadStatisticsPersistentStorage::ResourceLoadStatisticsPersistentStorage(WebResourceLoadStatisticsStore& store, const String& storageDirectoryPath)
+ : m_memoryStore(store)
+ , m_storageDirectoryPath(storageDirectoryPath)
+{
+ ASSERT(RunLoop::isMain());
+ m_memoryStore.statisticsQueue().dispatch([this] {
+ populateMemoryStoreFromDisk();
+ startMonitoringDisk();
+ m_memoryStore.includeTodayAsOperatingDateIfNecessary();
+ });
+}
+
+ResourceLoadStatisticsPersistentStorage::~ResourceLoadStatisticsPersistentStorage()
+{
+ finishAllPendingWorkSynchronously();
+ ASSERT(!m_hasPendingWrite);
+}
+
+String ResourceLoadStatisticsPersistentStorage::storageDirectoryPath() const
+{
+ return m_storageDirectoryPath.isolatedCopy();
+}
+
+String ResourceLoadStatisticsPersistentStorage::resourceLogFilePath() const
+{
+ String storagePath = this->storageDirectoryPath();
+ if (storagePath.isEmpty())
+ return emptyString();
+
+ return pathByAppendingComponent(storagePath, "full_browsing_session_resourceLog.plist");
+}
+
+void ResourceLoadStatisticsPersistentStorage::startMonitoringDisk()
+{
+ ASSERT(!RunLoop::isMain());
+ if (m_fileMonitor)
+ return;
+
+ String resourceLogPath = resourceLogFilePath();
+ if (resourceLogPath.isEmpty())
+ return;
+
+ m_fileMonitor = std::make_unique<FileMonitor>(resourceLogPath, m_memoryStore.statisticsQueue(), [this] (FileMonitor::FileChangeType type) {
+ ASSERT(!RunLoop::isMain());
+ switch (type) {
+ case FileMonitor::FileChangeType::Modification:
+ refreshMemoryStoreFromDisk();
+ break;
+ case FileMonitor::FileChangeType::Removal:
+ m_memoryStore.clearInMemory();
+ m_fileMonitor = nullptr;
+ break;
+ }
+ });
+}
+
+void ResourceLoadStatisticsPersistentStorage::stopMonitoringDisk()
+{
+ ASSERT(!RunLoop::isMain());
+ m_fileMonitor = nullptr;
+}
+
+// This is called when the file changes on disk.
+void ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk()
+{
+ ASSERT(!RunLoop::isMain());
+
+ String filePath = resourceLogFilePath();
+ if (filePath.isEmpty())
+ return;
+
+ // We sometimes see file changed events from before our load completed (we start
+ // reading at the first change event, but we might receive a series of events related
+ // to the same file operation). Catch this case to avoid reading overly often.
+ if (!hasFileChangedSince(filePath, m_lastStatisticsFileSyncTime))
+ return;
+
+ WallTime readTime = WallTime::now();
+
+ auto decoder = createDecoderForFile(filePath);
+ if (!decoder)
+ return;
+
+ m_memoryStore.resetDataFromDecoder(*decoder);
+ m_lastStatisticsFileSyncTime = readTime;
+}
+
+void ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk()
+{
+ ASSERT(!RunLoop::isMain());
+
+ String filePath = resourceLogFilePath();
+ if (filePath.isEmpty() || !fileExists(filePath)) {
+ m_memoryStore.grandfatherExistingWebsiteData();
+ return;
+ }
+
+ if (!hasFileChangedSince(filePath, m_lastStatisticsFileSyncTime)) {
+ // No need to grandfather in this case.
+ return;
+ }
+
+ WallTime readTime = WallTime::now();
+
+ auto decoder = createDecoderForFile(filePath);
+ if (!decoder) {
+ m_memoryStore.grandfatherExistingWebsiteData();
+ return;
+ }
+
+ m_memoryStore.resetDataFromDecoder(*decoder);
+
+ m_lastStatisticsFileSyncTime = readTime;
+
+ if (m_memoryStore.isEmpty())
+ m_memoryStore.grandfatherExistingWebsiteData();
+}
+
+void ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk()
+{
+ ASSERT(!RunLoop::isMain());
+
+ m_hasPendingWrite = false;
+ stopMonitoringDisk();
+
+ auto encoder = m_memoryStore.createEncoderFromData();
+ auto rawData = encoder->finishEncoding();
+ if (!rawData)
+ return;
+
+ auto storagePath = this->storageDirectoryPath();
+ if (!storagePath.isEmpty()) {
+ makeAllDirectories(storagePath);
+ excludeFromBackup();
+ }
+
+ auto handle = openAndLockFile(resourceLogFilePath(), OpenForWrite);
+ if (handle == invalidPlatformFileHandle)
+ return;
+
+ int64_t writtenBytes = writeToFile(handle, rawData->data(), rawData->size());
+ unlockAndCloseFile(handle);
+
+ if (writtenBytes != static_cast<int64_t>(rawData->size()))
+ RELEASE_LOG_ERROR(ResourceLoadStatistics, "WebResourceLoadStatisticsStore: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
+
+ m_lastStatisticsFileSyncTime = WallTime::now();
+ m_lastStatisticsWriteTime = MonotonicTime::now();
+
+ startMonitoringDisk();
+}
+
+void ResourceLoadStatisticsPersistentStorage::scheduleOrWriteMemoryStore()
+{
+ ASSERT(!RunLoop::isMain());
+
+ auto timeSinceLastWrite = MonotonicTime::now() - m_lastStatisticsWriteTime;
+ if (timeSinceLastWrite < minimumWriteInterval) {
+ if (!m_hasPendingWrite) {
+ m_hasPendingWrite = true;
+ Seconds delay = minimumWriteInterval - timeSinceLastWrite + 1_s;
+ m_memoryStore.statisticsQueue().dispatchAfter(delay, [this] () mutable {
+ writeMemoryStoreToDisk();
+ });
+ }
+ return;
+ }
+
+ writeMemoryStoreToDisk();
+}
+
+void ResourceLoadStatisticsPersistentStorage::clear()
+{
+ ASSERT(!RunLoop::isMain());
+ String filePath = resourceLogFilePath();
+ if (filePath.isEmpty())
+ return;
+
+ stopMonitoringDisk();
+
+ if (!deleteFile(filePath))
+ RELEASE_LOG_ERROR(ResourceLoadStatistics, "Unable to delete statistics file: %s", filePath.utf8().data());
+}
+
+void ResourceLoadStatisticsPersistentStorage::finishAllPendingWorkSynchronously()
+{
+ BinarySemaphore semaphore;
+ // Make sure any pending work in our queue is finished before we terminate.
+ m_memoryStore.statisticsQueue().dispatch([&semaphore, this] {
+ // Write final file state to disk.
+ if (m_hasPendingWrite)
+ writeMemoryStoreToDisk();
+ semaphore.signal();
+ });
+ semaphore.wait(WallTime::infinity());
+}
+
+#if !PLATFORM(IOS)
+void ResourceLoadStatisticsPersistentStorage::excludeFromBackup() const
+{
+}
+#endif
+
+} // namespace WebKit
Added: trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h (0 => 219453)
--- trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h 2017-07-13 17:52:43 UTC (rev 219453)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Forward.h>
+#include <wtf/MonotonicTime.h>
+#include <wtf/WallTime.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+class FileMonitor;
+}
+
+namespace WebKit {
+
+class WebResourceLoadStatisticsStore;
+
+class ResourceLoadStatisticsPersistentStorage {
+public:
+ ResourceLoadStatisticsPersistentStorage(WebResourceLoadStatisticsStore&, const String& storageDirectoryPath);
+ ~ResourceLoadStatisticsPersistentStorage();
+
+ void scheduleOrWriteMemoryStore();
+ void clear();
+
+ void finishAllPendingWorkSynchronously();
+
+private:
+ String storageDirectoryPath() const;
+ String resourceLogFilePath() const;
+
+ void startMonitoringDisk();
+ void stopMonitoringDisk();
+
+ void writeMemoryStoreToDisk();
+ void populateMemoryStoreFromDisk();
+ void excludeFromBackup() const;
+ void refreshMemoryStoreFromDisk();
+
+ WebResourceLoadStatisticsStore& m_memoryStore;
+ const String m_storageDirectoryPath;
+ std::unique_ptr<WebCore::FileMonitor> m_fileMonitor;
+ WallTime m_lastStatisticsFileSyncTime;
+ MonotonicTime m_lastStatisticsWriteTime;
+ bool m_hasPendingWrite { false };
+};
+
+}
Added: trunk/Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm (0 => 219453)
--- trunk/Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm (rev 0)
+++ trunk/Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm 2017-07-13 17:52:43 UTC (rev 219453)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "ResourceLoadStatisticsPersistentStorage.h"
+
+#if PLATFORM(IOS)
+
+namespace WebKit {
+
+void ResourceLoadStatisticsPersistentStorage::excludeFromBackup() const
+{
+ [[NSURL fileURLWithPath:(NSString *)m_storageDirectoryPath] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
+}
+
+}
+
+#endif
Modified: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp (219452 => 219453)
--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp 2017-07-13 17:52:43 UTC (rev 219453)
@@ -34,21 +34,16 @@
#include "WebsiteDataFetchOption.h"
#include "WebsiteDataStore.h"
#include "WebsiteDataType.h"
-#include <WebCore/FileMonitor.h>
-#include <WebCore/FileSystem.h>
#include <WebCore/KeyedCoding.h>
#include <WebCore/ResourceLoadStatistics.h>
-#include <WebCore/SharedBuffer.h>
#include <wtf/CrossThreadCopier.h>
#include <wtf/MathExtras.h>
#include <wtf/NeverDestroyed.h>
-#include <wtf/threads/BinarySemaphore.h>
using namespace WebCore;
namespace WebKit {
-constexpr Seconds minimumStatisticsFileWriteInterval { 5_min };
constexpr unsigned operatingDatesWindow { 30 };
constexpr unsigned statisticsModelVersion { 7 };
constexpr unsigned maxImportance { 3 };
@@ -84,8 +79,8 @@
WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, UpdateCookiePartitioningForDomainsHandler&& updateCookiePartitioningForDomainsHandler)
: m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
+ , m_persistentStorage(*this, resourceLoadStatisticsDirectory)
, m_updateCookiePartitioningForDomainsHandler(WTFMove(updateCookiePartitioningForDomainsHandler))
- , m_statisticsStoragePath(resourceLoadStatisticsDirectory)
, m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
{
ASSERT(RunLoop::isMain());
@@ -94,10 +89,6 @@
registerUserDefaultsIfNeeded();
#endif
- m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] {
- readDataFromDiskIfNeeded();
- startMonitoringStatisticsStorage();
- });
m_statisticsQueue->dispatchAfter(5_s, [this, protectedThis = makeRef(*this)] {
if (m_parameters.shouldSubmitTelemetry)
WebResourceLoadStatisticsTelemetry::calculateAndSubmit(*this);
@@ -155,7 +146,7 @@
});
}
- scheduleOrWriteStoreToDisk();
+ m_persistentStorage.scheduleOrWriteMemoryStore();
});
}
@@ -185,80 +176,7 @@
});
});
}
-
-WallTime WebResourceLoadStatisticsStore::statisticsFileModificationTime(const String& path) const
-{
- ASSERT(!RunLoop::isMain());
- time_t modificationTime;
- if (!getFileModificationTime(path, modificationTime))
- return { };
-
- return WallTime::fromRawSeconds(modificationTime);
-}
-
-bool WebResourceLoadStatisticsStore::hasStatisticsFileChangedSinceLastSync(const String& path) const
-{
- return statisticsFileModificationTime(path) > m_lastStatisticsFileSyncTime;
-}
-
-void WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded()
-{
- ASSERT(!RunLoop::isMain());
-
- String resourceLog = resourceLogFilePath();
- if (resourceLog.isEmpty() || !fileExists(resourceLog)) {
- grandfatherExistingWebsiteData();
- return;
- }
-
- if (!hasStatisticsFileChangedSinceLastSync(resourceLog)) {
- // No need to grandfather in this case.
- return;
- }
-
- WallTime readTime = WallTime::now();
-
- auto decoder = createDecoderFromDisk(resourceLog);
- if (!decoder) {
- grandfatherExistingWebsiteData();
- return;
- }
-
- clearInMemory();
- populateFromDecoder(*decoder);
-
- m_lastStatisticsFileSyncTime = readTime;
-
- if (m_resourceStatisticsMap.isEmpty())
- grandfatherExistingWebsiteData();
-
- includeTodayAsOperatingDateIfNecessary();
-}
-void WebResourceLoadStatisticsStore::refreshFromDisk()
-{
- ASSERT(!RunLoop::isMain());
-
- String resourceLog = resourceLogFilePath();
- if (resourceLog.isEmpty())
- return;
-
- // We sometimes see file changed events from before our load completed (we start
- // reading at the first change event, but we might receive a series of events related
- // to the same file operation). Catch this case to avoid reading overly often.
- if (!hasStatisticsFileChangedSinceLastSync(resourceLog))
- return;
-
- WallTime readTime = WallTime::now();
-
- auto decoder = createDecoderFromDisk(resourceLog);
- if (!decoder)
- return;
-
- populateFromDecoder(*decoder);
- m_lastStatisticsFileSyncTime = readTime;
-}
-
void WebResourceLoadStatisticsStore::processWillOpenConnection(WebProcessProxy&, IPC::Connection& connection)
{
connection.addWorkQueueMessageReceiver(Messages::WebResourceLoadStatisticsStore::messageReceiverName(), m_statisticsQueue.get(), this);
@@ -271,179 +189,9 @@
void WebResourceLoadStatisticsStore::applicationWillTerminate()
{
- BinarySemaphore semaphore;
- // Make sure any pending work in our queue is finished before we terminate.
- m_statisticsQueue->dispatch([&semaphore, this, protectedThis = makeRef(*this)] {
- // Write final file state to disk.
- if (m_didScheduleWrite)
- writeStoreToDisk();
-
- semaphore.signal();
- });
- semaphore.wait(WallTime::infinity());
+ m_persistentStorage.finishAllPendingWorkSynchronously();
}
-String WebResourceLoadStatisticsStore::statisticsStoragePath() const
-{
- return m_statisticsStoragePath.isolatedCopy();
-}
-
-String WebResourceLoadStatisticsStore::resourceLogFilePath() const
-{
- String statisticsStoragePath = this->statisticsStoragePath();
- if (statisticsStoragePath.isEmpty())
- return emptyString();
-
- return pathByAppendingComponent(statisticsStoragePath, "full_browsing_session_resourceLog.plist");
-}
-
-void WebResourceLoadStatisticsStore::writeStoreToDisk()
-{
- ASSERT(!RunLoop::isMain());
-
- stopMonitoringStatisticsStorage();
-
- syncWithExistingStatisticsStorageIfNeeded();
-
- auto encoder = createEncoderFromData();
- RefPtr<SharedBuffer> rawData = encoder->finishEncoding();
- if (!rawData)
- return;
-
- auto statisticsStoragePath = this->statisticsStoragePath();
- if (!statisticsStoragePath.isEmpty()) {
- makeAllDirectories(statisticsStoragePath);
- platformExcludeFromBackup();
- }
-
- auto handle = openAndLockFile(resourceLogFilePath(), OpenForWrite);
- if (handle == invalidPlatformFileHandle)
- return;
-
- int64_t writtenBytes = writeToFile(handle, rawData->data(), rawData->size());
- unlockAndCloseFile(handle);
-
- if (writtenBytes != static_cast<int64_t>(rawData->size()))
- RELEASE_LOG_ERROR(ResourceLoadStatistics, "WebResourceLoadStatisticsStore: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
-
- m_lastStatisticsFileSyncTime = WallTime::now();
- m_lastStatisticsWriteTime = MonotonicTime::now();
-
- startMonitoringStatisticsStorage();
- m_didScheduleWrite = false;
-}
-
-void WebResourceLoadStatisticsStore::scheduleOrWriteStoreToDisk()
-{
- ASSERT(!RunLoop::isMain());
-
- auto timeSinceLastWrite = MonotonicTime::now() - m_lastStatisticsWriteTime;
- if (timeSinceLastWrite < minimumStatisticsFileWriteInterval) {
- if (!m_didScheduleWrite) {
- m_didScheduleWrite = true;
- Seconds delay = minimumStatisticsFileWriteInterval - timeSinceLastWrite + 1_s;
- m_statisticsQueue->dispatchAfter(delay, [this, protectedThis = makeRef(*this)] {
- writeStoreToDisk();
- });
- }
- return;
- }
-
- writeStoreToDisk();
-}
-
-void WebResourceLoadStatisticsStore::deleteStoreFromDisk()
-{
- ASSERT(!RunLoop::isMain());
- String resourceLogPath = resourceLogFilePath();
- if (resourceLogPath.isEmpty())
- return;
-
- stopMonitoringStatisticsStorage();
-
- if (!deleteFile(resourceLogPath))
- RELEASE_LOG_ERROR(ResourceLoadStatistics, "Unable to delete statistics file: %s", resourceLogPath.utf8().data());
-}
-
-void WebResourceLoadStatisticsStore::startMonitoringStatisticsStorage()
-{
- ASSERT(!RunLoop::isMain());
- if (m_statisticsStorageMonitor)
- return;
-
- String resourceLogPath = resourceLogFilePath();
- if (resourceLogPath.isEmpty())
- return;
-
- m_statisticsStorageMonitor = std::make_unique<FileMonitor>(resourceLogPath, m_statisticsQueue.copyRef(), [this] (FileMonitor::FileChangeType type) {
- ASSERT(!RunLoop::isMain());
- switch (type) {
- case FileMonitor::FileChangeType::Modification:
- refreshFromDisk();
- break;
- case FileMonitor::FileChangeType::Removal:
- clearInMemory();
- m_statisticsStorageMonitor = nullptr;
- break;
- }
- });
-}
-
-void WebResourceLoadStatisticsStore::stopMonitoringStatisticsStorage()
-{
- ASSERT(!RunLoop::isMain());
- m_statisticsStorageMonitor = nullptr;
-}
-
-void WebResourceLoadStatisticsStore::syncWithExistingStatisticsStorageIfNeeded()
-{
- ASSERT(!RunLoop::isMain());
- if (m_statisticsStorageMonitor)
- return;
-
- String resourceLog = resourceLogFilePath();
- if (resourceLog.isEmpty() || !fileExists(resourceLog))
- return;
-
- refreshFromDisk();
-}
-
-#if !PLATFORM(COCOA)
-void WebResourceLoadStatisticsStore::platformExcludeFromBackup() const
-{
-}
-#endif
-
-std::unique_ptr<KeyedDecoder> WebResourceLoadStatisticsStore::createDecoderFromDisk(const String& path) const
-{
- ASSERT(!RunLoop::isMain());
- auto handle = openAndLockFile(path, OpenForRead);
- if (handle == invalidPlatformFileHandle)
- return nullptr;
-
- long long fileSize = 0;
- if (!getFileSize(handle, fileSize)) {
- unlockAndCloseFile(handle);
- return nullptr;
- }
-
- size_t bytesToRead;
- if (!WTF::convertSafely(fileSize, bytesToRead)) {
- unlockAndCloseFile(handle);
- return nullptr;
- }
-
- Vector<char> buffer(bytesToRead);
- size_t totalBytesRead = readFromFile(handle, buffer.data(), buffer.size());
-
- unlockAndCloseFile(handle);
-
- if (totalBytesRead != bytesToRead)
- return nullptr;
-
- return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
-}
-
void WebResourceLoadStatisticsStore::performDailyTasks()
{
ASSERT(RunLoop::isMain());
@@ -653,7 +401,7 @@
ASSERT(RunLoop::isMain());
m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] {
clearInMemory();
- deleteStoreFromDisk();
+ m_persistentStorage.clear();
grandfatherExistingWebsiteData();
});
}
@@ -732,12 +480,12 @@
return encoder;
}
-void WebResourceLoadStatisticsStore::populateFromDecoder(KeyedDecoder& decoder)
+void WebResourceLoadStatisticsStore::resetDataFromDecoder(KeyedDecoder& decoder)
{
ASSERT(!RunLoop::isMain());
- if (!m_resourceStatisticsMap.isEmpty())
- return;
+ clearInMemory();
+
unsigned versionOnDisk;
if (!decoder.decodeUInt32("version", versionOnDisk))
return;
Modified: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h (219452 => 219453)
--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h 2017-07-13 17:52:43 UTC (rev 219453)
@@ -27,6 +27,7 @@
#include "Connection.h"
#include "ResourceLoadStatisticsClassifier.h"
+#include "ResourceLoadStatisticsPersistentStorage.h"
#include <wtf/MonotonicTime.h>
#include <wtf/RunLoop.h>
#include <wtf/Vector.h>
@@ -42,7 +43,6 @@
}
namespace WebCore {
-class FileMonitor;
class KeyedDecoder;
class KeyedEncoder;
class URL;
@@ -55,7 +55,6 @@
enum class ShouldClearFirst;
-// FIXME: We should consider moving FileSystem I/O to a separate class.
class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
public:
using UpdateCookiePartitioningForDomainsHandler = WTF::Function<void(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst)>;
@@ -66,6 +65,9 @@
~WebResourceLoadStatisticsStore();
+ bool isEmpty() const { return m_resourceStatisticsMap.isEmpty(); }
+ WorkQueue& statisticsQueue() { return m_statisticsQueue.get(); }
+
void setNotifyPagesWhenDataRecordsWereScanned(bool value) { m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned = value; }
void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) { m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval = value; }
void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
@@ -109,33 +111,21 @@
void pruneStatisticsIfNeeded();
void resetParametersToDefaultValues();
+
+ std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
+ void resetDataFromDecoder(WebCore::KeyedDecoder&);
+ void clearInMemory();
+ void grandfatherExistingWebsiteData();
+ void includeTodayAsOperatingDateIfNecessary();
private:
WebResourceLoadStatisticsStore(const String&, UpdateCookiePartitioningForDomainsHandler&&);
- void readDataFromDiskIfNeeded();
-
void removeDataRecords();
- void startMonitoringStatisticsStorage();
- void stopMonitoringStatisticsStorage();
- String statisticsStoragePath() const;
- String resourceLogFilePath() const;
-
// IPC::MessageReceiver
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
- void grandfatherExistingWebsiteData();
-
- void writeStoreToDisk();
- void scheduleOrWriteStoreToDisk();
- std::unique_ptr<WebCore::KeyedDecoder> createDecoderFromDisk(const String& path) const;
- WallTime statisticsFileModificationTime(const String& label) const;
- void platformExcludeFromBackup() const;
- void deleteStoreFromDisk();
- void syncWithExistingStatisticsStorageIfNeeded();
- void refreshFromDisk();
- bool hasStatisticsFileChangedSinceLastSync(const String& path) const;
void performDailyTasks();
bool shouldRemoveDataRecords() const;
void setDataRecordsBeingRemoved(bool);
@@ -143,15 +133,11 @@
bool shouldPartitionCookies(const WebCore::ResourceLoadStatistics&) const;
bool hasStatisticsExpired(const WebCore::ResourceLoadStatistics&) const;
bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
- void includeTodayAsOperatingDateIfNecessary();
Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
void updateCookiePartitioning();
void updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
- std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
- void populateFromDecoder(WebCore::KeyedDecoder&);
- void clearInMemory();
void resetCookiePartitioningState();
@@ -178,15 +164,12 @@
ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
#endif
Ref<WTF::WorkQueue> m_statisticsQueue;
- std::unique_ptr<WebCore::FileMonitor> m_statisticsStorageMonitor;
+ ResourceLoadStatisticsPersistentStorage m_persistentStorage;
Deque<WTF::WallTime> m_operatingDates;
UpdateCookiePartitioningForDomainsHandler m_updateCookiePartitioningForDomainsHandler;
WallTime m_endOfGrandfatheringTimestamp;
- const String m_statisticsStoragePath;
- WallTime m_lastStatisticsFileSyncTime;
- MonotonicTime m_lastStatisticsWriteTime;
RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
MonotonicTime m_lastTimeDataRecordsWereRemoved;
@@ -193,7 +176,6 @@
Parameters m_parameters;
bool m_dataRecordsBeingRemoved { false };
- bool m_didScheduleWrite { false };
};
} // namespace WebKit
Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (219452 => 219453)
--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2017-07-13 17:34:52 UTC (rev 219452)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj 2017-07-13 17:52:43 UTC (rev 219453)
@@ -1334,6 +1334,7 @@
8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */; };
831EEBBD1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h in Headers */ = {isa = PBXBuildFile; fileRef = 831EEBBB1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h */; };
831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */; };
+ 8324355C1F1714670035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */; };
832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */; };
832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */; };
832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */; };
@@ -1347,6 +1348,8 @@
8372DB281A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */; };
8372DB291A67562800C697C5 /* WebPageDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */; };
8372DB2F1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB2E1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 83850C0C1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */; };
+ 83850C0D1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */; };
83891B631A68B3420030F386 /* APIDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B621A68B3420030F386 /* APIDiagnosticLoggingClient.h */; };
83891B691A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
83891B6C1A68C30B0030F386 /* DiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */; };
@@ -3631,6 +3634,7 @@
8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSubresourcesEntry.cpp; sourceTree = "<group>"; };
831EEBBB1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoad.h; sourceTree = "<group>"; };
831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoad.cpp; sourceTree = "<group>"; };
+ 8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoadStatisticsPersistentStorageIOS.mm; sourceTree = "<group>"; };
832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoadManager.h; sourceTree = "<group>"; };
832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoadManager.cpp; sourceTree = "<group>"; };
832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerActivityStateCPUUsageSampler.cpp; sourceTree = "<group>"; };
@@ -3644,6 +3648,8 @@
8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageDiagnosticLoggingClient.cpp; sourceTree = "<group>"; };
8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageDiagnosticLoggingClient.h; sourceTree = "<group>"; };
8372DB2E1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDiagnosticLoggingResultType.h; sourceTree = "<group>"; };
+ 83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadStatisticsPersistentStorage.cpp; sourceTree = "<group>"; };
+ 83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadStatisticsPersistentStorage.h; sourceTree = "<group>"; };
83891B621A68B3420030F386 /* APIDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIDiagnosticLoggingClient.h; sourceTree = "<group>"; };
83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDiagnosticLoggingDelegate.h; sourceTree = "<group>"; };
83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingClient.h; sourceTree = "<group>"; };
@@ -4702,6 +4708,8 @@
1A1D8BA01731A36300141DA4 /* LocalStorageDatabase.h */,
1A8C728A1738477C000A6554 /* LocalStorageDatabaseTracker.cpp */,
1A8C728B1738477C000A6554 /* LocalStorageDatabaseTracker.h */,
+ 83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */,
+ 83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */,
1A44B95916B73F9F00B7BBD8 /* StorageManager.cpp */,
1A44B95A16B73F9F00B7BBD8 /* StorageManager.h */,
1AB31A9316BC65AB00F6DBC9 /* StorageManager.messages.in */,
@@ -6014,6 +6022,7 @@
isa = PBXGroup;
children = (
5120C8301E54E2650025B250 /* LocalStorageDatabaseTrackerIOS.mm */,
+ 8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */,
);
path = ios;
sourceTree = "<group>";
@@ -8279,6 +8288,7 @@
1AD4C1931B39F33200ABC28E /* ApplicationStateTracker.h in Headers */,
1AEFD27911D16C81008219D3 /* ArgumentCoder.h in Headers */,
1AEFD2F711D1807B008219D3 /* ArgumentCoders.h in Headers */,
+ 83850C0D1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.h in Headers */,
1AAF0C4A12B16334008E49E2 /* ArgumentCodersCF.h in Headers */,
E179FD9C134D38060015B883 /* ArgumentCodersMac.h in Headers */,
CE1A0BD21A48E6C60054EF74 /* AssertionServicesSPI.h in Headers */,
@@ -9997,6 +10007,7 @@
E4436ECD1A0D040B00EAD204 /* NetworkCacheKey.cpp in Sources */,
831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */,
832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */,
+ 83850C0C1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp in Sources */,
83BDCCB91AC5FDB6003F6441 /* NetworkCacheStatistics.cpp in Sources */,
E4436ED01A0D040B00EAD204 /* NetworkCacheStorage.cpp in Sources */,
8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */,
@@ -10584,6 +10595,7 @@
1ACC50F11CBC381D003C7D03 /* WKOpenPanelParameters.mm in Sources */,
BC85806312B8505700EDEB2E /* WKOpenPanelParametersRef.cpp in Sources */,
BC85806212B8505700EDEB2E /* WKOpenPanelResultListener.cpp in Sources */,
+ 8324355C1F1714670035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm in Sources */,
BCD597D6112B56DC00EC8C23 /* WKPage.cpp in Sources */,
7C89D29B1A67837B003A5FDE /* WKPageConfigurationRef.cpp in Sources */,
BC7B633812A45ABA00D174A4 /* WKPageGroup.cpp in Sources */,