Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiprofile's Delete API modify #3069

Open
wants to merge 8 commits into
base: MultipleFile_Delete
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 73 additions & 27 deletions specs/MultiProfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,27 @@ void ScenarioCookieManagement::DeleteAllCookies()
### Delete profile

```cpp
HRESULT AppWindow::DeleteProfile(ICoreWebView2Controller* controller)
HRESULT AppWindow::DeleteProfile(ICoreWebView2* webView2)
{
wil::com_ptr<ICoreWebView2> coreWebView2;
CHECK_FAILURE(controller->get_CoreWebView2(&coreWebView2));
auto webview7 = coreWebView2.try_query<ICoreWebView2_7>();
if (webview7)
{
wil::com_ptr<ICoreWebView2Profile> profile;
CHECK_FAILURE(webview7->get_Profile(&profile));
auto profile2 = profile.try_query<ICoreWebView2StagingProfile4>();
if (profile2)
{
CHECK_FAILURE(profile2->Delete());
}
}
wil::com_ptr<ICoreWebView2Profile> profile;
CHECK_FAILURE(webView2->get_Profile(&profile));
CHECK_FAILURE(profile2->Delete());
}

EventRegistrationToken m_profileDeletedEventToken = {};
void AppWindow::AddProfileDeleted(ICoreWebView2* webView2)
{
CHECK_FAILURE(webView2->add_ProfileDeleted(
david-risney marked this conversation as resolved.
Show resolved Hide resolved
Microsoft::WRL::Callback<ICoreWebView2StagingProfileDeletedEventHandler>(
[this](ICoreWebView2Staging9* sender, IUnknown* args) {
CloseAppWindow();
return S_OK;
}).Get(), &m_profileDeletedEventToken));
}

void AppWindow::RemoveProfileDeleted(ICoreWebView2* webView2)
{
CHECK_FAILURE(webView2->remove_ProfileDeleted(m_profileDeletedEventToken));
}
```

Expand Down Expand Up @@ -253,10 +259,25 @@ public DeleteProfile(CoreWebView2Controller controller)
{
// Get the profile object.
CoreWebView2Profile profile = controller.CoreWebView2.Profile;

// Delete current profile.
profile.Delete();
}

private void AddProfileDeleted(object sender, object e)
{
webView.CoreWebView2.ProfileDeleted += CoreWebView2_ProfileDeleted;
}

private void RemoveProfileDeleted(object sender, object e)
{
webView.CoreWebView2.ProfileDeleted -= CoreWebView2_ProfileDeleted;
}

private void CoreWebView2_ProfileDeleted(object sender, object e)
{
Close();
}
```

# API Details
Expand Down Expand Up @@ -363,16 +384,36 @@ interface ICoreWebView2Profile2 : ICoreWebView2Profile {
[propget] HRESULT CookieManager([out, retval] ICoreWebView2CookieManager** cookieManager);
}

[uuid(1c1ae2cc-d5c2-ffe3-d3e7-7857035d23b7), object, pointer_default(unique)]
interface ICoreWebView2Profile3 : ICoreWebView2Profile2 {
/// All webviews on this profile will be closed, and the profile will be marked for deletion.
/// After the Delete() call completes, The render process of webviews on this profile will
/// asynchronously exit with the reason:`COREWEBVIEW2_PROCESS_FAILED_REASON_PROFILE_DELETED`.
/// See 'COREWEBVIEW2_PROCESS_FAILED_REASON::COREWEBVIEW2_PROCESS_FAILED_REASON_PROFILE_DELETED'
/// for more details. The profile directory on disk will be actually deleted when the browser
/// process exits. Webview2 creation will fail with the HRESULT is ERROR_INVALID_STATE(0x8007139FL)
/// if you create it with the same name as a profile that is being deleted.
HRESULT Delete();
[uuid(2765B8BD-7C57-4B76-B8AA-1EC940FE92CC), object, pointer_default(unique)]
interface ICoreWebView2StagingProfile4 : IUnknown {
/// After the API is called, the profile will be marked for deletion. The
/// local profile’s directory will be tried to delete at browser process
/// exit, if fail to delete, it will recursively try to delete at next
/// browser process start until successful.
/// The corresponding user's `ProfileDeleted` event handle function will
/// be triggered. After the function is triggered, continuing to use the
/// profile or its corresponding webviews is an undefined behavior.
david-risney marked this conversation as resolved.
Show resolved Hide resolved
/// For each WebView of the same profile, the WebView will be auto closed.
/// If the user has registered an event handler for ProfileDeleted event,
/// the event handle will be invoked before WebView is closed.
/// If create a new profile with the same name as the profile that has been
/// marked as deleted will be failure with the HRESULT:ERROR_INVALID_STATE
/// (0x8007139FL).
HRESULT Delete();
}

[uuid(cc39bea3-f6f8-471b-919f-fa253e2fff03), object, pointer_default(unique)]
interface ICoreWebView2Staging9 : IUnknown {
yunate marked this conversation as resolved.
Show resolved Hide resolved
/// The `ProfileDeleted` event is raised when its corresponding Profile's
/// Delete API is called. When this event has been raised, continue to use
yunate marked this conversation as resolved.
Show resolved Hide resolved
david-risney marked this conversation as resolved.
Show resolved Hide resolved
/// the profile or its corresponding webviews is an undefined behavior.
HRESULT add_ProfileDeleted(
david-risney marked this conversation as resolved.
Show resolved Hide resolved
[in] ICoreWebView2StagingProfileDeletedEventHandler* eventHandler,
[out] EventRegistrationToken* token);

/// Remove an event handler previously added with `add_ProfileDeleted`.
HRESULT remove_ProfileDeleted(
[in] EventRegistrationToken token);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition we should add a property where you can check if the CoreWebView2 is closed or not. This way end dev's asynchronous code that may be in progress when the profile is deleted can check if the CoreWebView2 has closed and take appropriate action.

/// Returns TRUE if the CoreWebView2 is closed. Once closed, CoreWebView2 
/// events will no longer be raised and methods will immediately return failure
/// unless otherwise noted in the API documentation. This property will continue
/// to work after the CoreWebView2 is closed.
[propget] HRESULT IsClosed([out] BOOL* value);

Copy link
Contributor Author

@yunate yunate Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think do not need this function. Because, close webview and Closed event handle function called are in a same therad and a same loop. So, if the Closed event handle function called, the user has known the webview has been closed, they can record a flag in this function; if before Closed event handle function called, the webview is always still alive.

```

Expand Down Expand Up @@ -414,6 +455,11 @@ namespace Microsoft.Web.WebView2.Core
{
// ...
CoreWebView2Profile Profile { get; };

[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Staging9")]
{
event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> ProfileDeleted;
}
}

runtimeclass CoreWebView2Profile
Expand All @@ -426,9 +472,9 @@ namespace Microsoft.Web.WebView2.Core

CoreWebView2CookieManager CookieManager { get; };

[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2Profile3")]
[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2StagingProfile4")]
yunate marked this conversation as resolved.
Show resolved Hide resolved
{
// ICoreWebView2Profile3 members
// ICoreWebView2StagingProfile4 members
void Delete();
}
}
Expand Down