Skip to content

Commit 55e2a08

Browse files
committed
[WebDriver][BiDi] Implement the browser module
https://bugs.webkit.org/show_bug.cgi?id=281941 Reviewed by BJ Burg. Basic implementation of UserContext management methods. Each user context is a pair of a WebsiteDataStore and a WebProcessPool. * Source/WebKit/Sources.txt: * Source/WebKit/SourcesGTK.txt: * Source/WebKit/UIProcess/Automation/BidiBrowserAgent.cpp: Added. Browser module logic is extracted into its own module for better readability and encapsulation of the implementation details. The agent maintains the list of all UserContexts, in the future they will be used to create pages (aka BrowsingContexts). (WebKit::BidiBrowserAgent::BidiBrowserAgent): (WebKit::BidiBrowserAgent::close): (WebKit::BidiBrowserAgent::createUserContext): (WebKit::BidiBrowserAgent::getUserContexts): (WebKit::BidiBrowserAgent::removeUserContext): (WebKit::BidiBrowserAgent::platformCreateUserContext): * Source/WebKit/UIProcess/Automation/BidiBrowserAgent.h: Added. An actual implementation of the user context. It is mostly WebsiteDataStore that provides user data isolation. After decoupling of the network process from WebProcessPool in https://commits.webkit.org/229885@main, we might not need a separate process pool per user context for cookie store isolatio. But we still need it for e.g. geo location overrides using WebGeolocationManagerProxy which is a supplement to WebProcessPool. * Source/WebKit/UIProcess/Automation/BidiUserContext.cpp: Added. (WebKit::BidiUserContext::BidiUserContext): * Source/WebKit/UIProcess/Automation/BidiUserContext.h: Added. * Source/WebKit/UIProcess/Automation/WebDriverBidiProcessor.cpp: (WebKit::WebDriverBidiProcessor::WebDriverBidiProcessor): * Source/WebKit/UIProcess/Automation/WebDriverBidiProcessor.h: * Source/WebKit/UIProcess/Automation/glib/BidiBrowserAgentGlib.cpp: Added. (WebKit::BidiBrowserAgent::platformCreateUserContext): * Source/WebKit/UIProcess/Automation/protocol/BidiBrowser.json: * Source/WebKit/WebKit.xcodeproj/project.pbxproj: Canonical link: https://commits.webkit.org/293942@main
1 parent f4c57b8 commit 55e2a08

File tree

11 files changed

+463
-19
lines changed

11 files changed

+463
-19
lines changed

Source/WebKit/Sources.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,8 @@ UIProcess/Authentication/WebCredential.cpp
560560
UIProcess/Authentication/WebProtectionSpace.cpp
561561

562562
// FIXME(206266): AutomationProtocolObjects.h's "namespace Protocol" conflicts with objc/runtime.h's "typedef struct objc_object Protocol"
563+
UIProcess/Automation/BidiBrowserAgent.cpp @no-unify
564+
UIProcess/Automation/BidiUserContext.cpp @no-unify
563565
UIProcess/Automation/SimulatedInputDispatcher.cpp @no-unify
564566
UIProcess/Automation/WebAutomationSession.cpp @no-unify
565567
UIProcess/Automation/WebDriverBidiProcessor.cpp @no-unify

Source/WebKit/SourcesGTK.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ UIProcess/API/gtk/WebKitWebViewGtk4.cpp @no-unify
216216
UIProcess/API/soup/HTTPCookieStoreSoup.cpp
217217

218218
UIProcess/Automation/cairo/WebAutomationSessionCairo.cpp
219+
UIProcess/Automation/glib/BidiBrowserAgentGlib.cpp @no-unify
219220
UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp @no-unify
220221

221222
UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (C) 2025 Microsoft Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#include "config.h"
27+
#include "BidiBrowserAgent.h"
28+
29+
#if ENABLE(WEBDRIVER_BIDI)
30+
31+
#include "AutomationProtocolObjects.h"
32+
#include "BidiUserContext.h"
33+
#include "WebAutomationSession.h"
34+
#include "WebAutomationSessionMacros.h"
35+
#include "WebDriverBidiProtocolObjects.h"
36+
#include "WebProcessPool.h"
37+
#include "WebsiteDataStore.h"
38+
#include <pal/SessionID.h>
39+
#include <wtf/NeverDestroyed.h>
40+
#include <wtf/text/StringBuilder.h>
41+
42+
namespace WebKit {
43+
44+
using namespace Inspector;
45+
using UserContextInfo = Inspector::Protocol::BidiBrowser::UserContextInfo;
46+
47+
namespace {
48+
49+
String toUserContextIDProtocolString(const PAL::SessionID& sessionID)
50+
{
51+
StringBuilder builder;
52+
builder.append(hex(sessionID.toUInt64(), 16));
53+
return builder.toString();
54+
}
55+
56+
const String& defaultUserContextID()
57+
{
58+
static NeverDestroyed<const String> contextID(MAKE_STATIC_STRING_IMPL("default"));
59+
return contextID;
60+
}
61+
62+
} // namespace
63+
64+
WTF_MAKE_TZONE_ALLOCATED_IMPL(BidiBrowserAgent);
65+
66+
BidiBrowserAgent::BidiBrowserAgent(WebAutomationSession& session, BackendDispatcher& backendDispatcher)
67+
: m_session(session)
68+
, m_browserDomainDispatcher(BidiBrowserBackendDispatcher::create(backendDispatcher, this))
69+
{
70+
}
71+
72+
BidiBrowserAgent::~BidiBrowserAgent() = default;
73+
74+
// MARK: Inspector::BidiBrowserDispatcherHandler methods.
75+
76+
Inspector::CommandResult<void> BidiBrowserAgent::close()
77+
{
78+
RefPtr session = m_session.get();
79+
SYNC_FAIL_WITH_PREDEFINED_ERROR_IF(!session, InternalError);
80+
81+
session->terminate();
82+
83+
return { };
84+
}
85+
86+
Inspector::CommandResult<String> BidiBrowserAgent::createUserContext()
87+
{
88+
String error;
89+
auto userContext = platformCreateUserContext(error);
90+
SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS_IF(!userContext, InternalError, error);
91+
92+
PAL::SessionID sessionID = userContext->dataStore().sessionID();
93+
String userContextID = toUserContextIDProtocolString(sessionID);
94+
m_userContexts.set(userContextID, WTFMove(userContext));
95+
96+
return userContextID;
97+
}
98+
99+
Inspector::CommandResult<Ref<JSON::ArrayOf<UserContextInfo>>> BidiBrowserAgent::getUserContexts()
100+
{
101+
auto userContexts = JSON::ArrayOf<UserContextInfo>::create();
102+
userContexts->addItem(UserContextInfo::create()
103+
.setUserContext(defaultUserContextID())
104+
.release());
105+
for (const auto& pair : m_userContexts) {
106+
userContexts->addItem(UserContextInfo::create()
107+
.setUserContext(pair.key)
108+
.release());
109+
}
110+
return userContexts;
111+
}
112+
113+
Inspector::CommandResult<void> BidiBrowserAgent::removeUserContext(const String& userContext)
114+
{
115+
// https://www.w3.org/TR/webdriver-bidi/#command-browser-removeUserContext step 2.
116+
SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS_IF(userContext == defaultUserContextID(), InvalidParameter, "Cannot delete default user context."_s);
117+
118+
auto it = m_userContexts.find(userContext);
119+
// https://www.w3.org/TR/webdriver-bidi/#command-browser-removeUserContext step 4.
120+
SYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS_IF(it == m_userContexts.end(), InvalidParameter, "no such user context"_s);
121+
122+
// TODO: track and close all pages that belong to this user context.
123+
m_userContexts.remove(it);
124+
return { };
125+
}
126+
127+
#if !PLATFORM(GTK)
128+
std::unique_ptr<BidiUserContext> BidiBrowserAgent::platformCreateUserContext(String& error)
129+
{
130+
error = "User context creation is not implemented for this platform yet."_s;
131+
return nullptr;
132+
}
133+
#endif
134+
135+
} // namespace WebKit
136+
137+
#endif // ENABLE(WEBDRIVER_BIDI)
138+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) 2025 Microsoft Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#if ENABLE(WEBDRIVER_BIDI)
29+
30+
#include "WebDriverBidiBackendDispatchers.h"
31+
#include <JavaScriptCore/InspectorBackendDispatcher.h>
32+
#include <wtf/FastMalloc.h>
33+
#include <wtf/Forward.h>
34+
#include <wtf/WeakPtr.h>
35+
36+
#if PLATFORM(GTK)
37+
#include <wtf/glib/GRefPtr.h>
38+
typedef struct _WebKitWebContext WebKitWebContext;
39+
#endif
40+
41+
namespace WebKit {
42+
43+
class BidiUserContext;
44+
class WebAutomationSession;
45+
class WebProcessPool;
46+
class WebsiteDataStore;
47+
48+
class BidiBrowserAgent final : public Inspector::BidiBrowserBackendDispatcherHandler {
49+
WTF_MAKE_TZONE_ALLOCATED(BidiBrowserAgent);
50+
public:
51+
BidiBrowserAgent(WebAutomationSession&, Inspector::BackendDispatcher&);
52+
~BidiBrowserAgent() override;
53+
54+
// Inspector::BidiBrowserBackendDispatcherHandler methods.
55+
Inspector::CommandResult<void> close() override;
56+
Inspector::CommandResult<String> createUserContext() override;
57+
Inspector::CommandResult<Ref<JSON::ArrayOf<Inspector::Protocol::BidiBrowser::UserContextInfo>>> getUserContexts() override;
58+
Inspector::CommandResult<void> removeUserContext(const String& userContext) override;
59+
60+
private:
61+
std::unique_ptr<BidiUserContext> platformCreateUserContext(String& error);
62+
63+
WeakPtr<WebAutomationSession> m_session;
64+
Ref<Inspector::BidiBrowserBackendDispatcher> m_browserDomainDispatcher;
65+
HashMap<String, std::unique_ptr<BidiUserContext>> m_userContexts;
66+
};
67+
68+
} // namespace WebKit
69+
70+
#endif // ENABLE(WEBDRIVER_BIDI)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) 2025 Microsoft Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#include "config.h"
27+
#include "BidiUserContext.h"
28+
29+
#if ENABLE(WEBDRIVER_BIDI)
30+
31+
#include "WebProcessPool.h"
32+
#include "WebsiteDataStore.h"
33+
34+
namespace WebKit {
35+
36+
#if PLATFORM(GTK)
37+
BidiUserContext::BidiUserContext(WebsiteDataStore& dataStore, WebProcessPool& processPool, GRefPtr<WebKitWebContext>&& context)
38+
: m_dataStore(dataStore)
39+
, m_processPool(processPool)
40+
, m_context(WTFMove(context))
41+
{
42+
};
43+
#else
44+
BidiUserContext::BidiUserContext(WebsiteDataStore& dataStore, WebProcessPool& processPool)
45+
: m_dataStore(dataStore)
46+
, m_processPool(processPool)
47+
{
48+
};
49+
#endif // PLATFORM(GTK)
50+
51+
BidiUserContext::~BidiUserContext() = default;
52+
53+
} // namespace WebKit
54+
55+
#endif // ENABLE(WEBDRIVER_BIDI)
56+
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) 2025 Microsoft Corporation. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#if ENABLE(WEBDRIVER_BIDI)
29+
30+
#include <wtf/FastMalloc.h>
31+
#include <wtf/Forward.h>
32+
#include <wtf/Noncopyable.h>
33+
#include <wtf/Ref.h>
34+
35+
#if PLATFORM(GTK)
36+
#include <wtf/glib/GRefPtr.h>
37+
typedef struct _WebKitWebContext WebKitWebContext;
38+
#endif
39+
40+
namespace WebKit {
41+
42+
class WebProcessPool;
43+
class WebsiteDataStore;
44+
45+
class BidiUserContext {
46+
WTF_MAKE_NONCOPYABLE(BidiUserContext);
47+
WTF_MAKE_FAST_ALLOCATED;
48+
public:
49+
#if PLATFORM(GTK)
50+
BidiUserContext(WebsiteDataStore&, WebProcessPool&, GRefPtr<WebKitWebContext>&&);
51+
#else
52+
BidiUserContext(WebsiteDataStore&, WebProcessPool&);
53+
#endif
54+
~BidiUserContext();
55+
56+
WebsiteDataStore& dataStore() const { return m_dataStore.get(); }
57+
WebProcessPool& processPool() const { return m_processPool.get(); }
58+
59+
private:
60+
61+
Ref<WebsiteDataStore> m_dataStore;
62+
Ref<WebProcessPool> m_processPool;
63+
#if PLATFORM(GTK)
64+
GRefPtr<WebKitWebContext> m_context;
65+
#endif
66+
};
67+
68+
} // namespace WebKit
69+
70+
#endif // ENABLE(WEBDRIVER_BIDI)

Source/WebKit/UIProcess/Automation/WebDriverBidiProcessor.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
// For AutomationError codes.
3232
#include "AutomationProtocolObjects.h"
33+
#include "BidiBrowserAgent.h"
3334
#include "Logging.h"
3435
#include "PageLoadState.h"
3536
#include "WebAutomationSession.h"
@@ -57,9 +58,9 @@ WebDriverBidiProcessor::WebDriverBidiProcessor(WebAutomationSession& session)
5758
: m_session(session)
5859
, m_frontendRouter(FrontendRouter::create())
5960
, m_backendDispatcher(BackendDispatcher::create(m_frontendRouter.copyRef()))
60-
, m_browserDomainDispatcher(BidiBrowserBackendDispatcher::create(m_backendDispatcher, this))
6161
, m_browsingContextDomainDispatcher(BidiBrowsingContextBackendDispatcher::create(m_backendDispatcher, this))
6262
, m_scriptDomainDispatcher(BidiScriptBackendDispatcher::create(m_backendDispatcher, this))
63+
, m_browserAgent(makeUnique<BidiBrowserAgent>(session, m_backendDispatcher))
6364
, m_logDomainNotifier(makeUnique<BidiLogFrontendDispatcher>(m_frontendRouter))
6465
{
6566
protectedFrontendRouter()->connectFrontend(*this);
@@ -277,18 +278,6 @@ void WebDriverBidiProcessor::reload(const BrowsingContext& browsingContext, std:
277278
});
278279
}
279280

280-
// MARK: Inspector::BidiBrowserDispatcherHandler methods.
281-
282-
Inspector::Protocol::ErrorStringOr<void> WebDriverBidiProcessor::close()
283-
{
284-
RefPtr session = m_session.get();
285-
SYNC_FAIL_WITH_PREDEFINED_ERROR_IF(!session, InternalError);
286-
287-
session->terminate();
288-
289-
return { };
290-
}
291-
292281
// MARK: Log domain.
293282

294283
void WebDriverBidiProcessor::logEntryAdded(const String& level, const String& source, const String& message, double timestamp, const String& type, const String& method)

0 commit comments

Comments
 (0)