Title: [284059] trunk
Revision
284059
Author
[email protected]
Date
2021-10-12 16:35:55 -0700 (Tue, 12 Oct 2021)

Log Message

Implement FileSystemSyncAccessHandle read() and write()
https://bugs.webkit.org/show_bug.cgi?id=231466
<rdar://problem/84050394>

Reviewed by Youenn Fablet.

LayoutTests/imported/w3c:

* web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt:
* web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt:
* web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt:
* web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-read-write.https.tentative.worker-expected.txt:
* web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt:

Source/WebCore:

Implement read() and write() according to proposal:
https://github.com/WICG/file-system-access/blob/main/AccessHandle.md

Test: storage/filesystemaccess/sync-access-handle-read-write-worker.html
API test: FileSystemAccess.ProcessCrashDuringWrite

* Modules/filesystemaccess/FileSystemFileHandle.cpp:
(WebCore::FileSystemFileHandle::createSyncAccessHandle):
(WebCore::FileSystemFileHandle::getSize):
(WebCore::FileSystemFileHandle::truncate):
(WebCore::FileSystemFileHandle::flush):
* Modules/filesystemaccess/FileSystemFileHandle.h:
* Modules/filesystemaccess/FileSystemStorageConnection.h:
* Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
(WebCore::FileSystemSyncAccessHandle::create):
(WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
(WebCore::FileSystemSyncAccessHandle::truncate):
(WebCore::FileSystemSyncAccessHandle::getSize):
(WebCore::FileSystemSyncAccessHandle::flush):
(WebCore::FileSystemSyncAccessHandle::close):
(WebCore::FileSystemSyncAccessHandle::read):
(WebCore::FileSystemSyncAccessHandle::write):
* Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
* Modules/filesystemaccess/FileSystemSyncAccessHandle.idl:
* Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp:
(WebCore::WorkerFileSystemStorageConnection::didCreateSyncAccessHandle):
(WebCore::WorkerFileSystemStorageConnection::createSyncAccessHandle):
* Modules/filesystemaccess/WorkerFileSystemStorageConnection.h:
* bindings/js/BufferSource.h:
(WebCore::BufferSource::mutableData const):

Source/WebCore/PAL:

* PAL.xcodeproj/project.pbxproj:
* pal/spi/cocoa/FilePortSPI.h: Added.

Source/WebKit:

Let network process open the file and pass file descriptor to web process, so that web process can read and
write the file without sending IPC messages. Currently getting file size, truncating file and syncing file are
still performed by network process.

* NetworkProcess/storage/FileSystemStorageError.h:
(WebKit::convertToException):
* NetworkProcess/storage/FileSystemStorageHandle.cpp:
(WebKit::FileSystemStorageHandle::createSyncAccessHandle):
(WebKit::FileSystemStorageHandle::truncate):
(WebKit::FileSystemStorageHandle::flush):
(WebKit::FileSystemStorageHandle::close):
* NetworkProcess/storage/FileSystemStorageHandle.h:
* NetworkProcess/storage/NetworkStorageManager.cpp:
(WebKit::NetworkStorageManager::createSyncAccessHandle):
* NetworkProcess/storage/NetworkStorageManager.h:
* NetworkProcess/storage/NetworkStorageManager.messages.in:
* Platform/IPC/SharedFileHandle.cpp: Added.
(IPC::SharedFileHandle::create):
(IPC::SharedFileHandle::encode const):
(IPC::SharedFileHandle::decode):
* Platform/IPC/SharedFileHandle.h: Added.
(IPC::SharedFileHandle::handle):
(IPC::SharedFileHandle::SharedFileHandle):
* Platform/IPC/cocoa/SharedFileHandleCocoa.cpp: Added.
(IPC::SharedFileHandle::create):
(IPC::SharedFileHandle::encode const):
(IPC::SharedFileHandle::decode):
* Sources.txt:
* UIProcess/API/Cocoa/WKPreferences.mm:
(-[WKPreferences _fileSystemAccessEnabled]):
(-[WKPreferences _setFileSystemAccessEnabled:]):
(-[WKPreferences _storageAPIEnabled]):
(-[WKPreferences _setStorageAPIEnabled:]):
(-[WKPreferences _accessHandleEnabled]):
(-[WKPreferences _setAccessHandleEnabled:]):
* UIProcess/API/Cocoa/WKPreferencesPrivate.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp:
(WebKit::WebFileSystemStorageConnection::createSyncAccessHandle):
* WebProcess/com.apple.WebProcess.sb.in:

Source/WTF:

* wtf/PlatformHave.h:

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm: Added.
(-[FileSystemAccessMessageHandler userContentController:didReceiveScriptMessage:]):
(test):

LayoutTests:

* storage/filesystemaccess/resources/sync-access-handle-read-write.js: Added.
(finishTest):
(arrayBufferToString):
(stringToArrayBuffer):
(write):
(read):
(async test):
* storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt: Added.
* storage/filesystemaccess/sync-access-handle-read-write-worker.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (284058 => 284059)


--- trunk/LayoutTests/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,21 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        * storage/filesystemaccess/resources/sync-access-handle-read-write.js: Added.
+        (finishTest):
+        (arrayBufferToString):
+        (stringToArrayBuffer):
+        (write):
+        (read):
+        (async test):
+        * storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt: Added.
+        * storage/filesystemaccess/sync-access-handle-read-write-worker.html: Added.
+
 2021-10-12  Ayumi Kojima  <[email protected]>
 
         [ iOS, Mac ] imported/w3c/web-platform-tests/css/css-cascade/layer-counter-style-override.html is a flaky failure.

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,17 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt:
+        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt:
+        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt:
+        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-read-write.https.tentative.worker-expected.txt:
+        * web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt:
+
 2021-10-12  Aditya Keerthi  <[email protected]>
 
         [css-ui] Fix interpolation of accent-color

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,10 +1,10 @@
 
 FAIL SyncAccessHandle.close is idempotent promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
 FAIL SyncAccessHandle.close is idempotent when called immediately promise_test: Unhandled rejection with value: object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)."
-FAIL SyncAccessHandle.read fails after SyncAccessHandle.close settles assert_throws_dom: function "() => handle.read(readBuffer, {at: 0})" threw object "TypeError: handle.read is not a function. (In 'handle.read(readBuffer, {at: 0})', 'handle.read' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL SyncAccessHandle.read fails immediately after calling SyncAccessHandle.close assert_throws_dom: function "() => handle.read(readBuffer, {at: 0})" threw object "TypeError: handle.read is not a function. (In 'handle.read(readBuffer, {at: 0})', 'handle.read' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL SyncAccessHandle.write fails after SyncAccessHandle.close settles assert_throws_dom: function "() => handle.write(writeBuffer, {at: 0})" threw object "TypeError: handle.write is not a function. (In 'handle.write(writeBuffer, {at: 0})', 'handle.write' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-FAIL SyncAccessHandle.write fails immediately after calling SyncAccessHandle.close assert_throws_dom: function "() => handle.write(writeBuffer, {at: 0})" threw object "TypeError: handle.write is not a function. (In 'handle.write(writeBuffer, {at: 0})', 'handle.write' is undefined)" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+FAIL SyncAccessHandle.read fails after SyncAccessHandle.close settles promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL SyncAccessHandle.read fails immediately after calling SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL SyncAccessHandle.write fails after SyncAccessHandle.close settles promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+FAIL SyncAccessHandle.write fails immediately after calling SyncAccessHandle.close promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
 FAIL SyncAccessHandle.flush fails after SyncAccessHandle.close settles promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
 FAIL SyncAccessHandle.flush fails immediately after calling SyncAccessHandle.close promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11
 FAIL SyncAccessHandle.getSize fails after SyncAccessHandle.close settles promise_rejects_dom: function "function () { throw e }" threw object "UnknownError: The operation failed for an unknown transient reason (e.g. out of memory)." that is not a DOMException InvalidStateError: property "code" is equal to 0, expected 11

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-flush.https.tentative.worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,6 +1,6 @@
 
 PASS Test flush on an empty file.
-FAIL SyncAccessHandle.read returns bytes written by SyncAccessHandle.write after SyncAccessHandle.flush promise_test: Unhandled rejection with value: object "TypeError: handle.write is not a function. (In 'handle.write(writeBuffer, {at: 0})', 'handle.write' is undefined)"
-FAIL SyncAccessHandle.read fails when there is a pending SyncAccessHandle.flush promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL SyncAccessHandle.write fails when there is a pending SyncAccessHandle.flush promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+PASS SyncAccessHandle.read returns bytes written by SyncAccessHandle.write after SyncAccessHandle.flush
+PASS SyncAccessHandle.read fails when there is a pending SyncAccessHandle.flush
+PASS SyncAccessHandle.write fails when there is a pending SyncAccessHandle.flush
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-getSize.https.tentative.worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,4 +1,4 @@
 
-FAIL test SyncAccessHandle.getSize after SyncAccessHandle.write promise_test: Unhandled rejection with value: object "TypeError: handle.write is not a function. (In 'handle.write(writeBuffer, {at: 0})', 'handle.write' is undefined)"
-FAIL test createSyncAccessHandle.getSize with pending operation promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+PASS test SyncAccessHandle.getSize after SyncAccessHandle.write
+FAIL test createSyncAccessHandle.getSize with pending operation assert_unreached: Should have rejected: undefined Reached unreachable code
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-read-write.https.tentative.worker-expected.txt (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-read-write.https.tentative.worker-expected.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-read-write.https.tentative.worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,10 +1,10 @@
 
-FAIL Test reading an empty file through a sync access handle. promise_test: Unhandled rejection with value: object "TypeError: handle.read is not a function. (In 'handle.read(readBuffer, {at: 0})', 'handle.read' is undefined)"
-FAIL Test writing and reading through a sync access handle. promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test second write that is bigger than the first write promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test second write that is smaller than the first write promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test initial write with an offset promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test overwriting the file at an offset promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test read at an offset promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
-FAIL Test reading at a negative offset fails. promise_test: Unhandled rejection with value: object "InvalidStateError: The object is in an invalid state."
+PASS Test reading an empty file through a sync access handle.
+PASS Test writing and reading through a sync access handle.
+PASS Test second write that is bigger than the first write
+PASS Test second write that is smaller than the first write
+PASS Test initial write with an offset
+PASS Test overwriting the file at an offset
+PASS Test read at an offset
+FAIL Test reading at a negative offset fails. assert_throws_dom: function "() => handle.read(readBuffer, { at: -1 })" threw object "TypeError: Value -1 is outside the range [0, 9007199254740991]" that is not a DOMException NotSupportedError: property "code" is equal to undefined, expected 9
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt (284058 => 284059)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,5 +1,5 @@
 
 FAIL test createSyncAccessHandle.truncate with pending operation assert_unreached: Should have rejected: undefined Reached unreachable code
 PASS test SyncAccessHandle.truncate with different sizes
-FAIL test SyncAccessHandle.truncate after SyncAccessHandle.write promise_test: Unhandled rejection with value: object "TypeError: handle.write is not a function. (In 'handle.write(writeBuffer, {at: 0})', 'handle.write' is undefined)"
+PASS test SyncAccessHandle.truncate after SyncAccessHandle.write
 

Added: trunk/LayoutTests/storage/filesystemaccess/resources/sync-access-handle-read-write.js (0 => 284059)


--- trunk/LayoutTests/storage/filesystemaccess/resources/sync-access-handle-read-write.js	                        (rev 0)
+++ trunk/LayoutTests/storage/filesystemaccess/resources/sync-access-handle-read-write.js	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,97 @@
+if (this.importScripts) {
+    importScripts('../../../resources/js-test.js');
+}
+
+description("This test checks read and write capabilities of FileSystemSyncAccessHandle.");
+
+var accessHandle, fileSize, writeBuffer, writeSize, readBuffer, readSize, readText, readError;
+var totalReadSize = 0, totalWriteSize = 0;
+
+var testString;
+
+function finishTest(error)
+{
+    if (error) {
+        testFailed(error);
+    }
+    finishJSTest();
+}
+
+function arrayBufferToString(buffer)
+{
+    const decoder = new TextDecoder();
+    var view = new Uint8Array(buffer);
+    return decoder.decode(view);
+}
+
+function stringToArrayBuffer(string)
+{
+    const encoder = new TextEncoder();
+    return encoder.encode(string);
+}
+
+function write(accessHandle, offset, text)
+{
+    writeBuffer = stringToArrayBuffer(text);
+    writeSize = accessHandle.write(writeBuffer, { "at" : offset });
+    shouldBe("writeSize", "writeBuffer.byteLength");
+    return writeSize;
+}
+
+function read(accessHandle, offset, size, expectedString)
+{
+    readBuffer = new ArrayBuffer(size);
+    readSize = accessHandle.read(readBuffer, { "at": offset });
+    shouldBe("readSize", "readBuffer.byteLength");
+    if (expectedString) {
+        readText = arrayBufferToString(readBuffer);
+        shouldBeEqualToString("readText", expectedString);
+    }
+    return readSize;
+}
+
+async function test() {
+    try {
+        var rootHandle = await navigator.storage.getDirectory();
+        // Create a new file for this test.
+        await rootHandle.removeEntry("sync-access-handle.txt").then(() => { }, () => { });
+        var fileHandle = await rootHandle.getFileHandle("sync-access-handle.txt", { "create" : true  });
+        accessHandle = await fileHandle.createSyncAccessHandle();
+        fileSize = await accessHandle.getSize();
+        shouldBe("fileSize", "0");
+
+        debug("test read() and write():");
+        totalWriteSize += write(accessHandle, 0, "This is first sentence.");
+        totalReadSize += read(accessHandle, 0, totalWriteSize, "This is first sentence.");
+        totalWriteSize += write(accessHandle, totalWriteSize, "This is second sentence.");
+        read(accessHandle, totalReadSize, totalWriteSize - totalReadSize, "This is second sentence.");
+        read(accessHandle, 0, totalWriteSize, "This is first sentence.This is second sentence.");
+
+        // Wrong offset to read and write.
+        shouldThrow("accessHandle.read(new ArrayBuffer(1), { \"at\" : Number.MAX_SAFE_INTEGER })");
+        shouldThrow("accessHandle.write(new ArrayBuffer(1), { \"at\" : Number.MAX_SAFE_INTEGER })");
+
+        debug("test flush():");
+        await accessHandle.flush();
+        fileSize = await accessHandle.getSize();
+        shouldBe("fileSize", "totalWriteSize");
+
+        debug("test truncate():");
+        await accessHandle.truncate(4);
+        await accessHandle.flush();
+        fileSize = await accessHandle.getSize();
+        shouldBe("fileSize", "4");
+
+        debug("test write() with pending operation:");
+        evalAndLog("accessHandle.truncate(0)");
+        readBuffer = new ArrayBuffer(4);
+        shouldThrow("accessHandle.read(readBuffer, { \"at\" : 0 })");
+
+        await accessHandle.close();
+        finishTest();
+    } catch (error) {
+        finishTest(error);
+    }
+}
+
+test();

Added: trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt (0 => 284059)


--- trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker-expected.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,29 @@
+[Worker] This test checks read and write capabilities of FileSystemSyncAccessHandle.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Starting worker: resources/sync-access-handle-read-write.js
+PASS [Worker] fileSize is 0
+[Worker] test read() and write():
+PASS [Worker] writeSize is writeBuffer.byteLength
+PASS [Worker] readSize is readBuffer.byteLength
+PASS [Worker] readText is "This is first sentence."
+PASS [Worker] writeSize is writeBuffer.byteLength
+PASS [Worker] readSize is readBuffer.byteLength
+PASS [Worker] readText is "This is second sentence."
+PASS [Worker] readSize is readBuffer.byteLength
+PASS [Worker] readText is "This is first sentence.This is second sentence."
+PASS [Worker] accessHandle.read(new ArrayBuffer(1), { "at" : Number.MAX_SAFE_INTEGER }) threw exception InvalidStateError: Failed to read at offset.
+PASS [Worker] accessHandle.write(new ArrayBuffer(1), { "at" : Number.MAX_SAFE_INTEGER }) threw exception InvalidStateError: Failed to write at offset.
+[Worker] test flush():
+PASS [Worker] fileSize is totalWriteSize
+[Worker] test truncate():
+PASS [Worker] fileSize is 4
+[Worker] test write() with pending operation:
+[Worker] accessHandle.truncate(0)
+PASS [Worker] accessHandle.read(readBuffer, { "at" : 0 }) threw exception InvalidStateError: Access handle has unfinished operation.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker.html (0 => 284059)


--- trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker.html	                        (rev 0)
+++ trunk/LayoutTests/storage/filesystemaccess/sync-access-handle-read-write-worker.html	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,9 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+worker = startWorker('resources/sync-access-handle-read-write.js');</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WTF/ChangeLog (284058 => 284059)


--- trunk/Source/WTF/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WTF/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,13 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        * wtf/PlatformHave.h:
+
 2021-10-12  Chris Dumez  <[email protected]>
 
         Decrease use of makeWeakPtr()

Modified: trunk/Source/WebCore/ChangeLog (284058 => 284059)


--- trunk/Source/WebCore/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,42 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        Implement read() and write() according to proposal:
+        https://github.com/WICG/file-system-access/blob/main/AccessHandle.md
+
+        Test: storage/filesystemaccess/sync-access-handle-read-write-worker.html
+        API test: FileSystemAccess.ProcessCrashDuringWrite
+
+        * Modules/filesystemaccess/FileSystemFileHandle.cpp:
+        (WebCore::FileSystemFileHandle::createSyncAccessHandle):
+        (WebCore::FileSystemFileHandle::getSize):
+        (WebCore::FileSystemFileHandle::truncate):
+        (WebCore::FileSystemFileHandle::flush):
+        * Modules/filesystemaccess/FileSystemFileHandle.h:
+        * Modules/filesystemaccess/FileSystemStorageConnection.h:
+        * Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp:
+        (WebCore::FileSystemSyncAccessHandle::create):
+        (WebCore::FileSystemSyncAccessHandle::FileSystemSyncAccessHandle):
+        (WebCore::FileSystemSyncAccessHandle::truncate):
+        (WebCore::FileSystemSyncAccessHandle::getSize):
+        (WebCore::FileSystemSyncAccessHandle::flush):
+        (WebCore::FileSystemSyncAccessHandle::close):
+        (WebCore::FileSystemSyncAccessHandle::read):
+        (WebCore::FileSystemSyncAccessHandle::write):
+        * Modules/filesystemaccess/FileSystemSyncAccessHandle.h:
+        * Modules/filesystemaccess/FileSystemSyncAccessHandle.idl:
+        * Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp:
+        (WebCore::WorkerFileSystemStorageConnection::didCreateSyncAccessHandle):
+        (WebCore::WorkerFileSystemStorageConnection::createSyncAccessHandle):
+        * Modules/filesystemaccess/WorkerFileSystemStorageConnection.h:
+        * bindings/js/BufferSource.h:
+        (WebCore::BufferSource::mutableData const):
+
 2021-10-12  Chris Dumez  <[email protected]>
 
         Decrease use of makeWeakPtr()

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -57,29 +57,24 @@
         if (result.hasException())
             return promise.reject(result.releaseException());
 
-        promise.settle(FileSystemSyncAccessHandle::create(protectedThis.get(), result.returnValue()));
+        auto resultValue = result.releaseReturnValue();
+        promise.settle(FileSystemSyncAccessHandle::create(protectedThis.get(), resultValue.first, resultValue.second));
     });
 }
 
-void FileSystemFileHandle::getSize(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, DOMPromiseDeferred<IDLUnsignedLongLong>&& promise)
+void FileSystemFileHandle::getSize(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, CompletionHandler<void(ExceptionOr<uint64_t>&&)>&& completionHandler)
 {
-    connection().getSize(identifier(), accessHandleIdentifier, [promise = WTFMove(promise)](auto result) mutable {
-        promise.settle(WTFMove(result));
-    });
+    connection().getSize(identifier(), accessHandleIdentifier, WTFMove(completionHandler));
 }
 
-void FileSystemFileHandle::truncate(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, unsigned long long size, DOMPromiseDeferred<void>&& promise)
+void FileSystemFileHandle::truncate(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, unsigned long long size, CompletionHandler<void(ExceptionOr<void>&&)>&& completionHandler)
 {
-    connection().truncate(identifier(), accessHandleIdentifier, size, [promise = WTFMove(promise)](auto result) mutable {
-        promise.settle(WTFMove(result));
-    });
+    connection().truncate(identifier(), accessHandleIdentifier, size, WTFMove(completionHandler));
 }
 
-void FileSystemFileHandle::flush(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, DOMPromiseDeferred<void>&& promise)
+void FileSystemFileHandle::flush(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&& completionHandler)
 {
-    connection().flush(identifier(), accessHandleIdentifier, [promise = WTFMove(promise)](auto result) mutable {
-        promise.settle(WTFMove(result));
-    });
+    connection().flush(identifier(), accessHandleIdentifier, WTFMove(completionHandler));
 }
 
 void FileSystemFileHandle::close(FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&& completionHandler)

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemFileHandle.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -41,9 +41,9 @@
     void getFile(DOMPromiseDeferred<IDLInterface<File>>&&);
 
     void createSyncAccessHandle(DOMPromiseDeferred<IDLInterface<FileSystemSyncAccessHandle>>&&);
-    void getSize(FileSystemSyncAccessHandleIdentifier, DOMPromiseDeferred<IDLUnsignedLongLong>&&);
-    void truncate(FileSystemSyncAccessHandleIdentifier, unsigned long long size, DOMPromiseDeferred<void>&&);
-    void flush(FileSystemSyncAccessHandleIdentifier, DOMPromiseDeferred<void>&&);
+    void getSize(FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(ExceptionOr<uint64_t>&&)>&&);
+    void truncate(FileSystemSyncAccessHandleIdentifier, unsigned long long size, CompletionHandler<void(ExceptionOr<void>&&)>&&);
+    void flush(FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&&);
     void close(FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(ExceptionOr<void>&&)>&&);
 
 private:

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemStorageConnection.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -28,6 +28,7 @@
 #include "FileSystemHandleIdentifier.h"
 #include "FileSystemSyncAccessHandleIdentifier.h"
 #include <wtf/CompletionHandler.h>
+#include <wtf/FileSystem.h>
 #include <wtf/ThreadSafeRefCounted.h>
 
 namespace WebCore {
@@ -43,7 +44,7 @@
     using SameEntryCallback = CompletionHandler<void(ExceptionOr<bool>&&)>;
     using GetHandleCallback = CompletionHandler<void(ExceptionOr<FileSystemHandleIdentifier>&&)>;
     using ResolveCallback = CompletionHandler<void(ExceptionOr<Vector<String>>&&)>;
-    using GetAccessHandleCallback = CompletionHandler<void(ExceptionOr<FileSystemSyncAccessHandleIdentifier>&&)>;
+    using GetAccessHandleCallback = CompletionHandler<void(ExceptionOr<std::pair<FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle>>&&)>;
     using VoidCallback = CompletionHandler<void(ExceptionOr<void>&&)>;
     using IntegerCallback = CompletionHandler<void(ExceptionOr<uint64_t>&&)>;
     using GetHandleNamesCallback = CompletionHandler<void(ExceptionOr<Vector<String>>&&)>;

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -34,14 +34,15 @@
 
 namespace WebCore {
 
-Ref<FileSystemSyncAccessHandle> FileSystemSyncAccessHandle::create(FileSystemFileHandle& source, FileSystemSyncAccessHandleIdentifier identifier)
+Ref<FileSystemSyncAccessHandle> FileSystemSyncAccessHandle::create(FileSystemFileHandle& source, FileSystemSyncAccessHandleIdentifier identifier, FileSystem::PlatformFileHandle file)
 {
-    return adoptRef(*new FileSystemSyncAccessHandle(source, identifier));
+    return adoptRef(*new FileSystemSyncAccessHandle(source, identifier, file));
 }
 
-FileSystemSyncAccessHandle::FileSystemSyncAccessHandle(FileSystemFileHandle& source, FileSystemSyncAccessHandleIdentifier identifier)
+FileSystemSyncAccessHandle::FileSystemSyncAccessHandle(FileSystemFileHandle& source, FileSystemSyncAccessHandleIdentifier identifier, FileSystem::PlatformFileHandle file)
     : m_source(source)
     , m_identifier(identifier)
+    , m_file(file)
 {
 }
 
@@ -53,17 +54,35 @@
 
 void FileSystemSyncAccessHandle::truncate(unsigned long long size, DOMPromiseDeferred<void>&& promise)
 {
-    m_source->truncate(m_identifier, size, WTFMove(promise));
+    m_pendingOperationCount++;
+    m_source->truncate(m_identifier, size, [weakThis = makeWeakPtr(*this), promise = WTFMove(promise)](auto result) mutable {
+        if (weakThis)
+            weakThis->m_pendingOperationCount--;
+
+        promise.settle(WTFMove(result));
+    });
 }
 
 void FileSystemSyncAccessHandle::getSize(DOMPromiseDeferred<IDLUnsignedLongLong>&& promise)
 {
-    m_source->getSize(m_identifier, WTFMove(promise));
+    m_pendingOperationCount++;
+    m_source->getSize(m_identifier, [weakThis = makeWeakPtr(*this), promise = WTFMove(promise)](auto result) mutable {
+        if (weakThis)
+            weakThis->m_pendingOperationCount--;
+
+        promise.settle(WTFMove(result));
+    });
 }
 
 void FileSystemSyncAccessHandle::flush(DOMPromiseDeferred<void>&& promise)
 {
-    m_source->flush(m_identifier, WTFMove(promise));
+    m_pendingOperationCount++;
+    m_source->flush(m_identifier, [weakThis = makeWeakPtr(*this), promise = WTFMove(promise)](auto result) mutable {
+        if (weakThis)
+            weakThis->m_pendingOperationCount--;
+
+        promise.settle(WTFMove(result));
+    });
 }
 
 void FileSystemSyncAccessHandle::close(DOMPromiseDeferred<void>&& promise)
@@ -71,9 +90,12 @@
     if (m_isClosed)
         return promise.reject(Exception { InvalidStateError });
 
+    m_pendingOperationCount++;
     m_source->close(m_identifier, [weakThis = makeWeakPtr(*this), promise = WTFMove(promise)](auto result) mutable {
-        if (weakThis)
+        if (weakThis) {
+            weakThis->m_pendingOperationCount--;
             weakThis->didClose();
+        }
 
         promise.settle(WTFMove(result));
     });
@@ -84,4 +106,46 @@
     m_isClosed = true;
 }
 
+ExceptionOr<unsigned long long> FileSystemSyncAccessHandle::read(BufferSource&& buffer, FileSystemSyncAccessHandle::FilesystemReadWriteOptions options)
+{
+    ASSERT(!isMainThread());
+
+    if (m_file == FileSystem::invalidPlatformFileHandle || m_isClosed)
+        return Exception { InvalidStateError };
+
+    if (m_pendingOperationCount)
+        return Exception { InvalidStateError, "Access handle has unfinished operation"_s };
+
+    int result = FileSystem::seekFile(m_file, options.at, FileSystem::FileSeekOrigin::Beginning);
+    if (result == -1)
+        return Exception { InvalidStateError, "Failed to read at offset"_s };
+
+    result = FileSystem::readFromFile(m_file, buffer.mutableData(), buffer.length());
+    if (result == -1)
+        return Exception { InvalidStateError, "Failed to read from file"_s };
+
+    return result;
+}
+
+ExceptionOr<unsigned long long> FileSystemSyncAccessHandle::write(BufferSource&& buffer, FileSystemSyncAccessHandle::FilesystemReadWriteOptions options)
+{
+    ASSERT(!isMainThread());
+
+    if (m_file == FileSystem::invalidPlatformFileHandle || m_isClosed)
+        return Exception { InvalidStateError };
+
+    if (m_pendingOperationCount)
+        return Exception { InvalidStateError, "Access handle has unfinished operation"_s };
+
+    int result = FileSystem::seekFile(m_file, options.at, FileSystem::FileSeekOrigin::Beginning);
+    if (result == -1)
+        return Exception { InvalidStateError, "Failed to write at offset"_s };
+
+    result = FileSystem::writeToFile(m_file, buffer.data(), buffer.length());
+    if (result == -1)
+        return Exception { InvalidStateError, "Failed to write to file"_s };
+
+    return result;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -25,8 +25,10 @@
 
 #pragma once
 
+#include "BufferSource.h"
 #include "FileSystemSyncAccessHandleIdentifier.h"
 #include "IDLTypes.h"
+#include <wtf/FileSystem.h>
 #include <wtf/WeakPtr.h>
 
 namespace WebCore {
@@ -33,6 +35,7 @@
 
 class FileSystemFileHandle;
 template<typename> class DOMPromiseDeferred;
+template<typename> class ExceptionOr;
 
 class FileSystemSyncAccessHandle : public RefCounted<FileSystemSyncAccessHandle>, public CanMakeWeakPtr<FileSystemSyncAccessHandle> {
 public:
@@ -40,7 +43,7 @@
         unsigned long long at;
     };
 
-    static Ref<FileSystemSyncAccessHandle> create(FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier);
+    static Ref<FileSystemSyncAccessHandle> create(FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle);
     ~FileSystemSyncAccessHandle();
 
     void truncate(unsigned long long size, DOMPromiseDeferred<void>&&);
@@ -48,13 +51,17 @@
     void flush(DOMPromiseDeferred<void>&&);
     void close(DOMPromiseDeferred<void>&&);
     void didClose();
+    ExceptionOr<unsigned long long> read(BufferSource&&, FilesystemReadWriteOptions);
+    ExceptionOr<unsigned long long> write(BufferSource&&, FilesystemReadWriteOptions);
 
 private:
-    FileSystemSyncAccessHandle(FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier);
+    FileSystemSyncAccessHandle(FileSystemFileHandle&, FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle);
 
     Ref<FileSystemFileHandle> m_source;
     FileSystemSyncAccessHandleIdentifier m_identifier;
     bool m_isClosed { false };
+    uint64_t m_pendingOperationCount { 0 };
+    FileSystem::PlatformFileHandle m_file;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl	2021-10-12 23:35:55 UTC (rev 284059)
@@ -33,6 +33,8 @@
     Promise<unsigned long long> getSize();
     Promise<undefined> flush();
     Promise<undefined> close();
+    unsigned long long read([AllowShared] BufferSource buffer, FilesystemReadWriteOptions options);
+    unsigned long long write([AllowShared] BufferSource buffer, FilesystemReadWriteOptions options);
 };
 
 dictionary FilesystemReadWriteOptions {

Modified: trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -193,7 +193,7 @@
         callback(WTFMove(result));
 }
 
-void WorkerFileSystemStorageConnection::didCreateSyncAccessHandle(CallbackIdentifier callbackIdentifier, ExceptionOr<FileSystemSyncAccessHandleIdentifier>&& result)
+void WorkerFileSystemStorageConnection::didCreateSyncAccessHandle(CallbackIdentifier callbackIdentifier, ExceptionOr<std::pair<FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle>>&& result)
 {
     if (auto callback = m_getAccessHandlCallbacks.take(callbackIdentifier))
         callback(WTFMove(result));
@@ -221,7 +221,10 @@
 
     callOnMainThread([callbackIdentifier, workerThread = Ref { m_scope->thread() }, mainThreadConnection = m_mainThreadConnection, identifier]() mutable {
         auto mainThreadCallback = [callbackIdentifier, workerThread = WTFMove(workerThread)](auto result) mutable {
-            workerThread->runLoop().postTaskForMode([callbackIdentifier, result = crossThreadCopy(result)] (auto& scope) mutable {
+            auto crossThreadResult = result;
+            if (result.hasException())
+                crossThreadResult = crossThreadCopy(result.exception());
+            workerThread->runLoop().postTaskForMode([callbackIdentifier, result = WTFMove(crossThreadResult)] (auto& scope) mutable {
                 if (auto connection = downcast<WorkerGlobalScope>(scope).fileSystemStorageConnection())
                     connection->didCreateSyncAccessHandle(callbackIdentifier, WTFMove(result));
             }, WorkerRunLoop::defaultMode());

Modified: trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h (284058 => 284059)


--- trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/Modules/filesystemaccess/WorkerFileSystemStorageConnection.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -47,7 +47,7 @@
     void didIsSameEntry(CallbackIdentifier, ExceptionOr<bool>&&);
     void didGetHandle(CallbackIdentifier, ExceptionOr<FileSystemHandleIdentifier>&&);
     void didResolve(CallbackIdentifier, ExceptionOr<Vector<String>>&&);
-    void didCreateSyncAccessHandle(CallbackIdentifier, ExceptionOr<FileSystemSyncAccessHandleIdentifier>&& result);
+    void didCreateSyncAccessHandle(CallbackIdentifier, ExceptionOr<std::pair<FileSystemSyncAccessHandleIdentifier, FileSystem::PlatformFileHandle>>&&);
     void completeVoidCallback(CallbackIdentifier, ExceptionOr<void>&& result);
     void completeIntegerCallback(CallbackIdentifier, ExceptionOr<uint64_t>&& result);
     void didGetHandleNames(CallbackIdentifier, ExceptionOr<Vector<String>>&&);

Modified: trunk/Source/WebCore/PAL/ChangeLog (284058 => 284059)


--- trunk/Source/WebCore/PAL/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/PAL/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,14 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        * PAL.xcodeproj/project.pbxproj:
+        * pal/spi/cocoa/FilePortSPI.h: Added.
+
 2021-10-12  Chris Dumez  <[email protected]>
 
         Allow direct construction of WeakPtr without makeWeakPtr()

Modified: trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj (284058 => 284059)


--- trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/PAL/PAL.xcodeproj/project.pbxproj	2021-10-12 23:35:55 UTC (rev 284059)
@@ -154,6 +154,7 @@
 		71B1142026823ACD004D6701 /* SystemPreviewSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 71B1141F26823ACD004D6701 /* SystemPreviewSPI.h */; };
 		7A36D0F9223AD9AB00B0522E /* CommonCryptoSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A36D0F8223AD9AB00B0522E /* CommonCryptoSPI.h */; };
 		7A3A6A8020CADB4700317AAE /* NSImageSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A3A6A7F20CADB4600317AAE /* NSImageSPI.h */; };
+		93468E672714A7CD009983E3 /* FilePortSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 93468E662714A7CD009983E3 /* FilePortSPI.h */; };
 		93B38EBE25821CB600198E63 /* SpeechSoftLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B38EBD25821CB600198E63 /* SpeechSoftLink.h */; };
 		93B38EC025821CD800198E63 /* SpeechSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93B38EBF25821CD700198E63 /* SpeechSoftLink.mm */; };
 		93B38EC225821D2200198E63 /* SpeechSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B38EC125821D2200198E63 /* SpeechSPI.h */; };
@@ -376,6 +377,7 @@
 		71B1141F26823ACD004D6701 /* SystemPreviewSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemPreviewSPI.h; sourceTree = "<group>"; };
 		7A36D0F8223AD9AB00B0522E /* CommonCryptoSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonCryptoSPI.h; sourceTree = "<group>"; };
 		7A3A6A7F20CADB4600317AAE /* NSImageSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSImageSPI.h; sourceTree = "<group>"; };
+		93468E662714A7CD009983E3 /* FilePortSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePortSPI.h; sourceTree = "<group>"; };
 		93B38EBD25821CB600198E63 /* SpeechSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechSoftLink.h; sourceTree = "<group>"; };
 		93B38EBF25821CD700198E63 /* SpeechSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpeechSoftLink.mm; sourceTree = "<group>"; };
 		93B38EC125821D2200198E63 /* SpeechSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpeechSPI.h; sourceTree = "<group>"; };
@@ -534,6 +536,7 @@
 				DF83E208263734F1000825EF /* CryptoKitPrivateSPI.h */,
 				0C2DA1251F3BEB4900DBC317 /* DataDetectorsCoreSPI.h */,
 				1D12CC4A2411BCAE00FDA0A3 /* FeatureFlagsSPI.h */,
+				93468E662714A7CD009983E3 /* FilePortSPI.h */,
 				CE5673862151A7B9002F92D7 /* IOKitSPI.h */,
 				0C2DA1261F3BEB4900DBC317 /* IOPMLibSPI.h */,
 				0C2DA1271F3BEB4900DBC317 /* IOPSLibSPI.h */,
@@ -900,6 +903,7 @@
 				A1175B571F6B470500C4B9F0 /* DefaultSearchProvider.h in Headers */,
 				0C2D9E731EEF5AF600DBC317 /* ExportMacros.h in Headers */,
 				1D12CC4B2411BCAE00FDA0A3 /* FeatureFlagsSPI.h in Headers */,
+				93468E672714A7CD009983E3 /* FilePortSPI.h in Headers */,
 				F44291601FA5261E002CC93E /* FileSizeFormatter.h in Headers */,
 				0C5AF91B1F43A4C7002EAC02 /* GraphicsServicesSPI.h in Headers */,
 				1C022EFF22CFEC53006DF01B /* Gunzip.h in Headers */,

Copied: trunk/Source/WebCore/PAL/pal/spi/cocoa/FilePortSPI.h (from rev 284058, trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl) (0 => 284059)


--- trunk/Source/WebCore/PAL/pal/spi/cocoa/FilePortSPI.h	                        (rev 0)
+++ trunk/Source/WebCore/PAL/pal/spi/cocoa/FilePortSPI.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#include <System/sys/fileport.h>
+
+#else
+
+extern "C" {
+int fileport_makeport(int, mach_port_t*);
+int fileport_makefd(mach_port_t);
+}
+
+#endif // #if USE(APPLE_INTERNAL_SDK)
+

Modified: trunk/Source/WebCore/bindings/js/BufferSource.h (284058 => 284059)


--- trunk/Source/WebCore/bindings/js/BufferSource.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebCore/bindings/js/BufferSource.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -49,6 +49,13 @@
             return buffer ? static_cast<const uint8_t*>(buffer->data()) : nullptr;
         }, m_variant);
     }
+    
+    void* mutableData() const
+    {
+        return std::visit([](auto& buffer) -> void* {
+            return buffer->data();
+        }, m_variant);
+    }
 
     size_t length() const
     {

Modified: trunk/Source/WebKit/ChangeLog (284058 => 284059)


--- trunk/Source/WebKit/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,52 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        Let network process open the file and pass file descriptor to web process, so that web process can read and 
+        write the file without sending IPC messages. Currently getting file size, truncating file and syncing file are 
+        still performed by network process.
+
+        * NetworkProcess/storage/FileSystemStorageError.h:
+        (WebKit::convertToException):
+        * NetworkProcess/storage/FileSystemStorageHandle.cpp:
+        (WebKit::FileSystemStorageHandle::createSyncAccessHandle):
+        (WebKit::FileSystemStorageHandle::truncate):
+        (WebKit::FileSystemStorageHandle::flush):
+        (WebKit::FileSystemStorageHandle::close):
+        * NetworkProcess/storage/FileSystemStorageHandle.h:
+        * NetworkProcess/storage/NetworkStorageManager.cpp:
+        (WebKit::NetworkStorageManager::createSyncAccessHandle):
+        * NetworkProcess/storage/NetworkStorageManager.h:
+        * NetworkProcess/storage/NetworkStorageManager.messages.in:
+        * Platform/IPC/SharedFileHandle.cpp: Added.
+        (IPC::SharedFileHandle::create):
+        (IPC::SharedFileHandle::encode const):
+        (IPC::SharedFileHandle::decode):
+        * Platform/IPC/SharedFileHandle.h: Added.
+        (IPC::SharedFileHandle::handle):
+        (IPC::SharedFileHandle::SharedFileHandle):
+        * Platform/IPC/cocoa/SharedFileHandleCocoa.cpp: Added.
+        (IPC::SharedFileHandle::create):
+        (IPC::SharedFileHandle::encode const):
+        (IPC::SharedFileHandle::decode):
+        * Sources.txt:
+        * UIProcess/API/Cocoa/WKPreferences.mm:
+        (-[WKPreferences _fileSystemAccessEnabled]):
+        (-[WKPreferences _setFileSystemAccessEnabled:]):
+        (-[WKPreferences _storageAPIEnabled]):
+        (-[WKPreferences _setStorageAPIEnabled:]):
+        (-[WKPreferences _accessHandleEnabled]):
+        (-[WKPreferences _setAccessHandleEnabled:]):
+        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp:
+        (WebKit::WebFileSystemStorageConnection::createSyncAccessHandle):
+        * WebProcess/com.apple.WebProcess.sb.in:
+
 2021-10-12  Chris Dumez  <[email protected]>
 
         Decrease use of makeWeakPtr()

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageError.h (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageError.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageError.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -31,9 +31,10 @@
 namespace WebKit {
 
 enum class FileSystemStorageError : uint8_t {
+    BackendNotSupported,
     FileNotFound,
+    InvalidModification,
     InvalidName,
-    InvalidModification,
     InvalidState,
     TypeMismatch,
     Unknown
@@ -42,16 +43,18 @@
 inline WebCore::Exception convertToException(FileSystemStorageError error)
 {
     switch (error) {
+    case FileSystemStorageError::BackendNotSupported:
+        return WebCore::Exception { WebCore::NotSupportedError, "Backend does not support this operation" };
     case FileSystemStorageError::FileNotFound:
         return WebCore::Exception { WebCore::NotFoundError };
     case FileSystemStorageError::InvalidModification:
         return WebCore::Exception { WebCore::InvalidModificationError };
-    case FileSystemStorageError::TypeMismatch:
-        return WebCore::Exception { WebCore::TypeError };
     case FileSystemStorageError::InvalidName:
         return WebCore::Exception { WebCore::UnknownError, "Name is invalid" };
     case FileSystemStorageError::InvalidState:
         return WebCore::Exception { WebCore::InvalidStateError };
+    case FileSystemStorageError::TypeMismatch:
+        return WebCore::Exception { WebCore::TypeError };
     case FileSystemStorageError::Unknown:
         break;
     }
@@ -74,9 +77,10 @@
 template<> struct EnumTraits<WebKit::FileSystemStorageError> {
     using values = EnumValues<
         WebKit::FileSystemStorageError,
+        WebKit::FileSystemStorageError::BackendNotSupported,
         WebKit::FileSystemStorageError::FileNotFound,
+        WebKit::FileSystemStorageError::InvalidModification,
         WebKit::FileSystemStorageError::InvalidName,
-        WebKit::FileSystemStorageError::InvalidModification,
         WebKit::FileSystemStorageError::InvalidState,
         WebKit::FileSystemStorageError::TypeMismatch,
         WebKit::FileSystemStorageError::Unknown

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.cpp (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -28,6 +28,7 @@
 
 #include "FileSystemStorageError.h"
 #include "FileSystemStorageManager.h"
+#include "SharedFileHandle.h"
 #include <wtf/Scope.h>
 
 namespace WebKit {
@@ -143,7 +144,7 @@
     return restPath.split(pathSeparator);
 }
 
-Expected<WebCore::FileSystemSyncAccessHandleIdentifier, FileSystemStorageError> FileSystemStorageHandle::createSyncAccessHandle()
+Expected<FileSystemStorageHandle::AccessHandleInfo, FileSystemStorageError> FileSystemStorageHandle::createSyncAccessHandle()
 {
     if (!m_manager)
         return makeUnexpected(FileSystemStorageError::Unknown);
@@ -152,9 +153,20 @@
     if (!acquired)
         return makeUnexpected(FileSystemStorageError::InvalidState);
 
+    m_handle = FileSystem::openFile(m_path, FileSystem::FileOpenMode::ReadWrite);
+    if (m_handle == FileSystem::invalidPlatformFileHandle)
+        return makeUnexpected(FileSystemStorageError::Unknown);
+
+    auto ipcHandle = IPC::SharedFileHandle::create(m_handle);
+    if (!ipcHandle) {
+        FileSystem::closeFile(m_handle);
+        m_handle = FileSystem::invalidPlatformFileHandle;
+        return makeUnexpected(FileSystemStorageError::BackendNotSupported);
+    }
+
     ASSERT(!m_activeSyncAccessHandle);
     m_activeSyncAccessHandle = WebCore::FileSystemSyncAccessHandleIdentifier::generateThreadSafe();
-    return *m_activeSyncAccessHandle;
+    return std::pair { *m_activeSyncAccessHandle, WTFMove(*ipcHandle) };
 }
 
 Expected<uint64_t, FileSystemStorageError> FileSystemStorageHandle::getSize(WebCore::FileSystemSyncAccessHandleIdentifier accessHandleIdentifier)
@@ -180,12 +192,8 @@
     if (!m_activeSyncAccessHandle || *m_activeSyncAccessHandle != accessHandleIdentifier)
         return FileSystemStorageError::Unknown;
 
-    auto handle = FileSystem::openFile(m_path, FileSystem::FileOpenMode::ReadWrite);
-    auto closeFileScope = makeScopeExit([&] {
-        FileSystem::closeFile(handle);
-    });
-
-    auto result = FileSystem::truncateFile(handle, size);
+    ASSERT(m_handle != FileSystem::invalidPlatformFileHandle);
+    auto result = FileSystem::truncateFile(m_handle, size);
     if (!result)
         return FileSystemStorageError::Unknown;
 
@@ -200,7 +208,11 @@
     if (!m_activeSyncAccessHandle || *m_activeSyncAccessHandle != accessHandleIdentifier)
         return FileSystemStorageError::Unknown;
 
-    // FIXME: when write operation is implemented, perform actual flush here.
+    ASSERT(m_handle != FileSystem::invalidPlatformFileHandle);
+    auto result = FileSystem::flushFile(m_handle);
+    if (!result)
+        return FileSystemStorageError::Unknown;
+
     return std::nullopt;
 }
 
@@ -212,6 +224,10 @@
     if (!m_activeSyncAccessHandle || *m_activeSyncAccessHandle != accessHandleIdentifier)
         return FileSystemStorageError::Unknown;
 
+    ASSERT(m_handle != FileSystem::invalidPlatformFileHandle);
+    FileSystem::closeFile(m_handle);
+    m_handle = FileSystem::invalidPlatformFileHandle;
+
     m_manager->releaseLockForFile(m_path, m_identifier);
     m_activeSyncAccessHandle = std::nullopt;
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/FileSystemStorageHandle.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -30,6 +30,10 @@
 #include <WebCore/FileSystemSyncAccessHandleIdentifier.h>
 #include <wtf/WeakPtr.h>
 
+namespace IPC {
+class SharedFileHandle;
+}
+
 namespace WebKit {
 
 class FileSystemStorageManager;
@@ -53,7 +57,8 @@
     Expected<Vector<String>, FileSystemStorageError> getHandleNames();
     Expected<std::pair<WebCore::FileSystemHandleIdentifier, bool>, FileSystemStorageError> getHandle(IPC::Connection::UniqueID, String&& name);
 
-    Expected<WebCore::FileSystemSyncAccessHandleIdentifier, FileSystemStorageError> createSyncAccessHandle();
+    using AccessHandleInfo = std::pair<WebCore::FileSystemSyncAccessHandleIdentifier, IPC::SharedFileHandle>;
+    Expected<AccessHandleInfo, FileSystemStorageError> createSyncAccessHandle();
     Expected<uint64_t, FileSystemStorageError> getSize(WebCore::FileSystemSyncAccessHandleIdentifier);
     std::optional<FileSystemStorageError> truncate(WebCore::FileSystemSyncAccessHandleIdentifier, uint64_t size);
     std::optional<FileSystemStorageError> flush(WebCore::FileSystemSyncAccessHandleIdentifier);
@@ -68,6 +73,7 @@
     String m_path;
     String m_name;
     std::optional<WebCore::FileSystemSyncAccessHandleIdentifier> m_activeSyncAccessHandle;
+    FileSystem::PlatformFileHandle m_handle { FileSystem::invalidPlatformFileHandle };
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -226,7 +226,7 @@
     completionHandler(handle->resolve(targetIdentifier));
 }
 
-void NetworkStorageManager::createSyncAccessHandle(WebCore::FileSystemHandleIdentifier identifier, CompletionHandler<void(Expected<WebCore::FileSystemSyncAccessHandleIdentifier, FileSystemStorageError>)>&& completionHandler)
+void NetworkStorageManager::createSyncAccessHandle(WebCore::FileSystemHandleIdentifier identifier, CompletionHandler<void(Expected<AccessHandleInfo, FileSystemStorageError>)>&& completionHandler)
 {
     ASSERT(!RunLoop::isMain());
 

Modified: trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -33,6 +33,10 @@
 #include <WebCore/FileSystemSyncAccessHandleIdentifier.h>
 #include <pal/SessionID.h>
 
+namespace IPC {
+class SharedFileHandle;
+}
+
 namespace WebCore {
 struct ClientOrigin;
 }
@@ -70,7 +74,8 @@
     void getDirectoryHandle(IPC::Connection&, WebCore::FileSystemHandleIdentifier, String&& name, bool createIfNecessary, CompletionHandler<void(Expected<WebCore::FileSystemHandleIdentifier, FileSystemStorageError>)>&&);
     void removeEntry(WebCore::FileSystemHandleIdentifier, const String& name, bool deleteRecursively, CompletionHandler<void(std::optional<FileSystemStorageError>)>&&);
     void resolve(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemHandleIdentifier, CompletionHandler<void(Expected<Vector<String>, FileSystemStorageError>)>&&);
-    void createSyncAccessHandle(WebCore::FileSystemHandleIdentifier, CompletionHandler<void(Expected<WebCore::FileSystemSyncAccessHandleIdentifier, FileSystemStorageError>)>&&);
+    using AccessHandleInfo = std::pair<WebCore::FileSystemSyncAccessHandleIdentifier, IPC::SharedFileHandle>;
+    void createSyncAccessHandle(WebCore::FileSystemHandleIdentifier, CompletionHandler<void(Expected<AccessHandleInfo, FileSystemStorageError>)>&&);
     void getSizeForAccessHandle(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(Expected<uint64_t, FileSystemStorageError>)>&&);
     void truncateForAccessHandle(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemSyncAccessHandleIdentifier, uint64_t size, CompletionHandler<void(std::optional<FileSystemStorageError>)>&&);
     void flushForAccessHandle(WebCore::FileSystemHandleIdentifier, WebCore::FileSystemSyncAccessHandleIdentifier, CompletionHandler<void(std::optional<FileSystemStorageError>)>&&);

Modified: trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in (284058 => 284059)


--- trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/NetworkProcess/storage/NetworkStorageManager.messages.in	2021-10-12 23:35:55 UTC (rev 284059)
@@ -33,7 +33,7 @@
     RemoveEntry(WebCore::FileSystemHandleIdentifier identifier, String name, bool deleteRecursively) -> (std::optional<WebKit::FileSystemStorageError> result) Async
     Resolve(WebCore::FileSystemHandleIdentifier identifier, WebCore::FileSystemHandleIdentifier targetIdentifier) -> (Expected<Vector<String>, WebKit::FileSystemStorageError> result) Async
 
-    CreateSyncAccessHandle(WebCore::FileSystemHandleIdentifier identifier) -> (Expected<WebCore::FileSystemSyncAccessHandleIdentifier, WebKit::FileSystemStorageError> result) Async
+    CreateSyncAccessHandle(WebCore::FileSystemHandleIdentifier identifier) -> (Expected<std::pair<WebCore::FileSystemSyncAccessHandleIdentifier, IPC::SharedFileHandle>, WebKit::FileSystemStorageError> result) Async
     GetSizeForAccessHandle(WebCore::FileSystemHandleIdentifier identifier, WebCore::FileSystemSyncAccessHandleIdentifier accessHandleIdentifier) -> (Expected<uint64_t, WebKit::FileSystemStorageError> result) Async
     TruncateForAccessHandle(WebCore::FileSystemHandleIdentifier identifier, WebCore::FileSystemSyncAccessHandleIdentifier accessHandleIdentifier, uint64_t size) -> (std::optional<WebKit::FileSystemStorageError> result) Async
     FlushForAccessHandle(WebCore::FileSystemHandleIdentifier identifier, WebCore::FileSystemSyncAccessHandleIdentifier accessHandleIdentifier) -> (std::optional<WebKit::FileSystemStorageError> result) Async

Copied: trunk/Source/WebKit/Platform/IPC/SharedFileHandle.cpp (from rev 284058, trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl) (0 => 284059)


--- trunk/Source/WebKit/Platform/IPC/SharedFileHandle.cpp	                        (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/SharedFileHandle.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 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 "SharedFileHandle.h"
+
+namespace IPC {
+
+#if !PLATFORM(COCOA)
+
+std::optional<SharedFileHandle> SharedFileHandle::create(FileSystem::PlatformFileHandle)
+{
+    return std::nullopt;
+}
+
+void SharedFileHandle::encode(Encoder&) const
+{
+}
+
+std::optional<SharedFileHandle> SharedFileHandle::decode(Decoder&)
+{
+    return std::nullopt;
+}
+
+#endif
+
+} // namespace IPC

Copied: trunk/Source/WebKit/Platform/IPC/SharedFileHandle.h (from rev 284058, trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl) (0 => 284059)


--- trunk/Source/WebKit/Platform/IPC/SharedFileHandle.h	                        (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/SharedFileHandle.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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 <fcntl.h>
+#include <wtf/FileSystem.h>
+
+namespace IPC {
+
+class Decoder;
+class Encoder;
+
+class SharedFileHandle {
+public:
+    static std::optional<SharedFileHandle> create(FileSystem::PlatformFileHandle);
+
+    SharedFileHandle() = default;
+    FileSystem::PlatformFileHandle handle() { return m_handle; }
+
+    void encode(Encoder&) const;
+
+    static std::optional<SharedFileHandle> decode(Decoder&);
+    
+private:
+    explicit SharedFileHandle(FileSystem::PlatformFileHandle handle)
+        : m_handle(handle)
+    {
+    }
+
+    FileSystem::PlatformFileHandle m_handle { FileSystem::invalidPlatformFileHandle };
+};
+
+} // namespace IPC
+
+

Copied: trunk/Source/WebKit/Platform/IPC/cocoa/SharedFileHandleCocoa.cpp (from rev 284058, trunk/Source/WebCore/Modules/filesystemaccess/FileSystemSyncAccessHandle.idl) (0 => 284059)


--- trunk/Source/WebKit/Platform/IPC/cocoa/SharedFileHandleCocoa.cpp	                        (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/cocoa/SharedFileHandleCocoa.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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 "SharedFileHandle.h"
+
+#include "MachPort.h"
+#include <pal/spi/cocoa/FilePortSPI.h>
+
+namespace IPC {
+
+std::optional<SharedFileHandle> SharedFileHandle::create(FileSystem::PlatformFileHandle handle)
+{
+    return SharedFileHandle { handle };
+}
+
+void SharedFileHandle::encode(Encoder& encoder) const
+{
+    mach_port_name_t fileport = MACH_PORT_NULL;
+    if (fileport_makeport(m_handle, &fileport) == -1) {
+        encoder << MachPort();
+        return;
+    }
+
+    encoder << MachPort(fileport, MACH_MSG_TYPE_MOVE_SEND);
+}
+
+std::optional<SharedFileHandle> SharedFileHandle::decode(Decoder& decoder)
+{
+    MachPort machPort;
+    if (!decoder.decode(machPort))
+        return std::nullopt;
+    
+    int fd = fileport_makefd(machPort.port());
+    if (fd == -1)
+        return SharedFileHandle { };
+
+    return SharedFileHandle::create(fileport_makefd(machPort.port()));
+}
+
+} // namespace IPC

Modified: trunk/Source/WebKit/Sources.txt (284058 => 284059)


--- trunk/Source/WebKit/Sources.txt	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/Sources.txt	2021-10-12 23:35:55 UTC (rev 284059)
@@ -173,6 +173,7 @@
 Platform/IPC/StreamClientConnection.cpp @no-unify
 Platform/IPC/StreamConnectionBuffer.cpp @no-unify
 Platform/IPC/StreamConnectionWorkQueue.cpp @no-unify
+Platform/IPC/SharedFileHandle.cpp @no-unify
 Platform/IPC/StreamServerConnection.cpp @no-unify
 Platform/IPC/StringReference.cpp @no-unify
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm (284058 => 284059)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1517,6 +1517,36 @@
     _preferences->setRequiresPageVisibilityToPlayAudio(requires);
 }
 
+- (BOOL)_fileSystemAccessEnabled
+{
+    return _preferences->fileSystemAccessEnabled();
+}
+
+- (void)_setFileSystemAccessEnabled:(BOOL)fileSystemAccessEnabled
+{
+    _preferences->setFileSystemAccessEnabled(fileSystemAccessEnabled);
+}
+
+- (BOOL)_storageAPIEnabled
+{
+    return _preferences->storageAPIEnabled();
+}
+
+- (void)_setStorageAPIEnabled:(BOOL)storageAPIEnabled
+{
+    _preferences->setStorageAPIEnabled(storageAPIEnabled);
+}
+
+- (BOOL)_accessHandleEnabled
+{
+    return _preferences->accessHandleEnabled();
+}
+
+- (void)_setAccessHandleEnabled:(BOOL)accessHandleEnabled
+{
+    _preferences->setAccessHandleEnabled(accessHandleEnabled);
+}
+
 @end
 
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h (284058 => 284059)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h	2021-10-12 23:35:55 UTC (rev 284059)
@@ -173,6 +173,9 @@
 @property (nonatomic, setter=_setMediaSessionEnabled:) BOOL _mediaSessionEnabled WK_API_AVAILABLE(macos(12.0), ios(15.0));
 @property (nonatomic, getter=_isExtensibleSSOEnabled, setter=_setExtensibleSSOEnabled:) BOOL _extensibleSSOEnabled WK_API_AVAILABLE(macos(12.0), ios(15.0));
 @property (nonatomic, setter=_setRequiresPageVisibilityToPlayAudio:) BOOL _requiresPageVisibilityToPlayAudio WK_API_AVAILABLE(macos(12.0), ios(15.0));
+@property (nonatomic, setter=_setFileSystemAccessEnabled:) BOOL _fileSystemAccessEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setStorageAPIEnabled:) BOOL _storageAPIEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setAccessHandleEnabled:) BOOL _accessHandleEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 #if !TARGET_OS_IPHONE
 @property (nonatomic, setter=_setWebGLEnabled:) BOOL _webGLEnabled WK_API_AVAILABLE(macos(10.13.4));

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (284058 => 284059)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1472,6 +1472,7 @@
 		93085DDF26E5BCF1000EC6A7 /* NetworkStorageManagerMessagesReplies.h in Headers */ = {isa = PBXBuildFile; fileRef = 93085DCE26E2E902000EC6A7 /* NetworkStorageManagerMessagesReplies.h */; };
 		93085DE026E5BCFD000EC6A7 /* NetworkStorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 93085DC426E1BBBD000EC6A7 /* NetworkStorageManager.h */; };
 		93085DE126E5BD13000EC6A7 /* NetworkStorageManagerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 93085DCD26E2E902000EC6A7 /* NetworkStorageManagerMessages.h */; };
+		93122C862710CCDF001D819F /* SharedFileHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 93122C852710CCDE001D819F /* SharedFileHandle.h */; };
 		9312BAD526F33C2600FDDF5F /* FileSystemStorageManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 931A075026F06310004474CD /* FileSystemStorageManager.h */; };
 		9312BAD626F33C2900FDDF5F /* FileSystemStorageHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 931A075326F06AB4004474CD /* FileSystemStorageHandle.h */; };
 		931A1BE226F870090081A7E5 /* FileSystemStorageError.h in Headers */ = {isa = PBXBuildFile; fileRef = 931A1BE026F85C320081A7E5 /* FileSystemStorageError.h */; };
@@ -1484,6 +1485,8 @@
 		933E835A23A1AE2800DEF289 /* WebIDBServerMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 933E835923A1ADF500DEF289 /* WebIDBServerMessages.h */; };
 		933E835B23A1B75000DEF289 /* WebIDBServerMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933E835823A1ADF500DEF289 /* WebIDBServerMessageReceiver.cpp */; };
 		9342589A255B535A0059EEDD /* MediaPermissionUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 93425898255B534B0059EEDD /* MediaPermissionUtilities.h */; };
+		93468E6B2714AF47009983E3 /* SharedFileHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93468E6A2714AF47009983E3 /* SharedFileHandle.cpp */; };
+		93468E6D2714AF88009983E3 /* SharedFileHandleCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93468E6C2714AF88009983E3 /* SharedFileHandleCocoa.cpp */; };
 		934B724419F5B9BE00AE96D6 /* WKActionMenuItemTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 934B724319F5B9BE00AE96D6 /* WKActionMenuItemTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		9354242C2703BDCB005CA72C /* WebFileSystemStorageConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9354242A2703BDCB005CA72C /* WebFileSystemStorageConnection.h */; };
 		9356F2DC2152B6B500E6D5DF /* WebSWClientConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 517A53021F4793B200DCDC0A /* WebSWClientConnection.h */; };
@@ -4950,6 +4953,7 @@
 		93085DCC26E2E902000EC6A7 /* NetworkStorageManagerMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStorageManagerMessageReceiver.cpp; sourceTree = "<group>"; };
 		93085DCD26E2E902000EC6A7 /* NetworkStorageManagerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkStorageManagerMessages.h; sourceTree = "<group>"; };
 		93085DCE26E2E902000EC6A7 /* NetworkStorageManagerMessagesReplies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkStorageManagerMessagesReplies.h; sourceTree = "<group>"; };
+		93122C852710CCDE001D819F /* SharedFileHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedFileHandle.h; sourceTree = "<group>"; };
 		931A075026F06310004474CD /* FileSystemStorageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSystemStorageManager.h; sourceTree = "<group>"; };
 		931A075126F06310004474CD /* FileSystemStorageManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemStorageManager.cpp; sourceTree = "<group>"; };
 		931A075226F06AB4004474CD /* FileSystemStorageHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemStorageHandle.cpp; sourceTree = "<group>"; };
@@ -4968,6 +4972,8 @@
 		933E835923A1ADF500DEF289 /* WebIDBServerMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebIDBServerMessages.h; path = DerivedSources/WebKit2/WebIDBServerMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
 		9342588F2555DCA50059EEDD /* MediaPermissionUtilities.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPermissionUtilities.mm; sourceTree = "<group>"; };
 		93425898255B534B0059EEDD /* MediaPermissionUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPermissionUtilities.h; sourceTree = "<group>"; };
+		93468E6A2714AF47009983E3 /* SharedFileHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedFileHandle.cpp; sourceTree = "<group>"; };
+		93468E6C2714AF88009983E3 /* SharedFileHandleCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedFileHandleCocoa.cpp; sourceTree = "<group>"; };
 		934B724319F5B9BE00AE96D6 /* WKActionMenuItemTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKActionMenuItemTypes.h; sourceTree = "<group>"; };
 		9354242A2703BDCB005CA72C /* WebFileSystemStorageConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebFileSystemStorageConnection.h; sourceTree = "<group>"; };
 		9354242B2703BDCB005CA72C /* WebFileSystemStorageConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebFileSystemStorageConnection.cpp; sourceTree = "<group>"; };
@@ -7359,6 +7365,8 @@
 				5CC5DB9121488E16006CB8A8 /* SharedBufferCopy.h */,
 				2DC1855EDBFB850BA0B6D06D /* SharedBufferDataReference.cpp */,
 				2DC1881ACBCAB5D57C5C6EF0 /* SharedBufferDataReference.h */,
+				93468E6A2714AF47009983E3 /* SharedFileHandle.cpp */,
+				93122C852710CCDE001D819F /* SharedFileHandle.h */,
 				7B73123625CC8524003B2796 /* StreamClientConnection.cpp */,
 				7B73123325CC8523003B2796 /* StreamClientConnection.h */,
 				7B73123425CC8524003B2796 /* StreamConnectionBuffer.cpp */,
@@ -11132,6 +11140,7 @@
 				1A6D86BF1DF75265007745E8 /* MachMessage.cpp */,
 				1A6D86C01DF75265007745E8 /* MachMessage.h */,
 				BCC56F771159957D001CCAF9 /* MachPort.h */,
+				93468E6C2714AF88009983E3 /* SharedFileHandleCocoa.cpp */,
 			);
 			path = cocoa;
 			sourceTree = "<group>";
@@ -12656,6 +12665,7 @@
 				A183494224EF467800BDC9A8 /* SharedBufferCopy.h in Headers */,
 				2DC18FF6EF2A3130C1301767 /* SharedBufferDataReference.h in Headers */,
 				F4A6D6BC254CA3E900B65FAA /* SharedDisplayListHandle.h in Headers */,
+				93122C862710CCDF001D819F /* SharedFileHandle.h in Headers */,
 				1A24BED5120894D100FBB059 /* SharedMemory.h in Headers */,
 				CD4B4D9D1E765E0000D27092 /* SharedRingBufferStorage.h in Headers */,
 				8313F7EC1F7DAE0800B944EB /* SharedStringHashStore.h in Headers */,
@@ -14618,6 +14628,8 @@
 				2D92A787212B6AB100F493FD /* ShareableBitmap.cpp in Sources */,
 				2DC18FEBF337B9671C88E3CD /* SharedBufferCopy.cpp in Sources */,
 				2DC181245B549343BC98164C /* SharedBufferDataReference.cpp in Sources */,
+				93468E6B2714AF47009983E3 /* SharedFileHandle.cpp in Sources */,
+				93468E6D2714AF88009983E3 /* SharedFileHandleCocoa.cpp in Sources */,
 				A1ADAFB62368E6A8009CB776 /* SharedMemory.cpp in Sources */,
 				575B1BB923CE9C0B0020639A /* SimulatedInputDispatcher.cpp in Sources */,
 				2DE6943D18BD2A68005C15E5 /* SmartMagnificationControllerMessageReceiver.cpp in Sources */,

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp (284058 => 284059)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFileSystemStorageConnection.cpp	2021-10-12 23:35:55 UTC (rev 284059)
@@ -121,7 +121,8 @@
         if (!result)
             return completionHandler(convertToException(result.error()));
 
-        completionHandler(WTFMove(result.value()));
+        auto resultValue = result.value();
+        completionHandler(std::pair { resultValue.first, resultValue.second.handle() });
     });
 }
 

Modified: trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in (284058 => 284059)


--- trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1978,6 +1978,7 @@
         (syscall-number SYS_connect_nocancel)
         (syscall-number SYS_sendto_nocancel)
         (syscall-number SYS_fsgetpath)
+        (syscall-number SYS_fileport_makefd)
         (syscall-number SYS_fileport_makeport)
         (syscall-number SYS_guarded_open_np)
         (syscall-number SYS_guarded_close_np)

Modified: trunk/Tools/ChangeLog (284058 => 284059)


--- trunk/Tools/ChangeLog	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Tools/ChangeLog	2021-10-12 23:35:55 UTC (rev 284059)
@@ -1,3 +1,16 @@
+2021-10-12  Sihui Liu  <[email protected]>
+
+        Implement FileSystemSyncAccessHandle read() and write()
+        https://bugs.webkit.org/show_bug.cgi?id=231466
+        <rdar://problem/84050394>
+
+        Reviewed by Youenn Fablet.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm: Added.
+        (-[FileSystemAccessMessageHandler userContentController:didReceiveScriptMessage:]):
+        (test):
+
 2021-10-12  Alex Christensen  <[email protected]>
 
         Rename AdAttributionDaemon to adattributiond

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (284058 => 284059)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-10-12 23:33:35 UTC (rev 284058)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2021-10-12 23:35:55 UTC (rev 284059)
@@ -854,6 +854,7 @@
 		933D631D1FCB76200032ECD6 /* Hasher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 933D631B1FCB76180032ECD6 /* Hasher.cpp */; };
 		9342589C255B609B0059EEDD /* SpeechRecognition.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9342589B255B609A0059EEDD /* SpeechRecognition.mm */; };
 		9342589E255B6A120059EEDD /* speechrecognition-user-permission-persistence.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9342589D255B66A00059EEDD /* speechrecognition-user-permission-persistence.html */; };
+		93468E6F2714B4F2009983E3 /* FileSystemAccess.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93468E6E2714B4F1009983E3 /* FileSystemAccess.mm */; };
 		935786CC20F6A2700000CDFC /* IndexedDB.sqlite3-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C520F69FED0040DC1B /* IndexedDB.sqlite3-wal */; };
 		935786CD20F6A2910000CDFC /* IndexedDB.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C720F69FEE0040DC1B /* IndexedDB.sqlite3 */; };
 		935786CE20F6A2A10000CDFC /* IndexedDB.sqlite3-shm in Copy Resources */ = {isa = PBXBuildFile; fileRef = 934FA5C620F69FED0040DC1B /* IndexedDB.sqlite3-shm */; };
@@ -2582,6 +2583,7 @@
 		933D631B1FCB76180032ECD6 /* Hasher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Hasher.cpp; sourceTree = "<group>"; };
 		9342589B255B609A0059EEDD /* SpeechRecognition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpeechRecognition.mm; sourceTree = "<group>"; };
 		9342589D255B66A00059EEDD /* speechrecognition-user-permission-persistence.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "speechrecognition-user-permission-persistence.html"; sourceTree = "<group>"; };
+		93468E6E2714B4F1009983E3 /* FileSystemAccess.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileSystemAccess.mm; sourceTree = "<group>"; };
 		934FA5C520F69FED0040DC1B /* IndexedDB.sqlite3-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IndexedDB.sqlite3-wal"; sourceTree = "<group>"; };
 		934FA5C620F69FED0040DC1B /* IndexedDB.sqlite3-shm */ = {isa = PBXFileReference; lastKnownFileType = file; path = "IndexedDB.sqlite3-shm"; sourceTree = "<group>"; };
 		934FA5C720F69FEE0040DC1B /* IndexedDB.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = IndexedDB.sqlite3; sourceTree = "<group>"; };
@@ -3510,6 +3512,7 @@
 				6B25A75125DC8D4E0070744F /* EventAttribution.mm */,
 				CDA29B2820FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm */,
 				1D12BEBF245BEF85004C0B7A /* ExitPiPOnSuspendVideoElement.mm */,
+				93468E6E2714B4F1009983E3 /* FileSystemAccess.mm */,
 				2D8104CB1BEC13E70020DA46 /* FindInPage.mm */,
 				51242CD42374E61E00EED9C1 /* FindInPageAPI.mm */,
 				118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm */,
@@ -5568,6 +5571,7 @@
 				7CCE7EF11A411AE600447C4C /* FailedLoad.cpp in Sources */,
 				579651E7216BFDED006EBFE5 /* FidoHidMessageTest.cpp in Sources */,
 				7A32D74A1F02151500162C44 /* FileMonitor.cpp in Sources */,
+				93468E6F2714B4F2009983E3 /* FileSystemAccess.mm in Sources */,
 				7CCE7EF31A411AE600447C4C /* Find.cpp in Sources */,
 				7C83E0BB1D0A650000FEBCF3 /* FindInPage.mm in Sources */,
 				51242CD52374E62500EED9C1 /* FindInPageAPI.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm (0 => 284059)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/FileSystemAccess.mm	2021-10-12 23:35:55 UTC (rev 284059)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 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"
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import "PlatformUtilities.h"
+#import "TestURLSchemeHandler.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <WebKit/WKWebViewPrivate.h>
+
+static bool receivedScriptMessage;
+static RetainPtr<WKScriptMessage> lastScriptMessage;
+
+@interface FileSystemAccessMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation FileSystemAccessMessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    receivedScriptMessage = true;
+    lastScriptMessage = message;
+}
+
+@end
+
+static NSString *mainFrameString = @"<script> \
+    function start() { \
+        var worker = new Worker('worker.js'); \
+        worker._onmessage_ = function(event) { \
+            window.webkit.messageHandlers.testHandler.postMessage(event.data); \
+        }; \
+    } \
+    window.webkit.messageHandlers.testHandler.postMessage('page is loaded'); \
+    </script>";
+
+static const char* workerBytes = R"TESTRESOURCE(
+async function test()
+{
+    try {
+        var rootHandle = await navigator.storage.getDirectory();
+        var fileHandle = await rootHandle.getFileHandle('file-system-access.txt', { 'create' : true });
+        var accessHandle = await fileHandle.createSyncAccessHandle();
+        var buffer = new ArrayBuffer(10);
+        var writeSize = accessHandle.write(buffer, { "at" : 0 });
+        self.postMessage('success: write ' + writeSize + ' bytes');
+    } catch (err) {
+        self.postMessage('error: ' + err.name + ' - ' + err.message);
+        close();
+    }
+}
+test();
+)TESTRESOURCE";
+
+TEST(FileSystemAccess, ProcessCrashDuringWrite)
+{
+    auto handler = adoptNS([[FileSystemAccessMessageHandler alloc] init]);
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
+    auto preferences = [configuration preferences];
+    preferences._fileSystemAccessEnabled = YES;
+    preferences._accessHandleEnabled = YES;
+    preferences._storageAPIEnabled = YES;
+    auto schemeHandler = adoptNS([[TestURLSchemeHandler alloc] init]);
+    [schemeHandler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
+        RetainPtr<NSURLResponse> response;
+        RetainPtr<NSData> data;
+        NSURL *requestURL = task.request.URL;
+        EXPECT_WK_STREQ("webkit://webkit.org/worker.js", requestURL.absoluteString);
+        response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:@"text/_javascript_" expectedContentLength:0 textEncodingName:nil]);
+        data = "" dataWithBytes:workerBytes length:strlen(workerBytes)];
+        [task didReceiveResponse:response.get()];
+        [task didReceiveData:data.get()];
+        [task didFinish];
+    }];
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"webkit"];
+
+    // load first web view & start test
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    [webView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
+
+    [webView evaluateJavaScript:@"start()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
+
+    auto secondWebView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get()]);
+    [secondWebView loadHTMLString:mainFrameString baseURL:[NSURL URLWithString:@"webkit://webkit.org"]];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"page is loaded", [lastScriptMessage body]);
+
+    // Access handle cannot be created when there is an open one.
+    [secondWebView evaluateJavaScript:@"start()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    receivedScriptMessage = false;
+    EXPECT_WK_STREQ(@"error: InvalidStateError - The object is in an invalid state.", [lastScriptMessage body]);
+
+    // Open access handle should be closed when web process crashes.
+    [webView _killWebContentProcess];
+
+    [secondWebView evaluateJavaScript:@"start()" completionHandler:nil];
+    TestWebKitAPI::Util::run(&receivedScriptMessage);
+    EXPECT_WK_STREQ(@"success: write 10 bytes", [lastScriptMessage body]);
+}
+
+#endif // USE(APPLE_INTERNAL_SDK)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to