[GTK][WPE] Add DeviceIdHashSaltStorage disk persistence
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Dec 2018 20:00:41 +0000 (20:00 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Dec 2018 20:00:41 +0000 (20:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190466

Patch by Alejandro G. Castro <alex@igalia.com> on 2018-12-21
Reviewed by Youenn Fablet.

Source/WebCore:

Added persistency to the DeviceIdHashSaltStorage.

* platform/glib/FileSystemGlib.cpp:
(WebCore::FileSystem::getFileSize): Implemented this function to
allow sharing code with the statistics storage class.
* platform/glib/KeyedDecoderGlib.cpp:
(WebCore::KeyedDecoderGlib::dictionaryFromGVariant): Added a
condition to control situations where the key is empty, it can
happen if the user modifies the file in the disk.
* Modules/indexeddb/shared/IDBResourceIdentifier.cpp: Add include
to make work compilation with debug, unified builds.

Source/WebKit:

Added persistency to the DeviceIdHashSaltStorage. Implemented a
decoder and an encoder for the HashSaltForOrigin struct to store
it in a file, this allows us to save the lastTimeUsed, the origin
and the hash salt. It uses a new directory where it creates a file
per hash salt, the name of the file is the hash salt to avoid
leaking information in the system. The last time used and the
origin are stored inside the file, it also adds a version
directory used to change the structure of the file in the future,
if we need to do it. In the DeviceIdHashSaltStorage class the disk
operations happen in a WorkQueue, but all interactions go in the
main thread. We added code to handle the operations when the load
still did not finish.

* Platform/Logging.h:
Added channel DiskPersistency..
* Sources.txt: Added new files.
* UIProcess/API/APIProcessPoolConfiguration.cpp: Added code to set
the directory for the deviceIdHashSalts. That way we can use the
configuration when creating the DeviceIdHashSaltStorage.
(API::ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration):
(API::ProcessPoolConfiguration::ProcessPoolConfiguration):
(API::ProcessPoolConfiguration::copy):
* UIProcess/API/APIProcessPoolConfiguration.h:
* UIProcess/API/APIWebsiteDataStore.cpp:
(API::WebsiteDataStore::legacyDefaultDataStoreConfiguration):
Added code to set the directory in the disk used to store the
information.
* UIProcess/API/APIWebsiteDataStore.h: Ditto.
* UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm: Added dummy
implementation to get the directory in cocoa.
(API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
(API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
* UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp: Defined the
default directories used to store the information in the disk.
(API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
(API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
(API::WebsiteDataStore::defaultDataStoreConfiguration):
* UIProcess/API/glib/WebKitWebsiteDataManager.cpp:
(webkitWebsiteDataManagerGetDataStore): Added the directory used
to store the information.
(webkit_website_data_manager_remove): Modified the way we use to
make sure when we remove the cookies we also remove the hash salts.
* UIProcess/API/win/APIWebsiteDataStoreWin.cpp: Added dummy
implementations to get the directory in windows platform.
(API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
(API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
* UIProcess/API/C/WKBackForwardListItemRef.cpp: Add namespace, it
seems some unified build compilation issue.
* UIProcess/DeviceIdHashSaltStorage.cpp:
(WebKit::DeviceIdHashSaltStorage::create): Added a create method
used to pass the directory and the persistency status of the websitedatastore.
(WebKit::DeviceIdHashSaltStorage::completeHandler): Added to share
the code copying the origins to complete the get handler.
(WebKit::DeviceIdHashSaltStorage::completeDeviceIdHashSaltForOriginCall):
Added to share the code when completing the task of getting a new
hash salt.
(WebKit::DeviceIdHashSaltStorage::DeviceIdHashSaltStorage): Added
a new constructor for the create method.
(WebKit::getSecurityOriginData): Added to get the
SecurityOriginData from a field in the decoder and do all the
checks.
(WebKit::DeviceIdHashSaltStorage::loadStorageFromDisk): Open the
directory and restore all the hash salts from disk to the memory
structure.
(WebKit::DeviceIdHashSaltStorage::createEncoderFromData const):
Creates the decoder to store the HashSaltForOrigin structure.
(WebKit::DeviceIdHashSaltStorage::storeHashSaltToDisk): Write to
disk a decoder object created from a HashSaltForOrigin
structure. It uses the writeEncoderToDisk function.
(WebKit::DeviceIdHashSaltStorage::deviceIdHashSaltForOrigin): Make
sure we store in disk a new hash salt when it is generated and the
WebsiteDataStore is persistent. Add a completionHandler to return
the value found or generated, this way we can control if the
HashMap is already loaded from disk.
(WebKit::DeviceIdHashSaltStorage::getDeviceIdHashSaltOrigins):
Make sure we run the get in a queue now that we store information
in disk.
(WebKit::DeviceIdHashSaltStorage::deleteHashSaltFromDiskIfNeeded):
Added code to make sure we remove the files in disk.
(WebKit::DeviceIdHashSaltStorage::deleteDeviceIdHashSaltForOrigins):
Added code to use the deleteHashSaltFromDiskIfNeeded and remove the files in disk.
(WebKit::DeviceIdHashSaltStorage::deleteDeviceIdHashSaltOriginsModifiedSince):
Added code to use the deleteHashSaltFromDiskIfNeeded and remove the files in disk.
* UIProcess/DeviceIdHashSaltStorage.h: Ditto.
* UIProcess/PersistencyUtils.cpp: Added file to share the
persistency code with the ResourceLoadStatisticsPersistentStorage class.
(WebKit::createDecoderForFile): Ditto.
(WebKit::writeEncoderToDisk): Ditto.
* UIProcess/PersistencyUtils.h: Ditto.
* UIProcess/ResourceLoadStatisticsPersistentStorage.cpp: Use the
new PersistencyUtils functions shared with the
DeviceIdHashSaltStorage class.
(WebKit::ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk):
(WebKit::ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk):
(WebKit::ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk):
* UIProcess/UserMediaPermissionRequestManagerProxy.cpp: After
changing the API of the deviceIdHashSaltForOrigin we now use a
completionHandler because it could happen the HashMap is not still
loaded and we would have to wait for it. We refactored the calls
to the method to use this new completionHandler.
(WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted):
(WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
(WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame):
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::WebsiteDataStore): Create the
DeviceIdHashSaltStorage class with the persistency information.
(WebKit::WebsiteDataStore::resolveDirectoriesIfNecessary): Make
sure we have the directory to store the information.
* UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h: Add get
and set functions for the deviceHashSaltStorageDirectory.
* WebKit.xcodeproj/project.pbxproj: Added PersistencyUtils file to
the xcode compilation.

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

27 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/shared/IDBResourceIdentifier.cpp
Source/WebCore/platform/glib/FileSystemGlib.cpp
Source/WebCore/platform/glib/KeyedDecoderGlib.cpp
Source/WebKit/ChangeLog
Source/WebKit/Platform/Logging.h
Source/WebKit/Sources.txt
Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp
Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h
Source/WebKit/UIProcess/API/APIWebsiteDataStore.cpp
Source/WebKit/UIProcess/API/APIWebsiteDataStore.h
Source/WebKit/UIProcess/API/C/WKBackForwardListItemRef.cpp
Source/WebKit/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm
Source/WebKit/UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp
Source/WebKit/UIProcess/API/glib/WebKitWebsiteDataManager.cpp
Source/WebKit/UIProcess/API/win/APIWebsiteDataStoreWin.cpp
Source/WebKit/UIProcess/DeviceIdHashSaltStorage.cpp
Source/WebKit/UIProcess/DeviceIdHashSaltStorage.h
Source/WebKit/UIProcess/PersistencyUtils.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/PersistencyUtils.h [new file with mode: 0644]
Source/WebKit/UIProcess/ResourceLoadStatisticsPersistentStorage.cpp
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp
Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj

index 1e56380..5442c2c 100644 (file)
@@ -1,3 +1,22 @@
+2018-12-21  Alejandro G. Castro  <alex@igalia.com>
+
+        [GTK][WPE] Add DeviceIdHashSaltStorage disk persistence
+        https://bugs.webkit.org/show_bug.cgi?id=190466
+
+        Reviewed by Youenn Fablet.
+
+        Added persistency to the DeviceIdHashSaltStorage.
+
+        * platform/glib/FileSystemGlib.cpp:
+        (WebCore::FileSystem::getFileSize): Implemented this function to
+        allow sharing code with the statistics storage class.
+        * platform/glib/KeyedDecoderGlib.cpp:
+        (WebCore::KeyedDecoderGlib::dictionaryFromGVariant): Added a
+        condition to control situations where the key is empty, it can
+        happen if the user modifies the file in the disk.
+        * Modules/indexeddb/shared/IDBResourceIdentifier.cpp: Add include
+        to make work compilation with debug, unified builds.
+
 2018-12-21  Zalan Bujtas  <zalan@apple.com>
 
         Synchronous media query evaluation could destroy current Frame/FrameView.
index d7e3f17..f673b2d 100644 (file)
@@ -32,6 +32,7 @@
 #include "IDBConnectionToServer.h"
 #include "IDBRequest.h"
 #include <wtf/MainThread.h>
+#include <wtf/text/StringConcatenateNumbers.h>
 
 namespace WebCore {
 
index 6f70fd8..ca6c3df 100644 (file)
@@ -145,10 +145,14 @@ bool getFileSize(const String& path, long long& resultSize)
     return true;
 }
 
-bool getFileSize(PlatformFileHandle, long long&)
+bool getFileSize(PlatformFileHandle handle, long long& resultSize)
 {
-    notImplemented();
-    return false;
+    auto info = g_file_io_stream_query_info(handle, G_FILE_ATTRIBUTE_STANDARD_SIZE, nullptr, nullptr);
+    if (!info)
+        return false;
+
+    resultSize = g_file_info_get_size(info);
+    return true;
 }
 
 Optional<WallTime> getFileCreationTime(const String&)
index ec817bb..e7dd191 100644 (file)
@@ -56,8 +56,10 @@ HashMap<String, GRefPtr<GVariant>> KeyedDecoderGlib::dictionaryFromGVariant(GVar
     g_variant_iter_init(&iter, variant);
     const char* key;
     GVariant* value;
-    while (g_variant_iter_loop(&iter, "{&sv}", &key, &value))
-        dictionary.set(String::fromUTF8(key), value);
+    while (g_variant_iter_loop(&iter, "{&sv}", &key, &value)) {
+        if (key)
+            dictionary.set(String::fromUTF8(key), value);
+    }
     return dictionary;
 }
 
index 5c3ec33..9d29f94 100644 (file)
@@ -1,3 +1,123 @@
+2018-12-21  Alejandro G. Castro  <alex@igalia.com>
+
+        [GTK][WPE] Add DeviceIdHashSaltStorage disk persistence
+        https://bugs.webkit.org/show_bug.cgi?id=190466
+
+        Reviewed by Youenn Fablet.
+
+        Added persistency to the DeviceIdHashSaltStorage. Implemented a
+        decoder and an encoder for the HashSaltForOrigin struct to store
+        it in a file, this allows us to save the lastTimeUsed, the origin
+        and the hash salt. It uses a new directory where it creates a file
+        per hash salt, the name of the file is the hash salt to avoid
+        leaking information in the system. The last time used and the
+        origin are stored inside the file, it also adds a version
+        directory used to change the structure of the file in the future,
+        if we need to do it. In the DeviceIdHashSaltStorage class the disk
+        operations happen in a WorkQueue, but all interactions go in the
+        main thread. We added code to handle the operations when the load
+        still did not finish.
+
+        * Platform/Logging.h:
+        Added channel DiskPersistency..
+        * Sources.txt: Added new files.
+        * UIProcess/API/APIProcessPoolConfiguration.cpp: Added code to set
+        the directory for the deviceIdHashSalts. That way we can use the
+        configuration when creating the DeviceIdHashSaltStorage.
+        (API::ProcessPoolConfiguration::createWithWebsiteDataStoreConfiguration):
+        (API::ProcessPoolConfiguration::ProcessPoolConfiguration):
+        (API::ProcessPoolConfiguration::copy):
+        * UIProcess/API/APIProcessPoolConfiguration.h:
+        * UIProcess/API/APIWebsiteDataStore.cpp:
+        (API::WebsiteDataStore::legacyDefaultDataStoreConfiguration):
+        Added code to set the directory in the disk used to store the
+        information.
+        * UIProcess/API/APIWebsiteDataStore.h: Ditto.
+        * UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm: Added dummy
+        implementation to get the directory in cocoa.
+        (API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
+        (API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
+        * UIProcess/API/glib/APIWebsiteDataStoreGLib.cpp: Defined the
+        default directories used to store the information in the disk.
+        (API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
+        (API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
+        (API::WebsiteDataStore::defaultDataStoreConfiguration):
+        * UIProcess/API/glib/WebKitWebsiteDataManager.cpp:
+        (webkitWebsiteDataManagerGetDataStore): Added the directory used
+        to store the information.
+        (webkit_website_data_manager_remove): Modified the way we use to
+        make sure when we remove the cookies we also remove the hash salts.
+        * UIProcess/API/win/APIWebsiteDataStoreWin.cpp: Added dummy
+        implementations to get the directory in windows platform.
+        (API::WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory):
+        (API::WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory):
+        * UIProcess/API/C/WKBackForwardListItemRef.cpp: Add namespace, it
+        seems some unified build compilation issue.
+        * UIProcess/DeviceIdHashSaltStorage.cpp:
+        (WebKit::DeviceIdHashSaltStorage::create): Added a create method
+        used to pass the directory and the persistency status of the websitedatastore.
+        (WebKit::DeviceIdHashSaltStorage::completeHandler): Added to share
+        the code copying the origins to complete the get handler.
+        (WebKit::DeviceIdHashSaltStorage::completeDeviceIdHashSaltForOriginCall):
+        Added to share the code when completing the task of getting a new
+        hash salt.
+        (WebKit::DeviceIdHashSaltStorage::DeviceIdHashSaltStorage): Added
+        a new constructor for the create method.
+        (WebKit::getSecurityOriginData): Added to get the
+        SecurityOriginData from a field in the decoder and do all the
+        checks.
+        (WebKit::DeviceIdHashSaltStorage::loadStorageFromDisk): Open the
+        directory and restore all the hash salts from disk to the memory
+        structure.
+        (WebKit::DeviceIdHashSaltStorage::createEncoderFromData const):
+        Creates the decoder to store the HashSaltForOrigin structure.
+        (WebKit::DeviceIdHashSaltStorage::storeHashSaltToDisk): Write to
+        disk a decoder object created from a HashSaltForOrigin
+        structure. It uses the writeEncoderToDisk function.
+        (WebKit::DeviceIdHashSaltStorage::deviceIdHashSaltForOrigin): Make
+        sure we store in disk a new hash salt when it is generated and the
+        WebsiteDataStore is persistent. Add a completionHandler to return
+        the value found or generated, this way we can control if the
+        HashMap is already loaded from disk.
+        (WebKit::DeviceIdHashSaltStorage::getDeviceIdHashSaltOrigins):
+        Make sure we run the get in a queue now that we store information
+        in disk.
+        (WebKit::DeviceIdHashSaltStorage::deleteHashSaltFromDiskIfNeeded):
+        Added code to make sure we remove the files in disk.
+        (WebKit::DeviceIdHashSaltStorage::deleteDeviceIdHashSaltForOrigins):
+        Added code to use the deleteHashSaltFromDiskIfNeeded and remove the files in disk.
+        (WebKit::DeviceIdHashSaltStorage::deleteDeviceIdHashSaltOriginsModifiedSince):
+        Added code to use the deleteHashSaltFromDiskIfNeeded and remove the files in disk.
+        * UIProcess/DeviceIdHashSaltStorage.h: Ditto.
+        * UIProcess/PersistencyUtils.cpp: Added file to share the
+        persistency code with the ResourceLoadStatisticsPersistentStorage class.
+        (WebKit::createDecoderForFile): Ditto.
+        (WebKit::writeEncoderToDisk): Ditto.
+        * UIProcess/PersistencyUtils.h: Ditto.
+        * UIProcess/ResourceLoadStatisticsPersistentStorage.cpp: Use the
+        new PersistencyUtils functions shared with the
+        DeviceIdHashSaltStorage class.
+        (WebKit::ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk):
+        (WebKit::ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk):
+        (WebKit::ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk):
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp: After
+        changing the API of the deviceIdHashSaltForOrigin we now use a
+        completionHandler because it could happen the HashMap is not still
+        loaded and we would have to wait for it. We refactored the calls
+        to the method to use this new completionHandler.
+        (WebKit::UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted):
+        (WebKit::UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame):
+        (WebKit::UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame):
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::WebsiteDataStore): Create the
+        DeviceIdHashSaltStorage class with the persistency information.
+        (WebKit::WebsiteDataStore::resolveDirectoriesIfNecessary): Make
+        sure we have the directory to store the information.
+        * UIProcess/WebsiteData/WebsiteDataStoreConfiguration.h: Add get
+        and set functions for the deviceHashSaltStorageDirectory.
+        * WebKit.xcodeproj/project.pbxproj: Added PersistencyUtils file to
+        the xcode compilation.
+
 2018-12-20  Alex Christensen  <achristensen@webkit.org>
 
         Remove unused NetworkProcessCreationParameters
index 9ca23cf..59cee85 100644 (file)
@@ -46,6 +46,7 @@ extern "C" {
     M(CacheStorage) \
     M(ContentObservation) \
     M(ContextMenu) \
+    M(DiskPersistency) \
     M(DragAndDrop) \
     M(Fullscreen) \
     M(Gamepad) \
index b52ae6b..e0a3282 100644 (file)
@@ -218,13 +218,14 @@ Shared/WebsiteData/WebsiteData.cpp
 
 UIProcess/BackgroundProcessResponsivenessTimer.cpp
 UIProcess/ChildProcessProxy.cpp
+UIProcess/DeviceIdHashSaltStorage.cpp
 UIProcess/DrawingAreaProxy.cpp
 UIProcess/FrameLoadState.cpp
 UIProcess/GeolocationPermissionRequestManagerProxy.cpp
 UIProcess/GeolocationPermissionRequestProxy.cpp
 UIProcess/InspectorTargetProxy.cpp
 UIProcess/PageLoadState.cpp
-UIProcess/DeviceIdHashSaltStorage.cpp
+UIProcess/PersistencyUtils.cpp
 UIProcess/ProcessAssertion.cpp
 UIProcess/ProcessThrottler.cpp
 UIProcess/RemoteWebInspectorProxy.cpp
index 9e881c7..4d91caf 100644 (file)
@@ -57,6 +57,7 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::createWithWebsiteDataSto
     configuration->m_mediaCacheDirectory = legacyConfiguration.mediaCacheDirectory();
     configuration->m_indexedDBDatabaseDirectory = WebsiteDataStore::legacyDefaultIndexedDBDatabaseDirectory();
     configuration->m_localStorageDirectory = legacyConfiguration.localStorageDirectory();
+    configuration->m_deviceIdHashSaltsStorageDirectory = legacyConfiguration.deviceIdHashSaltsStorageDirectory();
     configuration->m_mediaKeysStorageDirectory = legacyConfiguration.mediaKeysStorageDirectory();
     configuration->m_resourceLoadStatisticsDirectory = legacyConfiguration.resourceLoadStatisticsDirectory();
     configuration->m_webSQLDatabaseDirectory = legacyConfiguration.webSQLDatabaseDirectory();
@@ -72,6 +73,7 @@ ProcessPoolConfiguration::ProcessPoolConfiguration()
     , m_mediaCacheDirectory(WebsiteDataStore::defaultMediaCacheDirectory())
     , m_indexedDBDatabaseDirectory(WebsiteDataStore::defaultIndexedDBDatabaseDirectory())
     , m_localStorageDirectory(WebsiteDataStore::defaultLocalStorageDirectory())
+    , m_deviceIdHashSaltsStorageDirectory(WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory())
     , m_webSQLDatabaseDirectory(WebsiteDataStore::defaultWebSQLDatabaseDirectory())
     , m_mediaKeysStorageDirectory(WebsiteDataStore::defaultMediaKeysStorageDirectory())
     , m_resourceLoadStatisticsDirectory(WebsiteDataStore::defaultResourceLoadStatisticsDirectory())
@@ -98,6 +100,7 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
     copy->m_indexedDBDatabaseDirectory = this->m_indexedDBDatabaseDirectory;
     copy->m_injectedBundlePath = this->m_injectedBundlePath;
     copy->m_localStorageDirectory = this->m_localStorageDirectory;
+    copy->m_deviceIdHashSaltsStorageDirectory = this->m_deviceIdHashSaltsStorageDirectory;
     copy->m_mediaKeysStorageDirectory = this->m_mediaKeysStorageDirectory;
     copy->m_resourceLoadStatisticsDirectory = this->m_resourceLoadStatisticsDirectory;
     copy->m_javaScriptConfigurationDirectory = this->m_javaScriptConfigurationDirectory;
index dad1c05..db77f84 100644 (file)
@@ -96,6 +96,9 @@ public:
     const WTF::String& localStorageDirectory() const { return m_localStorageDirectory; }
     void setLocalStorageDirectory(const WTF::String& localStorageDirectory) { m_localStorageDirectory = localStorageDirectory; }
 
+    const WTF::String& deviceIdHashSaltsStorageDirectory() const { return m_deviceIdHashSaltsStorageDirectory; }
+    void setDeviceIdHashSaltsStorageDirectory(const WTF::String& directory) { m_deviceIdHashSaltsStorageDirectory = directory; }
+
     const WTF::String& webSQLDatabaseDirectory() const { return m_webSQLDatabaseDirectory; }
     void setWebSQLDatabaseDirectory(const WTF::String& webSQLDatabaseDirectory) { m_webSQLDatabaseDirectory = webSQLDatabaseDirectory; }
 
@@ -195,6 +198,7 @@ private:
     WTF::String m_indexedDBDatabaseDirectory;
     WTF::String m_injectedBundlePath;
     WTF::String m_localStorageDirectory;
+    WTF::String m_deviceIdHashSaltsStorageDirectory;
     WTF::String m_webSQLDatabaseDirectory;
     WTF::String m_mediaKeysStorageDirectory;
     WTF::String m_resourceLoadStatisticsDirectory;
index e5308b6..dbdbf9c 100644 (file)
@@ -139,6 +139,7 @@ Ref<WebKit::WebsiteDataStoreConfiguration> WebsiteDataStore::legacyDefaultDataSt
     configuration->setNetworkCacheDirectory(legacyDefaultNetworkCacheDirectory());
     configuration->setMediaCacheDirectory(legacyDefaultMediaCacheDirectory());
     configuration->setMediaKeysStorageDirectory(legacyDefaultMediaKeysStorageDirectory());
+    configuration->setDeviceIdHashSaltsStorageDirectory(legacyDefaultDeviceIdHashSaltsStorageDirectory());
     configuration->setIndexedDBDatabaseDirectory(legacyDefaultIndexedDBDatabaseDirectory());
     configuration->setWebSQLDatabaseDirectory(legacyDefaultWebSQLDatabaseDirectory());
     configuration->setLocalStorageDirectory(legacyDefaultLocalStorageDirectory());
index b857d69..9305950 100644 (file)
@@ -62,6 +62,7 @@ public:
     static WTF::String defaultServiceWorkerRegistrationDirectory();
     static WTF::String defaultLocalStorageDirectory();
     static WTF::String defaultMediaKeysStorageDirectory();
+    static WTF::String defaultDeviceIdHashSaltsStorageDirectory();
     static WTF::String defaultWebSQLDatabaseDirectory();
     static WTF::String defaultResourceLoadStatisticsDirectory();
     static WTF::String defaultJavaScriptConfigurationDirectory();
@@ -74,6 +75,7 @@ public:
     static WTF::String legacyDefaultIndexedDBDatabaseDirectory();
     static WTF::String legacyDefaultWebSQLDatabaseDirectory();
     static WTF::String legacyDefaultMediaKeysStorageDirectory();
+    static WTF::String legacyDefaultDeviceIdHashSaltsStorageDirectory();
     static WTF::String legacyDefaultMediaCacheDirectory();
     static WTF::String legacyDefaultJavaScriptConfigurationDirectory();
 
index 0aee82e..6f6607b 100644 (file)
@@ -29,6 +29,8 @@
 #include "WKAPICast.h"
 #include "WebBackForwardListItem.h"
 
+using namespace WebKit;
+
 WKTypeID WKBackForwardListItemGetTypeID()
 {
     return WebKit::toAPI(WebBackForwardListItem::APIType);
index 97647ce..4a2ec38 100644 (file)
@@ -95,6 +95,12 @@ WTF::String WebsiteDataStore::defaultMediaKeysStorageDirectory()
     return websiteDataDirectoryFileSystemRepresentation("MediaKeys");
 }
 
+WTF::String WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory()
+{
+    // Not implemented.
+    return String();
+}
+
 WTF::String WebsiteDataStore::defaultWebSQLDatabaseDirectory()
 {
     return websiteDataDirectoryFileSystemRepresentation("WebSQL");
@@ -199,6 +205,12 @@ WTF::String WebsiteDataStore::legacyDefaultMediaKeysStorageDirectory()
     return WebKit::stringByResolvingSymlinksInPath([mediaKeysStorageDirectory stringByStandardizingPath]);
 }
 
+WTF::String WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory()
+{
+    // Not implemented.
+    return String();
+}
+
 WTF::String WebsiteDataStore::legacyDefaultJavaScriptConfigurationDirectory()
 {
 #if PLATFORM(IOS_FAMILY)
index 17d2a40..e1c4529 100644 (file)
@@ -74,6 +74,11 @@ WTF::String WebsiteDataStore::defaultMediaKeysStorageDirectory()
     return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S "mediakeys");
 }
 
+String WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory()
+{
+    return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S "deviceidhashsalts");
+}
+
 WTF::String WebsiteDataStore::defaultWebSQLDatabaseDirectory()
 {
     return websiteDataDirectoryFileSystemRepresentation(BASE_DIRECTORY G_DIR_SEPARATOR_S "databases");
@@ -157,6 +162,15 @@ WTF::String WebsiteDataStore::legacyDefaultMediaKeysStorageDirectory()
     return defaultMediaKeysStorageDirectory();
 }
 
+String WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory()
+{
+#if PLATFORM(WPE)
+    GUniquePtr<gchar> deviceIdHashSaltsStorageDirectory(g_build_filename(g_get_user_data_dir(), "wpe", "deviceidhashsalts", nullptr));
+    return WebCore::FileSystem::stringFromFileSystemRepresentation(deviceIdHashSaltsStorageDirectory.get());
+#endif
+    return defaultDeviceIdHashSaltsStorageDirectory();
+}
+
 WTF::String WebsiteDataStore::legacyDefaultJavaScriptConfigurationDirectory()
 {
     GUniquePtr<gchar> javaScriptCoreConfigDirectory(g_build_filename(g_get_user_data_dir(), BASE_DIRECTORY, "JavaScriptCoreDebug", nullptr));
@@ -176,8 +190,10 @@ Ref<WebKit::WebsiteDataStoreConfiguration> WebsiteDataStore::defaultDataStoreCon
     configuration->setLocalStorageDirectory(defaultLocalStorageDirectory());
     configuration->setMediaKeysStorageDirectory(defaultMediaKeysStorageDirectory());
     configuration->setResourceLoadStatisticsDirectory(defaultResourceLoadStatisticsDirectory());
+    configuration->setDeviceIdHashSaltsStorageDirectory(defaultDeviceIdHashSaltsStorageDirectory());
 
     return configuration;
 }
 
 } // namespace API
+
index 364f127..23bf6dd 100644 (file)
@@ -321,6 +321,7 @@ static inline Ref<WebsiteDataStoreConfiguration> websiteDataStoreConfigurationFo
     configuration->setNetworkCacheDirectory(String(processPoolconfigurarion.diskCacheDirectory()));
     configuration->setWebSQLDatabaseDirectory(String(processPoolconfigurarion.webSQLDatabaseDirectory()));
     configuration->setLocalStorageDirectory(String(processPoolconfigurarion.localStorageDirectory()));
+    configuration->setDeviceIdHashSaltsStorageDirectory(String(processPoolconfigurarion.deviceIdHashSaltsStorageDirectory()));
     configuration->setMediaKeysStorageDirectory(String(processPoolconfigurarion.mediaKeysStorageDirectory()));
     return configuration;
 }
index 7d0999d..7e1d14b 100644 (file)
@@ -730,16 +730,15 @@ void webkit_website_data_manager_remove(WebKitWebsiteDataManager* manager, WebKi
     g_return_if_fail(WEBKIT_IS_WEBSITE_DATA_MANAGER(manager));
     g_return_if_fail(websiteData);
 
+    // We have to remove the hash salts when cookies are removed.
+    if (types & WEBKIT_WEBSITE_DATA_COOKIES)
+        types = static_cast<WebKitWebsiteDataTypes>(types | WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT);
+
     Vector<WebsiteDataRecord> records;
     for (GList* item = websiteData; item; item = g_list_next(item)) {
         WebKitWebsiteData* data = static_cast<WebKitWebsiteData*>(item->data);
 
-        // We have to remove the hash salts when cookies are removed.
-        auto dataTypes = webkit_website_data_get_types(data);
-        if (dataTypes & WEBKIT_WEBSITE_DATA_DEVICE_ID_HASH_SALT)
-            dataTypes = static_cast<WebKitWebsiteDataTypes>(dataTypes | WEBKIT_WEBSITE_DATA_COOKIES);
-
-        if (dataTypes & types)
+        if (webkit_website_data_get_types(data) & types)
             records.append(webkitWebsiteDataGetRecord(data));
     }
 
index 285bb6d..19be288 100644 (file)
@@ -65,6 +65,12 @@ String WebsiteDataStore::defaultMediaKeysStorageDirectory()
     return WebCore::FileSystem::pathByAppendingComponent(WebCore::FileSystem::localUserSpecificStorageDirectory(), "MediaKeyStorage");
 }
 
+String WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory()
+{
+    // Not Implemented.
+    return String();
+}
+
 String WebsiteDataStore::defaultWebSQLDatabaseDirectory()
 {
     return WebCore::FileSystem::pathByAppendingComponent(WebCore::FileSystem::localUserSpecificStorageDirectory(), "WebSQL");
@@ -120,6 +126,12 @@ String WebsiteDataStore::legacyDefaultMediaKeysStorageDirectory()
     return WebCore::FileSystem::pathByAppendingComponent(WebCore::FileSystem::localUserSpecificStorageDirectory(), "MediaKeyStorage");
 }
 
+String WebsiteDataStore::legacyDefaultDeviceIdHashSaltsStorageDirectory()
+{
+    // Not Implemented.
+    return String();
+}
+
 String WebsiteDataStore::legacyDefaultJavaScriptConfigurationDirectory()
 {
     return WebCore::FileSystem::pathByAppendingComponent(WebCore::FileSystem::localUserSpecificStorageDirectory(), "JavaScriptCoreDebug");
index fc8582e..e60ee3f 100644 (file)
 #include "config.h"
 #include "DeviceIdHashSaltStorage.h"
 
+#include "PersistencyUtils.h"
+
 #include <WebCore/FileSystem.h>
+#include <WebCore/SharedBuffer.h>
 #include <wtf/CryptographicallyRandomNumber.h>
 #include <wtf/HexNumber.h>
 #include <wtf/RunLoop.h>
 #include <wtf/text/StringBuilder.h>
 #include <wtf/text/StringHash.h>
 
-// FIXME: Implement persistency.
-
 namespace WebKit {
 using namespace WebCore;
 
-static const int hashSaltSize = 48;
-static const int randomDataSize = hashSaltSize / 16;
+static constexpr unsigned deviceIdHashSaltStorageVersion { 1 };
+static constexpr unsigned hashSaltSize { 48 };
+static constexpr unsigned randomDataSize { hashSaltSize / 16 };
+
+Ref<DeviceIdHashSaltStorage> DeviceIdHashSaltStorage::create(const String& deviceIdHashSaltStorageDirectory)
+{
+    auto deviceIdHashSaltStorage = adoptRef(*new DeviceIdHashSaltStorage(deviceIdHashSaltStorageDirectory));
+    return deviceIdHashSaltStorage;
+}
+
+void DeviceIdHashSaltStorage::completePendingHandler(CompletionHandler<void(HashSet<SecurityOriginData>&&)>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+
+    HashSet<SecurityOriginData> origins;
+
+    for (auto& hashSaltForOrigin : m_deviceIdHashSaltForOrigins) {
+        origins.add(hashSaltForOrigin.value->documentOrigin);
+        origins.add(hashSaltForOrigin.value->parentOrigin);
+    }
+
+    RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
+        completionHandler(WTFMove(origins));
+    });
+}
+
+DeviceIdHashSaltStorage::DeviceIdHashSaltStorage(const String& deviceIdHashSaltStorageDirectory)
+    : m_queue(WorkQueue::create("com.apple.WebKit.DeviceIdHashSaltStorage"))
+    , m_deviceIdHashSaltStorageDirectory(!deviceIdHashSaltStorageDirectory.isEmpty() ? FileSystem::pathByAppendingComponent(deviceIdHashSaltStorageDirectory, String::number(deviceIdHashSaltStorageVersion)) : String())
+{
+    if (m_deviceIdHashSaltStorageDirectory.isEmpty()) {
+        m_isLoaded = true;
+        return;
+    }
+
+    loadStorageFromDisk([this, protectedThis = makeRef(*this)] (auto&& deviceIdHashSaltForOrigins) {
+        ASSERT(RunLoop::isMain());
+        m_deviceIdHashSaltForOrigins = WTFMove(deviceIdHashSaltForOrigins);
+        m_isLoaded = true;
+
+        auto pendingCompletionHandlers = WTFMove(m_pendingCompletionHandlers);
+        for (auto& completionHandler : pendingCompletionHandlers)
+            completionHandler();
+    });
+}
 
-Ref<DeviceIdHashSaltStorage> DeviceIdHashSaltStorage::create()
+DeviceIdHashSaltStorage::~DeviceIdHashSaltStorage()
 {
-    return adoptRef(*new DeviceIdHashSaltStorage());
+    auto pendingCompletionHandlers = WTFMove(m_pendingCompletionHandlers);
+    for (auto& completionHandler : pendingCompletionHandlers)
+        completionHandler();
 }
 
-const String& DeviceIdHashSaltStorage::deviceIdHashSaltForOrigin(const SecurityOrigin& documentOrigin, const SecurityOrigin& parentOrigin)
+static WTF::Optional<SecurityOriginData> getSecurityOriginData(const char* name, KeyedDecoder* decoder)
 {
-    auto origins = makeString(documentOrigin.toRawString(), parentOrigin.toRawString());
-    auto& deviceIdHashSalt = m_deviceIdHashSaltForOrigins.ensure(origins, [&documentOrigin, &parentOrigin] () {
+    String origin;
+
+    if (!decoder->decodeString(name, origin))
+        return WTF::nullopt;
+
+    auto securityOriginData = SecurityOriginData::fromDatabaseIdentifier(origin);
+    if (!securityOriginData)
+        return WTF::nullopt;
+
+    return securityOriginData;
+}
+
+void DeviceIdHashSaltStorage::loadStorageFromDisk(CompletionHandler<void(HashMap<String, std::unique_ptr<HashSaltForOrigin>>&&)>&& completionHandler)
+{
+    m_queue->dispatch([this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)]() mutable {
+        ASSERT(!RunLoop::isMain());
+
+        FileSystem::makeAllDirectories(m_deviceIdHashSaltStorageDirectory);
+
+        auto originPaths = FileSystem::listDirectory(m_deviceIdHashSaltStorageDirectory, "*");
+
+        HashMap<String, std::unique_ptr<HashSaltForOrigin>> deviceIdHashSaltForOrigins;
+        for (const auto& originPath : originPaths) {
+            URL url;
+            url.setProtocol("file"_s);
+            url.setPath(originPath);
+
+            String deviceIdHashSalt = url.lastPathComponent();
+
+            if (hashSaltSize != deviceIdHashSalt.length()) {
+                RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: The length of the hash salt (%d) is different to the length of the hash salts defined in WebKit (%d)", deviceIdHashSalt.length(), hashSaltSize);
+                continue;
+            }
+
+            long long fileSize = 0;
+            if (!FileSystem::getFileSize(originPath, fileSize)) {
+                RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: Impossible to get the file size of: '%s'", originPath.utf8().data());
+                continue;
+            }
+
+            auto decoder = createForFile(originPath);
+
+            if (!decoder) {
+                RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: Impossible to access the file to restore the hash salt: '%s'", originPath.utf8().data());
+                continue;
+            }
+
+            auto hashSaltForOrigin = getDataFromDecoder(decoder.get(), WTFMove(deviceIdHashSalt));
+
+            auto origins = makeString(hashSaltForOrigin->documentOrigin.toString(), hashSaltForOrigin->parentOrigin.toString());
+            auto deviceIdHashSaltForOrigin = deviceIdHashSaltForOrigins.ensure(origins, [hashSaltForOrigin = WTFMove(hashSaltForOrigin)] () mutable {
+                return WTFMove(hashSaltForOrigin);
+            });
+
+            if (!deviceIdHashSaltForOrigin.isNewEntry)
+                RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: There are two files with different hash salts for the same origin: '%s'", originPath.utf8().data());
+        }
+
+        RunLoop::main().dispatch([deviceIdHashSaltForOrigins = WTFMove(deviceIdHashSaltForOrigins), completionHandler = WTFMove(completionHandler)]() mutable {
+            completionHandler(WTFMove(deviceIdHashSaltForOrigins));
+        });
+    });
+}
+
+std::unique_ptr<DeviceIdHashSaltStorage::HashSaltForOrigin> DeviceIdHashSaltStorage::getDataFromDecoder(KeyedDecoder* decoder, String&& deviceIdHashSalt) const
+{
+    auto securityOriginData = getSecurityOriginData("origin", decoder);
+    if (!securityOriginData) {
+        RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: The security origin data in the file is not correct: '%s'", deviceIdHashSalt.utf8().data());
+        return nullptr;
+    }
+
+    auto parentSecurityOriginData = getSecurityOriginData("parentOrigin", decoder);
+    if (!parentSecurityOriginData) {
+        RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: The parent security origin data in the file is not correct: '%s'", deviceIdHashSalt.utf8().data());
+        return nullptr;
+    }
+
+    double lastTimeUsed;
+    if (!decoder->decodeDouble("lastTimeUsed", lastTimeUsed)) {
+        RELEASE_LOG_ERROR(DiskPersistency, "DeviceIdHashSaltStorage: The last time used was not correctly restored for: '%s'", deviceIdHashSalt.utf8().data());
+        return nullptr;
+    }
+
+    auto hashSaltForOrigin = std::make_unique<HashSaltForOrigin>(WTFMove(securityOriginData.value()), WTFMove(parentSecurityOriginData.value()), WTFMove(deviceIdHashSalt));
+
+    hashSaltForOrigin->lastTimeUsed = WallTime::fromRawSeconds(lastTimeUsed);
+
+    return hashSaltForOrigin;
+}
+
+std::unique_ptr<KeyedEncoder> DeviceIdHashSaltStorage::createEncoderFromData(const HashSaltForOrigin& hashSaltForOrigin) const
+{
+    auto encoder = KeyedEncoder::encoder();
+    encoder->encodeString("origin", hashSaltForOrigin.documentOrigin.databaseIdentifier());
+    encoder->encodeString("parentOrigin", hashSaltForOrigin.parentOrigin.databaseIdentifier());
+    encoder->encodeDouble("lastTimeUsed", hashSaltForOrigin.lastTimeUsed.secondsSinceEpoch().value());
+    return encoder;
+}
+
+void DeviceIdHashSaltStorage::storeHashSaltToDisk(const HashSaltForOrigin& hashSaltForOrigin)
+{
+    if (m_deviceIdHashSaltStorageDirectory.isEmpty())
+        return;
+
+    m_queue->dispatch([this, protectedThis = makeRef(*this), hashSaltForOrigin = hashSaltForOrigin.isolatedCopy()]() mutable {
+        auto encoder = createEncoderFromData(hashSaltForOrigin);
+        writeToDisk(WTFMove(encoder), FileSystem::pathByAppendingComponent(m_deviceIdHashSaltStorageDirectory, hashSaltForOrigin.deviceIdHashSalt));
+    });
+}
+
+void DeviceIdHashSaltStorage::completeDeviceIdHashSaltForOriginCall(SecurityOriginData&& documentOrigin, SecurityOriginData&& parentOrigin, CompletionHandler<void(String&&)>&& completionHandler)
+{
+    auto origins = makeString(documentOrigin.toString(), parentOrigin.toString());
+    auto& deviceIdHashSalt = m_deviceIdHashSaltForOrigins.ensure(origins, [documentOrigin = WTFMove(documentOrigin), parentOrigin = WTFMove(parentOrigin)] () mutable {
         uint64_t randomData[randomDataSize];
         cryptographicallyRandomValues(reinterpret_cast<unsigned char*>(randomData), sizeof(randomData));
 
         StringBuilder builder;
         builder.reserveCapacity(hashSaltSize);
-        for (int i = 0; i < randomDataSize; i++)
+        for (unsigned i = 0; i < randomDataSize; i++)
             appendUnsigned64AsHex(randomData[i], builder);
 
         String deviceIdHashSalt = builder.toString();
 
-        return std::make_unique<HashSaltForOrigin>(documentOrigin.data().isolatedCopy(), parentOrigin.data().isolatedCopy(), WTFMove(deviceIdHashSalt));
+        auto newHashSaltForOrigin = std::make_unique<HashSaltForOrigin>(WTFMove(documentOrigin), WTFMove(parentOrigin), WTFMove(deviceIdHashSalt));
+
+        return newHashSaltForOrigin;
     }).iterator->value;
 
     deviceIdHashSalt->lastTimeUsed = WallTime::now();
 
-    return deviceIdHashSalt->deviceIdHashSalt;
+    storeHashSaltToDisk(*deviceIdHashSalt.get());
+
+    completionHandler(String(deviceIdHashSalt->deviceIdHashSalt));
+}
+
+void DeviceIdHashSaltStorage::deviceIdHashSaltForOrigin(const SecurityOrigin& documentOrigin, const SecurityOrigin& parentOrigin, CompletionHandler<void(String&&)>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+
+    if (!m_isLoaded) {
+        m_pendingCompletionHandlers.append([this, documentOrigin = documentOrigin.data().isolatedCopy(), parentOrigin = parentOrigin.data().isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
+            completeDeviceIdHashSaltForOriginCall(WTFMove(documentOrigin), WTFMove(parentOrigin), WTFMove(completionHandler));
+        });
+        return;
+    }
+
+    completeDeviceIdHashSaltForOriginCall(SecurityOriginData(documentOrigin.data()), SecurityOriginData(parentOrigin.data()), WTFMove(completionHandler));
 }
 
 void DeviceIdHashSaltStorage::getDeviceIdHashSaltOrigins(CompletionHandler<void(HashSet<SecurityOriginData>&&)>&& completionHandler)
 {
-    HashSet<SecurityOriginData> origins;
+    ASSERT(RunLoop::isMain());
 
-    for (auto& hashSaltForOrigin : m_deviceIdHashSaltForOrigins) {
-        origins.add(hashSaltForOrigin.value->documentOrigin);
-        origins.add(hashSaltForOrigin.value->parentOrigin);
+    if (!m_isLoaded) {
+        m_pendingCompletionHandlers.append([this, completionHandler = WTFMove(completionHandler)]() mutable {
+            completePendingHandler(WTFMove(completionHandler));
+        });
+        return;
     }
 
-    RunLoop::main().dispatch([origins = WTFMove(origins), completionHandler = WTFMove(completionHandler)]() mutable {
-        completionHandler(WTFMove(origins));
+    completePendingHandler(WTFMove(completionHandler));
+}
+
+void DeviceIdHashSaltStorage::deleteHashSaltFromDisk(const HashSaltForOrigin& hashSaltForOrigin)
+{
+    m_queue->dispatch([this, protectedThis = makeRef(*this), deviceIdHashSalt = hashSaltForOrigin.deviceIdHashSalt.isolatedCopy()]() mutable {
+        ASSERT(!RunLoop::isMain());
+
+        String fileFullPath = FileSystem::pathByAppendingComponent(m_deviceIdHashSaltStorageDirectory, deviceIdHashSalt.utf8().data());
+        FileSystem::deleteFile(fileFullPath);
     });
 }
 
 void DeviceIdHashSaltStorage::deleteDeviceIdHashSaltForOrigins(const Vector<SecurityOriginData>& origins, CompletionHandler<void()>&& completionHandler)
 {
-    m_deviceIdHashSaltForOrigins.removeIf([&origins](auto& keyAndValue) {
-        return origins.contains(keyAndValue.value->documentOrigin) || origins.contains(keyAndValue.value->parentOrigin);
+    ASSERT(RunLoop::isMain());
+
+    m_deviceIdHashSaltForOrigins.removeIf([this, &origins](auto& keyAndValue) {
+        bool needsRemoval = origins.contains(keyAndValue.value->documentOrigin) || origins.contains(keyAndValue.value->parentOrigin);
+        if (m_deviceIdHashSaltStorageDirectory.isEmpty())
+            return needsRemoval;
+        if (needsRemoval)
+            this->deleteHashSaltFromDisk(*keyAndValue.value.get());
+        return needsRemoval;
     });
 
     RunLoop::main().dispatch(WTFMove(completionHandler));
@@ -93,8 +287,15 @@ void DeviceIdHashSaltStorage::deleteDeviceIdHashSaltForOrigins(const Vector<Secu
 
 void DeviceIdHashSaltStorage::deleteDeviceIdHashSaltOriginsModifiedSince(WallTime time, CompletionHandler<void()>&& completionHandler)
 {
-    m_deviceIdHashSaltForOrigins.removeIf([time](auto& keyAndValue) {
-        return keyAndValue.value->lastTimeUsed > time;
+    ASSERT(RunLoop::isMain());
+
+    m_deviceIdHashSaltForOrigins.removeIf([this, time](auto& keyAndValue) {
+        bool needsRemoval = keyAndValue.value->lastTimeUsed > time;
+        if (m_deviceIdHashSaltStorageDirectory.isEmpty())
+            return needsRemoval;
+        if (needsRemoval)
+            this->deleteHashSaltFromDisk(*keyAndValue.value.get());
+        return needsRemoval;
     });
 
     RunLoop::main().dispatch(WTFMove(completionHandler));
index 5fe2a86..cacd469 100644 (file)
 #pragma once
 
 #include "UserMediaPermissionCheckProxy.h"
+#include <WebCore/KeyedCoding.h>
 #include <WebCore/SecurityOrigin.h>
+#include <wtf/CompletionHandler.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/Ref.h>
+#include <wtf/WorkQueue.h>
 
 namespace WebKit {
 
-class DeviceIdHashSaltStorage : public RefCounted<DeviceIdHashSaltStorage> {
+class DeviceIdHashSaltStorage : public ThreadSafeRefCounted<DeviceIdHashSaltStorage, WTF::DestructionThread::Main> {
 public:
-    static Ref<DeviceIdHashSaltStorage> create();
-    ~DeviceIdHashSaltStorage() = default;
+    static Ref<DeviceIdHashSaltStorage> create(const String& deviceIdHashSaltStorageDirectory);
+    ~DeviceIdHashSaltStorage();
 
-    const String& deviceIdHashSaltForOrigin(const WebCore::SecurityOrigin& documentOrigin, const WebCore::SecurityOrigin& parentOrigin);
+    void deviceIdHashSaltForOrigin(const WebCore::SecurityOrigin& documentOrigin, const WebCore::SecurityOrigin& parentOrigin, CompletionHandler<void(String&&)>&&);
 
     void getDeviceIdHashSaltOrigins(CompletionHandler<void(HashSet<WebCore::SecurityOriginData>&&)>&&);
     void deleteDeviceIdHashSaltForOrigins(const Vector<WebCore::SecurityOriginData>&, CompletionHandler<void()>&&);
@@ -53,15 +56,33 @@ private:
             , lastTimeUsed(WallTime::now())
         { };
 
+        HashSaltForOrigin isolatedCopy() const
+        {
+            auto isolatedCopy = HashSaltForOrigin(documentOrigin.isolatedCopy(), parentOrigin.isolatedCopy(), deviceIdHashSalt.isolatedCopy());
+            isolatedCopy.lastTimeUsed = lastTimeUsed;
+            return isolatedCopy;
+        };
+
         WebCore::SecurityOriginData documentOrigin;
         WebCore::SecurityOriginData parentOrigin;
         String deviceIdHashSalt;
         WallTime lastTimeUsed;
     };
 
-    DeviceIdHashSaltStorage() = default;
+    DeviceIdHashSaltStorage(const String& deviceIdHashSaltStorageDirectory);
+    void loadStorageFromDisk(CompletionHandler<void(HashMap<String, std::unique_ptr<HashSaltForOrigin>>&&)>&&);
+    void storeHashSaltToDisk(const HashSaltForOrigin&);
+    void deleteHashSaltFromDisk(const HashSaltForOrigin&);
+    std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData(const HashSaltForOrigin&) const;
+    std::unique_ptr<HashSaltForOrigin> getDataFromDecoder(WebCore::KeyedDecoder*, String&& deviceIdHashSalt) const;
+    void completePendingHandler(CompletionHandler<void(HashSet<WebCore::SecurityOriginData>&&)>&&);
+    void completeDeviceIdHashSaltForOriginCall(WebCore::SecurityOriginData&& documentOrigin, WebCore::SecurityOriginData&& parentOrigin, CompletionHandler<void(String&&)>&&);
 
+    Ref<WorkQueue> m_queue;
     HashMap<String, std::unique_ptr<HashSaltForOrigin>> m_deviceIdHashSaltForOrigins;
+    bool m_isLoaded { false };
+    Vector<CompletionHandler<void()>> m_pendingCompletionHandlers;
+    const String m_deviceIdHashSaltStorageDirectory;
 };
 
 } // namespace WebKit
diff --git a/Source/WebKit/UIProcess/PersistencyUtils.cpp b/Source/WebKit/UIProcess/PersistencyUtils.cpp
new file mode 100644 (file)
index 0000000..5dba968
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2017-2018 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 "PersistencyUtils.h"
+
+#include "Logging.h"
+#include <WebCore/FileSystem.h>
+#include <WebCore/SharedBuffer.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+using namespace WebCore;
+
+std::unique_ptr<KeyedDecoder> createForFile(const String& path)
+{
+    ASSERT(!RunLoop::isMain());
+
+    auto handle = FileSystem::openAndLockFile(path, FileSystem::FileOpenMode::Read);
+    if (handle == FileSystem::invalidPlatformFileHandle)
+        return nullptr;
+
+    long long fileSize = 0;
+    if (!FileSystem::getFileSize(handle, fileSize) || !fileSize) {
+        FileSystem::unlockAndCloseFile(handle);
+        return nullptr;
+    }
+
+    size_t bytesToRead;
+    if (!WTF::convertSafely(fileSize, bytesToRead)) {
+        FileSystem::unlockAndCloseFile(handle);
+        return nullptr;
+    }
+
+    Vector<char> buffer(bytesToRead);
+    size_t totalBytesRead = FileSystem::readFromFile(handle, buffer.data(), buffer.size());
+
+    FileSystem::unlockAndCloseFile(handle);
+
+    if (totalBytesRead != bytesToRead)
+        return nullptr;
+
+    // FIXME: We should try to modify the constructor to pass &&.
+    return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
+}
+
+void writeToDisk(std::unique_ptr<KeyedEncoder>&& encoder, String&& path)
+{
+    ASSERT(!RunLoop::isMain());
+
+    auto rawData = encoder->finishEncoding();
+    if (!rawData)
+        return;
+
+    FileSystem::PlatformFileHandle handle = FileSystem::openAndLockFile(path, FileSystem::FileOpenMode::Write);
+    if (handle == FileSystem::invalidPlatformFileHandle)
+        return;
+
+    auto writtenBytes = FileSystem::writeToFile(handle, rawData->data(), rawData->size());
+    FileSystem::unlockAndCloseFile(handle);
+
+    if (writtenBytes != static_cast<int64_t>(rawData->size()))
+        RELEASE_LOG_ERROR(DiskPersistency, "Disk persistency: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit/UIProcess/PersistencyUtils.h b/Source/WebKit/UIProcess/PersistencyUtils.h
new file mode 100644 (file)
index 0000000..160270f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017-2018 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 <WebCore/KeyedCoding.h>
+
+namespace WebKit {
+
+std::unique_ptr<WebCore::KeyedDecoder> createForFile(const String& path);
+void writeToDisk(std::unique_ptr<WebCore::KeyedEncoder>&&, String&& path);
+
+} // namespace WebKit
index 770e837..d08d802 100644 (file)
@@ -52,36 +52,6 @@ static bool hasFileChangedSince(const String& path, WallTime since)
     return modificationTime.value() > since;
 }
 
-static std::unique_ptr<KeyedDecoder> createDecoderForFile(const String& path)
-{
-    ASSERT(!RunLoop::isMain());
-    auto handle = FileSystem::openAndLockFile(path, FileSystem::FileOpenMode::Read);
-    if (handle == FileSystem::invalidPlatformFileHandle)
-        return nullptr;
-
-    long long fileSize = 0;
-    if (!FileSystem::getFileSize(handle, fileSize)) {
-        FileSystem::unlockAndCloseFile(handle);
-        return nullptr;
-    }
-
-    size_t bytesToRead;
-    if (!WTF::convertSafely(fileSize, bytesToRead)) {
-        FileSystem::unlockAndCloseFile(handle);
-        return nullptr;
-    }
-
-    Vector<char> buffer(bytesToRead);
-    size_t totalBytesRead = FileSystem::readFromFile(handle, buffer.data(), buffer.size());
-
-    FileSystem::unlockAndCloseFile(handle);
-
-    if (totalBytesRead != bytesToRead)
-        return nullptr;
-
-    return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
-}
-
 ResourceLoadStatisticsPersistentStorage::ResourceLoadStatisticsPersistentStorage(ResourceLoadStatisticsMemoryStore& memoryStore, WorkQueue& workQueue, const String& storageDirectoryPath)
     : m_memoryStore(memoryStore)
     , m_workQueue(workQueue)
@@ -203,7 +173,7 @@ void ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk()
 
     WallTime readTime = WallTime::now();
 
-    auto decoder = createDecoderForFile(filePath);
+    auto decoder = createForFile(filePath);
     if (!decoder)
         return;
 
@@ -229,7 +199,7 @@ void ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk()
 
     WallTime readTime = WallTime::now();
 
-    auto decoder = createDecoderForFile(filePath);
+    auto decoder = createForFile(filePath);
     if (!decoder) {
         m_memoryStore.grandfatherExistingWebsiteData([]() { });
         return;
@@ -251,26 +221,7 @@ void ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk()
     m_hasPendingWrite = false;
     stopMonitoringDisk();
 
-    auto encoder = m_memoryStore.createEncoderFromData();
-    auto rawData = encoder->finishEncoding();
-    if (!rawData)
-        return;
-
-    auto storagePath = storageDirectoryPath();
-    if (!storagePath.isEmpty()) {
-        FileSystem::makeAllDirectories(storagePath);
-        excludeFromBackup();
-    }
-
-    auto handle = FileSystem::openAndLockFile(resourceLogFilePath(), FileSystem::FileOpenMode::Write);
-    if (handle == FileSystem::invalidPlatformFileHandle)
-        return;
-
-    int64_t writtenBytes = FileSystem::writeToFile(handle, rawData->data(), rawData->size());
-    FileSystem::unlockAndCloseFile(handle);
-
-    if (writtenBytes != static_cast<int64_t>(rawData->size()))
-        RELEASE_LOG_ERROR(ResourceLoadStatistics, "ResourceLoadStatisticsPersistentStorage: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
+    writeToDisk(m_memoryStore.createEncoderFromData(), resourceLogFilePath());
 
     m_lastStatisticsFileSyncTime = WallTime::now();
     m_lastStatisticsWriteTime = MonotonicTime::now();
index e7b3708..4ef5dcc 100644 (file)
@@ -184,14 +184,16 @@ void UserMediaPermissionRequestManagerProxy::userMediaAccessWasGranted(uint64_t
     if (!request)
         return;
 
-    auto deviceIDHashSalt = m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin());
-
-    if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) {
-        m_grantedRequests.append(request.releaseNonNull());
-        if (m_hasFilteredDeviceList)
-            captureDevicesChanged();
-        m_hasFilteredDeviceList = false;
-    }
+    m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin(), [this, weakThis = makeWeakPtr(*this), userMediaID, audioDevice = WTFMove(audioDevice), videoDevice = WTFMove(videoDevice), localRequest = request.copyRef()] (String&& deviceIDHashSalt) mutable {
+        if (!weakThis)
+            return;
+        if (grantAccess(userMediaID, WTFMove(audioDevice), WTFMove(videoDevice), WTFMove(deviceIDHashSalt))) {
+            m_grantedRequests.append(localRequest.releaseNonNull());
+            if (m_hasFilteredDeviceList)
+                captureDevicesChanged();
+            m_hasFilteredDeviceList = false;
+        }
+    });
 #else
     UNUSED_PARAM(userMediaID);
     UNUSED_PARAM(audioDevice);
@@ -390,8 +392,9 @@ void UserMediaPermissionRequestManagerProxy::requestUserMediaPermissionForFrame(
 
         syncWithWebCorePrefs();
 
-        auto deviceIDHashSalt = m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(pendingRequest.value()->userMediaDocumentSecurityOrigin(), pendingRequest.value()->topLevelDocumentSecurityOrigin());
-        RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(localUserRequest), WTFMove(deviceIDHashSalt));
+        m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(pendingRequest.value()->userMediaDocumentSecurityOrigin(), pendingRequest.value()->topLevelDocumentSecurityOrigin(), [validHandler = WTFMove(validHandler), invalidHandler = WTFMove(invalidHandler), localUserRequest = localUserRequest] (String&& deviceIDHashSalt) mutable {
+            RealtimeMediaSourceCenter::singleton().validateRequestConstraints(WTFMove(validHandler), WTFMove(invalidHandler), WTFMove(localUserRequest), WTFMove(deviceIDHashSalt));
+        });
     };
 
     getUserMediaPermissionInfo(requestID, frameID, WTFMove(havePermissionInfoHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
@@ -456,49 +459,52 @@ void UserMediaPermissionRequestManagerProxy::enumerateMediaDevicesForFrame(uint6
 
     auto requestID = generateRequestID();
     auto completionHandler = [this, requestID, userMediaID, requestOrigin = userMediaDocumentOrigin.copyRef(), topOrigin = topLevelDocumentOrigin.copyRef()](bool originHasPersistentAccess) {
-        auto pendingRequest = m_pendingDeviceRequests.take(requestID);
-        if (!pendingRequest)
-            return;
-
-        if (!m_page.isValid() || !m_page.websiteDataStore().deviceIdHashSaltStorage())
-            return;
+        m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(requestOrigin.get(), topOrigin.get(), [this, weakThis = makeWeakPtr(*this), requestID, userMediaID, &originHasPersistentAccess] (String&& deviceIDHashSalt) {
+            if (!weakThis)
+                return;
+            auto pendingRequest = m_pendingDeviceRequests.take(requestID);
+            if (!pendingRequest)
+                return;
 
-        syncWithWebCorePrefs();
+            if (!m_page.isValid() || !m_page.websiteDataStore().deviceIdHashSaltStorage())
+                return;
 
-        auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
-        auto& request = *pendingRequest;
-        bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(request->frameID(), request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin());
-        int cameraCount = 0;
-        int microphoneCount = 0;
-        auto deviceIDHashSalt = m_page.websiteDataStore().deviceIdHashSaltStorage()->deviceIdHashSaltForOrigin(requestOrigin.get(), topOrigin.get());
+            syncWithWebCorePrefs();
 
-        Vector<CaptureDevice> filteredDevices;
-        for (const auto& device : devices) {
-            if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone))
-                continue;
+            auto devices = RealtimeMediaSourceCenter::singleton().getMediaStreamDevices();
+            auto& request = *pendingRequest;
+            bool revealIdsAndLabels = originHasPersistentAccess || wasGrantedVideoOrAudioAccess(request->frameID(), request->userMediaDocumentSecurityOrigin(), request->topLevelDocumentSecurityOrigin());
+            int cameraCount = 0;
+            int microphoneCount = 0;
 
-            if (!revealIdsAndLabels) {
-                if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount)
+            Vector<CaptureDevice> filteredDevices;
+            for (const auto& device : devices) {
+                if (!device.enabled() || (device.type() != WebCore::CaptureDevice::DeviceType::Camera && device.type() != WebCore::CaptureDevice::DeviceType::Microphone))
                     continue;
-                if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount)
-                    continue;
-            }
 
-            auto label = emptyString();
-            auto id = emptyString();
-            auto groupId = emptyString();
-            if (revealIdsAndLabels) {
-                label = device.label();
-                id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt);
-                groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt);
+                if (!revealIdsAndLabels) {
+                    if (device.type() == WebCore::CaptureDevice::DeviceType::Camera && ++cameraCount > defaultMaximumCameraCount)
+                        continue;
+                    if (device.type() == WebCore::CaptureDevice::DeviceType::Microphone && ++microphoneCount > defaultMaximumMicrophoneCount)
+                        continue;
+                }
+
+                auto label = emptyString();
+                auto id = emptyString();
+                auto groupId = emptyString();
+                if (revealIdsAndLabels) {
+                    label = device.label();
+                    id = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.persistentId(), deviceIDHashSalt);
+                    groupId = RealtimeMediaSourceCenter::singleton().hashStringWithSalt(device.groupId(), deviceIDHashSalt);
+                }
+
+                filteredDevices.append(CaptureDevice(id, device.type(), label, groupId));
             }
 
-            filteredDevices.append(CaptureDevice(id, device.type(), label, groupId));
-        }
-
-        m_hasFilteredDeviceList = !revealIdsAndLabels;
+            m_hasFilteredDeviceList = !revealIdsAndLabels;
 
-        m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(filteredDevices), WTFMove(deviceIDHashSalt), originHasPersistentAccess), m_page.pageID());
+            m_page.process().send(Messages::WebPage::DidCompleteMediaDeviceEnumeration(userMediaID, WTFMove(filteredDevices), WTFMove(deviceIDHashSalt), originHasPersistentAccess), m_page.pageID());
+        });
     };
 
     getUserMediaPermissionInfo(requestID, frameID, WTFMove(completionHandler), WTFMove(userMediaDocumentOrigin), WTFMove(topLevelDocumentOrigin));
index 16acded..eacce6f 100644 (file)
@@ -26,6 +26,7 @@
 #include <wtf/HashMap.h>
 #include <wtf/RunLoop.h>
 #include <wtf/Seconds.h>
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 class CaptureDevice;
@@ -38,7 +39,7 @@ namespace WebKit {
 
 class WebPageProxy;
 
-class UserMediaPermissionRequestManagerProxy {
+class UserMediaPermissionRequestManagerProxy : public CanMakeWeakPtr<UserMediaPermissionRequestManagerProxy> {
 public:
     explicit UserMediaPermissionRequestManagerProxy(WebPageProxy&);
     ~UserMediaPermissionRequestManagerProxy();
index 62aca6d..4d7f511 100644 (file)
@@ -92,7 +92,7 @@ WebsiteDataStore::WebsiteDataStore(Ref<WebsiteDataStoreConfiguration>&& configur
     , m_resolvedConfiguration(WTFMove(configuration))
     , m_configuration(m_resolvedConfiguration->copy())
     , m_storageManager(StorageManager::create(m_configuration->localStorageDirectory()))
-    , m_deviceIdHashSaltStorage(DeviceIdHashSaltStorage::create())
+    , m_deviceIdHashSaltStorage(DeviceIdHashSaltStorage::create(isPersistent() ? m_configuration->deviceIdHashSaltsStorageDirectory() : String()))
     , m_queue(WorkQueue::create("com.apple.WebKit.WebsiteDataStore"))
 #if ENABLE(WEB_AUTHN)
     , m_authenticatorManager(makeUniqueRef<AuthenticatorManager>())
@@ -174,6 +174,8 @@ void WebsiteDataStore::resolveDirectoriesIfNecessary()
         m_resolvedConfiguration->setWebSQLDatabaseDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory()));
     if (!m_configuration->indexedDBDatabaseDirectory().isEmpty())
         m_resolvedConfiguration->setIndexedDBDatabaseDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->indexedDBDatabaseDirectory()));
+    if (!m_configuration->deviceIdHashSaltsStorageDirectory().isEmpty())
+        m_resolvedConfiguration->setDeviceIdHashSaltsStorageDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->deviceIdHashSaltsStorageDirectory()));
     if (!m_configuration->resourceLoadStatisticsDirectory().isEmpty())
         m_resolvedConfiguration->setResourceLoadStatisticsDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->resourceLoadStatisticsDirectory()));
     if (!m_configuration->serviceWorkerRegistrationDirectory().isEmpty() && m_resolvedConfiguration->serviceWorkerRegistrationDirectory().isEmpty())
index 832c3ec..1012cb3 100644 (file)
@@ -63,7 +63,10 @@ public:
 
     const String& localStorageDirectory() const { return m_localStorageDirectory; }
     void setLocalStorageDirectory(String&& directory) { m_localStorageDirectory = WTFMove(directory); }
-    
+
+    const String& deviceIdHashSaltsStorageDirectory() const { return m_deviceIdHashSaltsStorageDirectory; }
+    void setDeviceIdHashSaltsStorageDirectory(String&& directory) { m_deviceIdHashSaltsStorageDirectory = WTFMove(directory); }
+
     const String& cookieStorageFile() const { return m_cookieStorageFile; }
     void setCookieStorageFile(String&& directory) { m_cookieStorageFile = WTFMove(directory); }
     
index 2e9f0d8..4da02fa 100644 (file)
@@ -77,6 +77,7 @@
                00B9661A18E25AE100CE1F88 /* FindClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 00B9661818E25AE100CE1F88 /* FindClient.h */; };
                07297F9F1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */; };
                07297F9F1C17BBEA015F0735 /* DeviceIdHashSaltStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */; };
+               07297F9F1C17AA1A015F0735 /* PersistencyUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */; };
                07297FA31C186ADB003F0735 /* WKUserMediaPermissionCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
                074E75FE1DF2211900D318EC /* UserMediaProcessManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 074E75FB1DF1FD1300D318EC /* UserMediaProcessManager.h */; };
                076E884E1A13CADF005E90FC /* APIContextMenuClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 076E884D1A13CADF005E90FC /* APIContextMenuClient.h */; };
                07297F9C1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMediaPermissionCheckProxy.cpp; sourceTree = "<group>"; };
                07297F9D1C17BBEA003F0735 /* UserMediaPermissionCheckProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaPermissionCheckProxy.h; sourceTree = "<group>"; };
                07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceIdHashSaltStorage.h; sourceTree = "<group>"; };
+               0729455C1C1711EA003F0735 /* PersistencyUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PersistencyUtils.cpp; sourceTree = "<group>"; };
+               07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersistencyUtils.h; sourceTree = "<group>"; };
                07297FA01C186ADB003F0735 /* WKUserMediaPermissionCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKUserMediaPermissionCheck.cpp; sourceTree = "<group>"; };
                07297FA11C186ADB003F0735 /* WKUserMediaPermissionCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKUserMediaPermissionCheck.h; sourceTree = "<group>"; };
                074E75FB1DF1FD1300D318EC /* UserMediaProcessManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMediaProcessManager.h; sourceTree = "<group>"; };
                                1AC7537A183A9FDB0072CB15 /* PageLoadState.h */,
                                832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */,
                                832ED18A1E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.h */,
+                               0729455C1C1711EA003F0735 /* PersistencyUtils.cpp */,
+                               07321F9D1C17BBEA223F0735 /* PersistencyUtils.h */,
                                37716A59195B910500EE8B1B /* ProcessAssertion.cpp */,
                                86F9536018FF4FD4001DB2EF /* ProcessAssertion.h */,
                                86E67A22190F411800004AB7 /* ProcessThrottler.cpp */,
                                2DC18FB0218912640025A88D /* PencilKitSPI.h in Headers */,
                                5C298DA01C3DF02100470AFE /* PendingDownload.h in Headers */,
                                832ED18C1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.h in Headers */,
+                               07297F9F1C17AA1A015F0735 /* PersistencyUtils.h in Headers */,
                                5CE85B201C88E64B0070BFCE /* PingLoad.h in Headers */,
                                0F5E200418E77051003EC3E5 /* PlatformCAAnimationRemote.h in Headers */,
                                2DA049B4180CCCD300AAFA9E /* PlatformCALayerRemote.h in Headers */,