@@ -11,7 +11,7 @@ as part of the app. Some examples:
11
11
code to print. See https://github.com/MicrosoftEdge/WebView2Feedback/issues/89 .
12
12
- Native side generates a large amount of data for the web side to consume. The data
13
13
might or might not come directly from files. For example the native side has generated
14
- terrabytes of data to produce different graphs on the web side.
14
+ terabytes of data to produce different graphs on the web side.
15
15
See https://github.com/MicrosoftEdge/WebView2Feedback/issues/1005 .
16
16
17
17
To support these scenarios, we are adding an Edge WebView2 API to support sharing
@@ -30,7 +30,7 @@ from native side via an IStream* object that you can get from the shared buffer
30
30
When the application code calls ` PostSharedBufferToScript ` , the script side will
31
31
receive a ` SharedBufferReceived ` event containing the buffer as an ` ArrayBuffer ` object.
32
32
After receiving the shared buffer object, it can access it the same way as any other
33
- ArrayBuffer object, including transering to a web worker to process the data on
33
+ ArrayBuffer object, including transferring to a web worker to process the data on
34
34
the worker thread.
35
35
36
36
As shared buffer normally represent a large memory, instead of waiting for garbage
@@ -53,19 +53,19 @@ The example below illustrates how to send data from application to script for on
53
53
The script code will look like this:
54
54
```
55
55
window.onload = function () {
56
- window.chrome.webview.addEventListener("SharedBufferReceived ", e => {
56
+ window.chrome.webview.addEventListener("sharedbufferreceived ", e => {
57
57
SharedBufferReceived(e);
58
58
});
59
59
}
60
60
61
61
function SharedBufferReceived(e) {
62
- if (e.data && e.data.readOnly ) {
63
- // This is the one time read only buffer
64
- let oneTimeSharedBuffer = e.sharedBuffer;
65
- // Consume the data from the buffer
66
- DisplaySharedBufferData(oneTimeSharedBuffer );
62
+ if (e.additionalData && e.additionalData.contosoBufferKind == "contosoDisplayBuffer" ) {
63
+ let displayBuffer = e.getBuffer();
64
+ // Consume the data from the buffer (in the form of an ArrayBuffer)
65
+ let view = new UInt32Array(displayBuffer);
66
+ DisplaySharedBufferData(view );
67
67
// Release the buffer after consuming the data.
68
- chrome.webview.releaseBuffer(oneTimeSharedBuffer );
68
+ chrome.webview.releaseBuffer(displayBuffer );
69
69
}
70
70
}
71
71
```
@@ -76,18 +76,18 @@ The script code will look like this:
76
76
CHECK_FAILURE (webviewEnvironment->CreateSharedBuffer(bufferSize, &sharedBuffer));
77
77
// Fill data into the shared memory via IStream.
78
78
wil::com_ptr<IStream > stream;
79
- CHECK_FAILURE(sharedBuffer->GetStream (&stream));
79
+ CHECK_FAILURE(sharedBuffer->OpenStream (&stream));
80
80
CHECK_FAILURE(stream->Write(data, dataSize, nullptr));
81
- PCWSTR additionalDataAsJson = L"{\" readOnly \" : true }";
81
+ PCWSTR additionalDataAsJson = L"{\" contosoBufferKind \" :\" contosoDisplayBuffer \" }";
82
82
if (forFrame)
83
83
{
84
84
m_webviewFrame->PostSharedBufferToScript(
85
- sharedBuffer.get(), / * isReadOnlyToScript * /TRUE , additionalDataAsJson);
85
+ sharedBuffer.get(), COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY , additionalDataAsJson);
86
86
}
87
87
else
88
88
{
89
89
m_webView->PostSharedBufferToScript(
90
- sharedBuffer.get(), / * isReadOnlyToScript * /TRUE , additionalDataAsJson);
90
+ sharedBuffer.get(), COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY , additionalDataAsJson);
91
91
}
92
92
// Explicitly close the one time shared buffer to ensure that the resource is released timely.
93
93
sharedBuffer->Close();
@@ -98,21 +98,21 @@ The script code will look like this:
98
98
using (CoreWebView2SharedBuffer sharedBuffer = WebViewEnvironment.CreateSharedBuffer(bufferSize))
99
99
{
100
100
// Fill data using access Stream
101
- using (Stream stream = sharedBuffer.GetStream ())
101
+ using (Stream stream = sharedBuffer.OpenStream ())
102
102
{
103
103
using (StreamWriter writer = new StreamWriter(stream))
104
104
{
105
105
writer.Write(data);
106
106
}
107
107
}
108
- string additionalDataAsJson = "{\"readOnly \":true }";
108
+ string additionalDataAsJson = "{\"contosoBufferKind \":\"contosoDisplayBuffer\" }";
109
109
if (forFrame)
110
110
{
111
- m_webviewFrame.PostSharedBufferToScript(sharedBuffer, /*isReadOnlyToScript*/true , additionalDataAsJson);
111
+ m_webviewFrame.PostSharedBufferToScript(sharedBuffer, CoreWebView2SharedBufferAccess.ReadOnly , additionalDataAsJson);
112
112
}
113
113
else
114
114
{
115
- m_webview.PostSharedBufferToScript(sharedBuffer, /*isReadOnlyToScript*/true , additionalDataAsJson);
115
+ m_webview.PostSharedBufferToScript(sharedBuffer, CoreWebView2SharedBufferAccess.ReadOnly , additionalDataAsJson);
116
116
}
117
117
}
118
118
```
@@ -127,7 +127,6 @@ interface ICoreWebView2Environment11 : IUnknown {
127
127
/// Once shared, the same content of the buffer will be accessible from both
128
128
/// the app process and script in WebView. Modification to the content will be visible
129
129
/// to all parties that have access to the buffer.
130
- /// For 32bit application, the creation will fail with E_INVALIDARG if `size` is larger than 4GB.
131
130
HRESULT CreateSharedBuffer(
132
131
[in] UINT64 size,
133
132
[out, retval] ICoreWebView2SharedBuffer** shared_buffer);
@@ -141,15 +140,17 @@ interface ICoreWebView2SharedBuffer : IUnknown {
141
140
[propget] HRESULT Buffer([out, retval] BYTE** value);
142
141
143
142
/// Get an IStream object that can be used to access the shared buffer.
144
- HRESULT GetStream ([out, retval] IStream** value);
143
+ HRESULT OpenStream ([out, retval] IStream** value);
145
144
146
- /// The file mapping handle of the shared memory of the buffer.
145
+ /// Returns a handle to the file mapping object that backs this shared buffer.
146
+ /// The returned handle is owned by the shared buffer object. You should not
147
+ /// call CloseHandle on it.
147
148
/// Normal app should use `Buffer` or `GetStream` to get memory address
148
149
/// or IStream object to access the buffer.
149
- /// For advanced scenarios, you could duplicate this handle to another application
150
- /// process and create a mapping from the duplicated handle in that process to access
151
- /// the buffer from that separate process.
152
- [propget] HRESULT Handle ([out, retval] HANDLE* value);
150
+ /// For advanced scenarios, you could use file-mapping APIs to obtain other views
151
+ /// or duplicate this handle to another application process and create a view from
152
+ /// the duplicated handle in that process to access the buffer from that separate process.
153
+ [propget] HRESULT FileMappingHandle ([out, retval] HANDLE* value);
153
154
154
155
/// Release the backing shared memory. The application should call this API when no
155
156
/// access to the buffer is needed any more, to ensure that the underlying resources
@@ -174,17 +175,24 @@ interface ICoreWebView2SharedBuffer : IUnknown {
174
175
HRESULT Close();
175
176
}
176
177
178
+ typedef enum COREWEBVIEW2_SHARED_BUFFER_ACCESS {
179
+ // The script only has read access to the shared buffer
180
+ COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY,
181
+ // The script has read and write access to the shared buffer
182
+ COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_WRITE
183
+ } COREWEBVIEW2_SHARED_BUFFER_ACCESS;
184
+
177
185
interface ICoreWebView2_14 : IUnknown {
178
186
/// Share a shared buffer object with script of the main frame in the WebView.
179
187
/// The script will receive a `SharedBufferReceived` event from chrome.webview.
180
- /// The event arg for that event will have the following properties:
181
- /// `sharedBuffer`: an ArrayBuffer object with the backing content from the shared buffer.
182
- /// `data `: an object as the result of parsing `additionalDataAsJson` as JSON string.
188
+ /// The event arg for that event will have the following methods and properties:
189
+ /// `getBuffer()`: returns an ArrayBuffer object with the backing content from the shared buffer.
190
+ /// `additionalData `: an object as the result of parsing `additionalDataAsJson` as JSON string.
183
191
/// This property will be `undefined` if `additionalDataAsJson` is nullptr or empty string.
184
192
/// `source`: with a value set as `chrome.webview` object.
185
193
/// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string,
186
194
/// the API will fail with `E_INVALIDARG`.
187
- /// If `isReadOnlyToScript ` is true , the script will only have read access to the buffer.
195
+ /// If `access ` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY , the script will only have read access to the buffer.
188
196
/// If the script tries to modify the content in a read only buffer, it will cause an access
189
197
/// violation in WebView renderer process and crash the renderer process.
190
198
/// If the shared buffer is already closed, the API will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
@@ -199,7 +207,7 @@ interface ICoreWebView2_14 : IUnknown {
199
207
/// it could result in corrupted data that might even crash the application.
200
208
HRESULT PostSharedBufferToScript(
201
209
[in] ICoreWebView2SharedBuffer* sharedBuffer,
202
- [in] BOOL isReadOnlyToScript ,
210
+ [in] COREWEBVIEW2_SHARED_BUFFER_ACCESS access ,
203
211
[in] LPCWSTR additionalDataAsJson);
204
212
}
205
213
@@ -213,7 +221,7 @@ interface ICoreWebView2Frame4 : IUnknown {
213
221
/// `source`: with a value set as `chrome.webview` object.
214
222
/// If a string is provided as `additionalDataAsJson` but it is not a valid JSON string,
215
223
/// the API will fail with `E_INVALIDARG`.
216
- /// If `isReadOnlyToScript ` is true , the script will only have read access to the buffer.
224
+ /// If `access ` is COREWEBVIEW2_SHARED_BUFFER_ACCESS_READ_ONLY , the script will only have read access to the buffer.
217
225
/// If the script tries to modify the content in a read only buffer, it will cause an access
218
226
/// violation in WebView renderer process and crash the renderer process.
219
227
/// If the shared buffer is already closed, the API will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
@@ -228,7 +236,7 @@ interface ICoreWebView2Frame4 : IUnknown {
228
236
/// it could result in corrupted data that might even crash the application.
229
237
HRESULT PostSharedBufferToScript(
230
238
[in] ICoreWebView2SharedBuffer* sharedBuffer,
231
- [in] BOOL isReadOnlyToScript ,
239
+ [in] COREWEBVIEW2_SHARED_BUFFER_ACCESS access ,
232
240
[in] LPCWSTR additionalDataAsJson);
233
241
}
234
242
@@ -255,27 +263,27 @@ namespace Microsoft.Web.WebView2.Core
255
263
public IntPtr Buffer { get ; };
256
264
257
265
/// The native file mapping handle of the shared memory of the buffer.
258
- /// Normal app should use `GetStream ` to get a Stream object to access the buffer.
266
+ /// Normal app should use `OpenStream ` to get a Stream object to access the buffer.
259
267
/// For advanced scenario, you could use native APIs to duplicate this handle to
260
268
/// another application process and create a mapping from the duplicated handle in
261
269
/// that process to access the buffer from that separate process.
262
- public IntPtr Handle { get ; };
270
+ public System.Runtime.InteropServices. SafeHandle FileMappingHandle { get ; };
263
271
264
- public Stream GetStream ();
272
+ public Stream OpenStream ();
265
273
266
274
void Close ();
267
275
}
268
276
269
277
runtimeclass CoreWebView2
270
278
{
271
279
public void PostSharedBufferToScript(
272
- CoreWebView2SharedBuffer sharedBuffer, bool isReadOnlyToScript , string additionalDataAsJson);
280
+ CoreWebView2SharedBuffer sharedBuffer, CoreWebView2SharedBufferAccess access , string additionalDataAsJson);
273
281
}
274
282
275
283
class CoreWebView2Frame
276
284
{
277
285
public void PostSharedBufferToScript (
278
- CoreWebView2SharedBuffer sharedBuffer , bool isReadOnlyToScript , string additionalDataAsJson );
286
+ CoreWebView2SharedBuffer sharedBuffer , CoreWebView2SharedBufferAccess access , string additionalDataAsJson );
279
287
}
280
288
}
281
289
@@ -297,7 +305,7 @@ namespace Microsoft.Web.WebView2.Core
297
305
{
298
306
UInt64 Size { get ; };
299
307
300
- Windows .Storage .Streams .IRandomAccessStream GetStream ();
308
+ Windows .Storage .Streams .IRandomAccessStream OpenStream ();
301
309
302
310
[interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2SharedBuffer_Manual" )]
303
311
{
@@ -316,7 +324,7 @@ namespace Microsoft.Web.WebView2.Core
316
324
[interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2_14" )]
317
325
{
318
326
void PostSharedBufferToScript (
319
- CoreWebView2SharedBuffer sharedBuffer , Boolean isReadOnlyToScript , String additionalDataAsJson );
327
+ CoreWebView2SharedBuffer sharedBuffer , CoreWebView2SharedBufferAccess access , String additionalDataAsJson );
320
328
}
321
329
}
322
330
@@ -325,7 +333,7 @@ namespace Microsoft.Web.WebView2.Core
325
333
[interface_name (" Microsoft.Web.WebView2.Core.ICoreWebView2Frame4" )]
326
334
{
327
335
void PostSharedBufferToScript (
328
- CoreWebView2SharedBuffer sharedBuffer , Boolean isReadOnlyToScript , String additionalDataAsJson );
336
+ CoreWebView2SharedBuffer sharedBuffer , CoreWebView2SharedBufferAccess access , String additionalDataAsJson );
329
337
}
330
338
}
331
339
}
0 commit comments