Commit 35643b53 authored by Johannes Henkel's avatar Johannes Henkel Committed by Commit Bot

Flatten DevToolsClientImpl hierarchy in chromedriver.

It turns out we may not need to have a deeply nested hierarchy,
so this PR attempts to flatten this hierarchy as we're
creating child session instances.

This avoids a crash that would happen for grandchildren when
they're trying to use their parent's socket to send messages.

BUG=chromedriver:3165

Change-Id: I4fb22a7aeaf67321a062deb831ebc68ace904b7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1851227
Commit-Queue: Johannes Henkel <johannes@chromium.org>
Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704519}
parent 74a3e615
...@@ -79,8 +79,8 @@ DevToolsClientImpl::DevToolsClientImpl(const SyncWebSocketFactory& factory, ...@@ -79,8 +79,8 @@ DevToolsClientImpl::DevToolsClientImpl(const SyncWebSocketFactory& factory,
const std::string& id) const std::string& id)
: socket_(factory.Run()), : socket_(factory.Run()),
url_(url), url_(url),
parent_(nullptr),
owner_(nullptr), owner_(nullptr),
parent_(nullptr),
crashed_(false), crashed_(false),
detached_(false), detached_(false),
id_(id), id_(id),
...@@ -99,8 +99,8 @@ DevToolsClientImpl::DevToolsClientImpl( ...@@ -99,8 +99,8 @@ DevToolsClientImpl::DevToolsClientImpl(
const FrontendCloserFunc& frontend_closer_func) const FrontendCloserFunc& frontend_closer_func)
: socket_(factory.Run()), : socket_(factory.Run()),
url_(url), url_(url),
parent_(nullptr),
owner_(nullptr), owner_(nullptr),
parent_(nullptr),
crashed_(false), crashed_(false),
detached_(false), detached_(false),
id_(id), id_(id),
...@@ -114,9 +114,9 @@ DevToolsClientImpl::DevToolsClientImpl( ...@@ -114,9 +114,9 @@ DevToolsClientImpl::DevToolsClientImpl(
DevToolsClientImpl::DevToolsClientImpl(DevToolsClientImpl* parent, DevToolsClientImpl::DevToolsClientImpl(DevToolsClientImpl* parent,
const std::string& session_id) const std::string& session_id)
: parent_(parent), : owner_(nullptr),
owner_(nullptr),
session_id_(session_id), session_id_(session_id),
parent_(parent),
crashed_(false), crashed_(false),
detached_(false), detached_(false),
id_(session_id), id_(session_id),
...@@ -136,8 +136,8 @@ DevToolsClientImpl::DevToolsClientImpl( ...@@ -136,8 +136,8 @@ DevToolsClientImpl::DevToolsClientImpl(
const ParserFunc& parser_func) const ParserFunc& parser_func)
: socket_(factory.Run()), : socket_(factory.Run()),
url_(url), url_(url),
parent_(nullptr),
owner_(nullptr), owner_(nullptr),
parent_(nullptr),
crashed_(false), crashed_(false),
detached_(false), detached_(false),
id_(id), id_(id),
...@@ -297,6 +297,10 @@ DevToolsClientImpl::ResponseInfo::ResponseInfo(const std::string& method) ...@@ -297,6 +297,10 @@ DevToolsClientImpl::ResponseInfo::ResponseInfo(const std::string& method)
DevToolsClientImpl::ResponseInfo::~ResponseInfo() {} DevToolsClientImpl::ResponseInfo::~ResponseInfo() {}
DevToolsClientImpl* DevToolsClientImpl::GetRootClient() {
return parent_ ? parent_ : this;
}
Status DevToolsClientImpl::SendCommandInternal( Status DevToolsClientImpl::SendCommandInternal(
const std::string& method, const std::string& method,
const base::DictionaryValue& params, const base::DictionaryValue& params,
...@@ -324,8 +328,7 @@ Status DevToolsClientImpl::SendCommandInternal( ...@@ -324,8 +328,7 @@ Status DevToolsClientImpl::SendCommandInternal(
VLOG(1) << "DevTools WebSocket Command: " << method << " (id=" << command_id VLOG(1) << "DevTools WebSocket Command: " << method << " (id=" << command_id
<< ") " << id_ << " " << FormatValueForDisplay(params); << ") " << id_ << " " << FormatValueForDisplay(params);
} }
SyncWebSocket* socket = SyncWebSocket* socket = GetRootClient()->socket_.get();
(parent_ != nullptr) ? parent_->socket_.get() : socket_.get();
if (!socket->Send(message)) { if (!socket->Send(message)) {
return Status(kDisconnected, "unable to send message to renderer"); return Status(kDisconnected, "unable to send message to renderer");
} }
......
...@@ -120,6 +120,7 @@ class DevToolsClientImpl : public DevToolsClient { ...@@ -120,6 +120,7 @@ class DevToolsClientImpl : public DevToolsClient {
Status HandleReceivedEvents() override; Status HandleReceivedEvents() override;
void SetDetached() override; void SetDetached() override;
void SetOwner(WebViewImpl* owner) override; void SetOwner(WebViewImpl* owner) override;
DevToolsClientImpl* GetRootClient();
private: private:
enum ResponseState { enum ResponseState {
...@@ -164,10 +165,13 @@ class DevToolsClientImpl : public DevToolsClient { ...@@ -164,10 +165,13 @@ class DevToolsClientImpl : public DevToolsClient {
std::unique_ptr<SyncWebSocket> socket_; std::unique_ptr<SyncWebSocket> socket_;
GURL url_; GURL url_;
DevToolsClientImpl* parent_;
// WebViewImpl that owns this instance; nullptr for browser-wide DevTools. // WebViewImpl that owns this instance; nullptr for browser-wide DevTools.
WebViewImpl* owner_; WebViewImpl* owner_;
const std::string session_id_; const std::string session_id_;
// parent_ / children_: it's a flat hierarchy - nesting is at most one level
// deep. children_ holds child sessions - identified by their session id -
// which send/receive messages via the socket_ of their parent.
DevToolsClientImpl* parent_;
std::map<std::string, DevToolsClientImpl*> children_; std::map<std::string, DevToolsClientImpl*> children_;
bool crashed_; bool crashed_;
bool detached_; bool detached_;
......
...@@ -195,10 +195,14 @@ WebViewImpl::~WebViewImpl() {} ...@@ -195,10 +195,14 @@ WebViewImpl::~WebViewImpl() {}
WebViewImpl* WebViewImpl::CreateChild(const std::string& session_id, WebViewImpl* WebViewImpl::CreateChild(const std::string& session_id,
const std::string& target_id) const { const std::string& target_id) const {
DevToolsClientImpl* parent_client = // While there may be a deep hierarchy of WebViewImpl instances, the
static_cast<DevToolsClientImpl*>(client_.get()); // hierarchy for DevToolsClientImpl is flat - there's a root which
// sends/receives over the socket, and all child sessions are considered
// its children (one level deep at most).
DevToolsClientImpl* root_client =
static_cast<DevToolsClientImpl*>(client_.get())->GetRootClient();
std::unique_ptr<DevToolsClient> child_client( std::unique_ptr<DevToolsClient> child_client(
std::make_unique<DevToolsClientImpl>(parent_client, session_id)); std::make_unique<DevToolsClientImpl>(root_client, session_id));
WebViewImpl* child = new WebViewImpl(target_id, w3c_compliant_, browser_info_, WebViewImpl* child = new WebViewImpl(target_id, w3c_compliant_, browser_info_,
std::move(child_client), nullptr, std::move(child_client), nullptr,
navigation_tracker_->IsNonBlocking() navigation_tracker_->IsNonBlocking()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment