Skip to content

Commit a2fa44b

Browse files
authored
Merge pull request #1654 from MicrosoftEdge/api-multiprofile-draft
Add spec for MultiProfile.md
2 parents 41f9aec + a51e651 commit a2fa44b

1 file changed

Lines changed: 255 additions & 0 deletions

File tree

specs/MultiProfile.md

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
API spec for multiple profile support
2+
===
3+
4+
# Background
5+
6+
Previously, all WebView2s can only use one fixed Edge profile in the browser process, which is
7+
normally the **Default** profile or the profile specified by the **--profile-directory** command
8+
line switch. It means different WebView2s share a single profile directory on disk for data storage,
9+
which might bring security concerns over cookies, autofill data, and password management etc.. Also,
10+
they might also interfere with each other in terms of user preference settings.
11+
12+
Although you can make your WebView2s use different user data directories to achieve data separation,
13+
in such way you'll have to be running multiple browser instances (each including a browser process
14+
and a bunch of child processes), which means much more consumption for system resources including
15+
memory, CPU footprint, disk space etc. so it is not desirable.
16+
17+
With all above, we're adding these new APIs to support multiple profiles, so that you can have
18+
multiple WebView2s running with separate profiles under a single user data directory (i.e. a single
19+
browser instance at runtime), which means separate cookies, user preference settings, and various
20+
data storage etc., to help you build a more wonderful experience for your application.
21+
22+
# Examples
23+
24+
## Provide options to create WebView2 with a specific profile
25+
26+
### Win32 C++
27+
28+
```cpp
29+
HRESULT AppWindow::CreateControllerWithOptions()
30+
{
31+
auto webViewEnvironment4 =
32+
m_webViewEnvironment.try_query<ICoreWebView2Environment4>();
33+
if (!webViewEnvironment4)
34+
{
35+
FeatureNotAvailable();
36+
return S_OK;
37+
}
38+
39+
Microsoft::WRL::ComPtr<ICoreWebView2ControllerOptions> options;
40+
HRESULT hr = webViewEnvironment4->CreateCoreWebView2ControllerOptions(
41+
m_webviewOption.profile.c_str(), m_webviewOption.isInPrivate, options.GetAddressOf());
42+
if (hr == E_INVALIDARG)
43+
{
44+
ShowFailure(hr, L"Unable to create WebView2 due to an invalid profile name.");
45+
CloseAppWindow();
46+
return S_OK;
47+
}
48+
CHECK_FAILURE(hr);
49+
50+
#ifdef USE_WEBVIEW2_WIN10
51+
if (m_dcompDevice || m_wincompCompositor)
52+
#else
53+
if (m_dcompDevice)
54+
#endif
55+
{
56+
CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2CompositionControllerWithOptions(
57+
m_mainWindow, options.Get(),
58+
Callback<ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
59+
[this](
60+
HRESULT result,
61+
ICoreWebView2CompositionController* compositionController) -> HRESULT {
62+
auto controller =
63+
wil::com_ptr<ICoreWebView2CompositionController>(compositionController)
64+
.query<ICoreWebView2Controller>();
65+
return OnCreateCoreWebView2ControllerCompleted(result, controller.get());
66+
})
67+
.Get()));
68+
}
69+
else
70+
{
71+
CHECK_FAILURE(webViewEnvironment4->CreateCoreWebView2ControllerWithOptions(
72+
m_mainWindow, options.Get(),
73+
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
74+
this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)
75+
.Get()));
76+
}
77+
78+
return S_OK;
79+
}
80+
```
81+
82+
## Access the profile property of WebView2
83+
84+
### Win32 C++
85+
86+
```cpp
87+
HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted(HRESULT result, ICoreWebView2Controller* controller)
88+
{
89+
// ...
90+
91+
m_controller = controller;
92+
93+
// Gets the webview object from controller.
94+
wil::com_ptr<ICoreWebView2> coreWebView2;
95+
CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2));
96+
97+
auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();
98+
if (webview7)
99+
{
100+
// Gets the profile property of webview.
101+
wil::com_ptr<ICoreWebView2Profile> profile;
102+
CHECK_FAILURE(webview7->get_Profile(&profile));
103+
104+
// Accesses the profile object.
105+
BOOL inPrivateModeEnabled = FALSE;
106+
CHECK_FAILURE(profile->get_IsInPrivateModeEnabled(&inPrivateModeEnabled));
107+
wil::unique_cotaskmem_string profile_path;
108+
CHECK_FAILURE(profile->get_ProfilePath(&profile_path));
109+
std::wstring str(profile_path.get());
110+
m_profileDirName = str.substr(str.find_last_of(L'\\') + 1);
111+
112+
// update window title with m_profileDirName
113+
UpdateAppTitle();
114+
115+
// update window icon
116+
SetAppIcon(inPrivate);
117+
}
118+
119+
// ...
120+
}
121+
```
122+
123+
# API Details
124+
125+
## Win32 C++
126+
127+
```IDL
128+
interface ICoreWebView2ControllerOptions;
129+
interface ICoreWebView2Environment5;
130+
interface ICoreWebView2_7;
131+
interface ICoreWebView2Profile;
132+
133+
[uuid(C2669A3A-03A9-45E9-97EA-03CD55E5DC03), object, pointer_default(unique)]
134+
interface ICoreWebView2ControllerOptions : IUnknown {
135+
/// `ProfileName` property is to specify a profile name, which is only allowed to contain
136+
/// the following ASCII characters. It has a maximum length of 64 characters excluding the null terminator. It is
137+
/// ASCII case insensitive.
138+
/// alphabet characters: a-z and A-Z
139+
/// digit characters: 0-9
140+
/// and '#', '@', '$', '(', ')', '+', '-', '_', '~', '.', ' ' (space).
141+
/// Note: the text must not end with a period '.' or ' ' (space). And, although upper case letters are
142+
/// allowed, they're treated just as lower case couterparts because the profile name will be mapped to
143+
/// the real profile directory path on disk and Windows file system handles path names in a case-insensitive way.
144+
[propget] HRESULT ProfileName([out, retval] LPWSTR* value);
145+
/// Sets the `ProfileName` property.
146+
[propput] HRESULT ProfileName([in] LPCWSTR value);
147+
148+
/// `IsInPrivateModeEnabled` property is to enable/disable InPrivate mode.
149+
[propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);
150+
/// Sets the `IsInPrivateModeEnabled` property.
151+
[propput] HRESULT IsInPrivateModeEnabled([in] BOOL value);
152+
}
153+
154+
[uuid(57FD205C-39D5-4BA1-8E7B-3E53C323EA87), object, pointer_default(unique)]
155+
interface ICoreWebView2Environment5 : IUnknown
156+
{
157+
/// Create a new ICoreWebView2ControllerOptions to be passed as a parameter of
158+
/// CreateCoreWebView2ControllerWithOptions and CreateCoreWebView2CompositionControllerWithOptions.
159+
/// Returns E_INVALIDARG only in case of invalid profile name.
160+
HRESULT CreateCoreWebView2ControllerOptions(
161+
[in] LPCWSTR profileName,
162+
[in] BOOL isInPrivateModeEnabled,
163+
[out, retval] ICoreWebView2ControllerOptions** options);
164+
165+
/// Create a new WebView with options.
166+
HRESULT CreateCoreWebView2ControllerWithOptions(
167+
[in] HWND parentWindow,
168+
[in] ICoreWebView2ControllerOptions* options,
169+
[in] ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* handler);
170+
171+
/// Create a new WebView in visual hosting mode with options.
172+
HRESULT CreateCoreWebView2CompositionControllerWithOptions(
173+
[in] HWND parentWindow,
174+
[in] ICoreWebView2ControllerOptions* options,
175+
[in] ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler* handler);
176+
}
177+
178+
[uuid(6E5CE5F0-16E6-4A05-97D8-4E256B3EB609), object, pointer_default(unique)]
179+
interface ICoreWebView2_7 : IUnknown {
180+
/// The associated `ICoreWebView2Profile` object.
181+
[propget] HRESULT Profile([out, retval] ICoreWebView2Profile** value);
182+
}
183+
184+
[uuid(3B9A2AF2-E703-4C81-9D25-FCE44312E960), object, pointer_default(unique)]
185+
interface ICoreWebView2Profile : IUnknown {
186+
/// Name of the profile.
187+
[propget] HRESULT ProfileName([out, retval] LPWSTR* value);
188+
189+
/// InPrivate mode is enabled or not.
190+
[propget] HRESULT IsInPrivateModeEnabled([out, retval] BOOL* value);
191+
192+
/// Full path of the profile directory.
193+
[propget] HRESULT ProfilePath([out, retval] LPWSTR* value);
194+
195+
// TODO: All profile-wide operations/settings will be put below in the future.
196+
}
197+
```
198+
199+
## .NET and WinRT
200+
201+
```c#
202+
namespace Microsoft.Web.WebView2.Core
203+
{
204+
runtimeclass CoreWebView2ControllerOptions;
205+
runtimeclass CoreWebView2Environment;
206+
runtimeclass CoreWebView2;
207+
runtimeclass CoreWebView2Profile;
208+
209+
runtimeclass CoreWebView2ControllerOptions
210+
{
211+
String ProfileName { get; set; };
212+
213+
Boolean IsInPrivateModeEnabled { get; set; };
214+
}
215+
216+
runtimeclass CoreWebView2Environment
217+
{
218+
// ...
219+
220+
CoreWebView2ControllerOptions CreateCoreWebView2ControllerOptions(
221+
String ProfileName, Boolean InPrivateModeEnabled);
222+
223+
Windows.Foundation.IAsyncOperation<CoreWebView2Controller>
224+
CreateCoreWebView2ControllerWithOptionsAsync(
225+
CoreWebView2ControllerWindowReference ParentWindow,
226+
CoreWebView2ControllerOptions options);
227+
228+
Windows.Foundation.IAsyncOperation<CoreWebView2CompositionController>
229+
CreateCoreWebView2CompositionControllerWithOptionsAsync(
230+
CoreWebView2ControllerWindowReference ParentWindow,
231+
CoreWebView2ControllerOptions options);
232+
}
233+
234+
runtimeclass CoreWebView2
235+
{
236+
// ...
237+
CoreWebView2Profile Profile { get; };
238+
}
239+
240+
runtimeclass CoreWebView2Profile
241+
{
242+
String ProfileName { get; };
243+
244+
Boolean IsInPrivateModeEnabled { get; };
245+
246+
String ProfilePath { get; };
247+
}
248+
}
249+
```
250+
251+
# Appendix
252+
253+
Next we'll consolidate all profile-wide operations/settings into the interface
254+
`ICoreWebView2Profile`, and will also add support for erasing a profile completely
255+
if strongly requested.

0 commit comments

Comments
 (0)