mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-21 14:40:49 +01:00
Reduce locking in browser and frame implementations to avoid potential deadlocks (issue #824).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1265 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
b3cd2ae6a8
commit
468eee6560
@ -2129,7 +2129,9 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
|||||||
response_manager_.reset(new CefResponseManager);
|
response_manager_.reset(new CefResponseManager);
|
||||||
|
|
||||||
placeholder_frame_ =
|
placeholder_frame_ =
|
||||||
new CefFrameHostImpl(this, CefFrameHostImpl::kInvalidFrameId, true);
|
new CefFrameHostImpl(this, CefFrameHostImpl::kInvalidFrameId, true,
|
||||||
|
CefString(), CefString(),
|
||||||
|
CefFrameHostImpl::kInvalidFrameId);
|
||||||
|
|
||||||
// Make sure RenderViewCreated is called at least one time.
|
// Make sure RenderViewCreated is called at least one time.
|
||||||
RenderViewCreated(web_contents->GetRenderViewHost());
|
RenderViewCreated(web_contents->GetRenderViewHost());
|
||||||
@ -2150,30 +2152,30 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
|||||||
if (!frame_name.empty())
|
if (!frame_name.empty())
|
||||||
name = frame_name;
|
name = frame_name;
|
||||||
|
|
||||||
|
CefRefPtr<CefFrameHostImpl> frame;
|
||||||
|
bool frame_created = false;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
|
|
||||||
if (is_main_frame)
|
if (is_main_frame)
|
||||||
main_frame_id_ = frame_id;
|
main_frame_id_ = frame_id;
|
||||||
|
|
||||||
CefRefPtr<CefFrameHostImpl> frame;
|
|
||||||
|
|
||||||
// Check if a frame object already exists.
|
// Check if a frame object already exists.
|
||||||
FrameMap::const_iterator it = frames_.find(frame_id);
|
FrameMap::const_iterator it = frames_.find(frame_id);
|
||||||
if (it != frames_.end())
|
if (it != frames_.end())
|
||||||
frame = it->second.get();
|
frame = it->second.get();
|
||||||
|
|
||||||
if (!frame.get()) {
|
if (!frame.get()) {
|
||||||
// Create a new frame object.
|
frame = new CefFrameHostImpl(this, frame_id, is_main_frame, url, name,
|
||||||
frame = new CefFrameHostImpl(this, frame_id, is_main_frame);
|
parent_frame_id);
|
||||||
|
frame_created = true;
|
||||||
frames_.insert(std::make_pair(frame_id, frame));
|
frames_.insert(std::make_pair(frame_id, frame));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!url.empty())
|
if (!frame_created)
|
||||||
frame->SetURL(url);
|
frame->SetAttributes(url, name, parent_frame_id);
|
||||||
if (!name.empty())
|
|
||||||
frame->SetName(name);
|
|
||||||
if (parent_frame_id != CefFrameHostImpl::kUnspecifiedFrameId)
|
|
||||||
frame->SetParentId(parent_frame_id);
|
|
||||||
|
|
||||||
return frame.get();
|
return frame.get();
|
||||||
}
|
}
|
||||||
@ -2194,42 +2196,54 @@ void CefBrowserHostImpl::DetachFrame(int64 frame_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::DetachAllFrames() {
|
void CefBrowserHostImpl::DetachAllFrames() {
|
||||||
|
FrameMap frames;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
|
|
||||||
FrameMap::const_iterator it = frames_.begin();
|
frames = frames_;
|
||||||
for (; it != frames_.end(); ++it)
|
|
||||||
it->second->Detach();
|
|
||||||
|
|
||||||
frames_.clear();
|
frames_.clear();
|
||||||
|
|
||||||
if (main_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
if (main_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
||||||
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||||
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
||||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameMap::const_iterator it = frames.begin();
|
||||||
|
for (; it != frames.end(); ++it)
|
||||||
|
it->second->Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::SetFocusedFrame(int64 frame_id) {
|
void CefBrowserHostImpl::SetFocusedFrame(int64 frame_id) {
|
||||||
|
CefRefPtr<CefFrameHostImpl> unfocused_frame;
|
||||||
|
CefRefPtr<CefFrameHostImpl> focused_frame;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
|
|
||||||
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
|
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
|
||||||
// Unfocus the previously focused frame.
|
// Unfocus the previously focused frame.
|
||||||
FrameMap::const_iterator it = frames_.find(frame_id);
|
FrameMap::const_iterator it = frames_.find(frame_id);
|
||||||
if (it != frames_.end())
|
if (it != frames_.end())
|
||||||
it->second->SetFocused(false);
|
unfocused_frame = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_id != CefFrameHostImpl::kInvalidFrameId) {
|
if (frame_id != CefFrameHostImpl::kInvalidFrameId) {
|
||||||
// Focus the newly focused frame.
|
// Focus the newly focused frame.
|
||||||
FrameMap::iterator it = frames_.find(frame_id);
|
FrameMap::iterator it = frames_.find(frame_id);
|
||||||
if (it != frames_.end()) {
|
if (it != frames_.end())
|
||||||
it->second->SetFocused(true);
|
focused_frame = it->second;
|
||||||
focused_frame_id_ = frame_id;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No valid frame found.
|
focused_frame_id_ =
|
||||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
focused_frame ? frame_id : CefFrameHostImpl::kInvalidFrameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unfocused_frame)
|
||||||
|
unfocused_frame->SetFocused(false);
|
||||||
|
if (focused_frame)
|
||||||
|
focused_frame->SetFocused(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserHostImpl::OnAddressChange(CefRefPtr<CefFrame> frame,
|
void CefBrowserHostImpl::OnAddressChange(CefRefPtr<CefFrame> frame,
|
||||||
|
@ -49,12 +49,18 @@ class ViewTextHandler : public CefResponseManager::Handler {
|
|||||||
|
|
||||||
CefFrameHostImpl::CefFrameHostImpl(CefBrowserHostImpl* browser,
|
CefFrameHostImpl::CefFrameHostImpl(CefBrowserHostImpl* browser,
|
||||||
int64 frame_id,
|
int64 frame_id,
|
||||||
bool is_main_frame)
|
bool is_main_frame,
|
||||||
|
const CefString& url,
|
||||||
|
const CefString& name,
|
||||||
|
int64 parent_frame_id)
|
||||||
: frame_id_(frame_id),
|
: frame_id_(frame_id),
|
||||||
is_main_frame_(is_main_frame),
|
is_main_frame_(is_main_frame),
|
||||||
browser_(browser),
|
browser_(browser),
|
||||||
is_focused_(false),
|
is_focused_(false),
|
||||||
parent_frame_id_(kInvalidFrameId) {
|
url_(url),
|
||||||
|
name_(name),
|
||||||
|
parent_frame_id_(parent_frame_id == kUnspecifiedFrameId ?
|
||||||
|
kInvalidFrameId : parent_frame_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CefFrameHostImpl::~CefFrameHostImpl() {
|
CefFrameHostImpl::~CefFrameHostImpl() {
|
||||||
@ -66,88 +72,86 @@ bool CefFrameHostImpl::IsValid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Undo() {
|
void CefFrameHostImpl::Undo() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Undo", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Undo", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Redo() {
|
void CefFrameHostImpl::Redo() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Redo", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Redo", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Cut() {
|
void CefFrameHostImpl::Cut() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Cut", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Cut", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Copy() {
|
void CefFrameHostImpl::Copy() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Copy", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Copy", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Paste() {
|
void CefFrameHostImpl::Paste() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Paste", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Paste", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Delete() {
|
void CefFrameHostImpl::Delete() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("Delete", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "Delete", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::SelectAll() {
|
void CefFrameHostImpl::SelectAll() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("SelectAll", NULL);
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "SelectAll", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::ViewSource() {
|
void CefFrameHostImpl::ViewSource() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("GetSource", new ViewTextHandler(this));
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId)
|
|
||||||
browser_->SendCommand(frame_id_, "GetSource", new ViewTextHandler(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::GetSource(CefRefPtr<CefStringVisitor> visitor) {
|
void CefFrameHostImpl::GetSource(CefRefPtr<CefStringVisitor> visitor) {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("GetSource", new StringVisitHandler(visitor));
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId) {
|
|
||||||
browser_->SendCommand(frame_id_, "GetSource",
|
|
||||||
new StringVisitHandler(visitor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::GetText(CefRefPtr<CefStringVisitor> visitor) {
|
void CefFrameHostImpl::GetText(CefRefPtr<CefStringVisitor> visitor) {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
SendCommand("GetText", new StringVisitHandler(visitor));
|
||||||
if (browser_ && frame_id_ != kInvalidFrameId) {
|
|
||||||
browser_->SendCommand(frame_id_, "GetText",
|
|
||||||
new StringVisitHandler(visitor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::LoadRequest(CefRefPtr<CefRequest> request) {
|
void CefFrameHostImpl::LoadRequest(CefRefPtr<CefRequest> request) {
|
||||||
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
if (browser_)
|
browser = browser_;
|
||||||
browser_->LoadRequest((is_main_frame_ ? kMainFrameId : frame_id_), request);
|
frame_id = (is_main_frame_ ? kMainFrameId : frame_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser)
|
||||||
|
browser->LoadRequest(frame_id, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::LoadURL(const CefString& url) {
|
void CefFrameHostImpl::LoadURL(const CefString& url) {
|
||||||
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
if (browser_)
|
browser = browser_;
|
||||||
browser_->LoadURL((is_main_frame_ ? kMainFrameId : frame_id_), url);
|
frame_id = (is_main_frame_ ? kMainFrameId : frame_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser)
|
||||||
|
browser->LoadURL(frame_id, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::LoadString(const CefString& string,
|
void CefFrameHostImpl::LoadString(const CefString& string,
|
||||||
const CefString& url) {
|
const CefString& url) {
|
||||||
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
if (browser_) {
|
browser = browser_;
|
||||||
browser_->LoadString((is_main_frame_ ? kMainFrameId : frame_id_), string,
|
frame_id = (is_main_frame_ ? kMainFrameId : frame_id_);
|
||||||
url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (browser)
|
||||||
|
browser->LoadString(frame_id, string, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::ExecuteJavaScript(const CefString& jsCode,
|
void CefFrameHostImpl::ExecuteJavaScript(const CefString& jsCode,
|
||||||
@ -175,13 +179,19 @@ int64 CefFrameHostImpl::GetIdentifier() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefFrame> CefFrameHostImpl::GetParent() {
|
CefRefPtr<CefFrame> CefFrameHostImpl::GetParent() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 parent_frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
|
base::AutoLock lock_scope(state_lock_);
|
||||||
if (is_main_frame_ || parent_frame_id_ == kInvalidFrameId)
|
if (is_main_frame_ || parent_frame_id_ == kInvalidFrameId)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
browser = browser_;
|
||||||
|
parent_frame_id = parent_frame_id_;
|
||||||
|
}
|
||||||
|
|
||||||
if (browser_)
|
if (browser)
|
||||||
return browser_->GetFrame(parent_frame_id_);
|
return browser->GetFrame(parent_frame_id);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -201,19 +211,16 @@ void CefFrameHostImpl::SetFocused(bool focused) {
|
|||||||
is_focused_ = focused;
|
is_focused_ = focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::SetURL(const CefString& url) {
|
void CefFrameHostImpl::SetAttributes(const CefString& url,
|
||||||
|
const CefString& name,
|
||||||
|
int64 parent_frame_id) {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
|
if (!url.empty() && url != url_)
|
||||||
url_ = url;
|
url_ = url;
|
||||||
}
|
if (!name.empty() && name != name_)
|
||||||
|
|
||||||
void CefFrameHostImpl::SetName(const CefString& name) {
|
|
||||||
base::AutoLock lock_scope(state_lock_);
|
|
||||||
name_ = name;
|
name_ = name;
|
||||||
}
|
if (parent_frame_id != kUnspecifiedFrameId)
|
||||||
|
parent_frame_id_ = parent_frame_id;
|
||||||
void CefFrameHostImpl::SetParentId(int64 frame_id) {
|
|
||||||
base::AutoLock lock_scope(state_lock_);
|
|
||||||
parent_frame_id_ = frame_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefV8Context> CefFrameHostImpl::GetV8Context() {
|
CefRefPtr<CefV8Context> CefFrameHostImpl::GetV8Context() {
|
||||||
@ -234,14 +241,37 @@ void CefFrameHostImpl::SendJavaScript(
|
|||||||
if (startLine < 0)
|
if (startLine < 0)
|
||||||
startLine = 0;
|
startLine = 0;
|
||||||
|
|
||||||
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
if (browser_) {
|
browser = browser_;
|
||||||
browser_->SendCode((is_main_frame_ ? kMainFrameId : frame_id_), true,
|
frame_id = (is_main_frame_ ? kMainFrameId : frame_id_);
|
||||||
jsCode, scriptUrl, startLine, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (browser)
|
||||||
|
browser->SendCode(frame_id, true, jsCode, scriptUrl, startLine, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameHostImpl::Detach() {
|
void CefFrameHostImpl::Detach() {
|
||||||
base::AutoLock lock_scope(state_lock_);
|
base::AutoLock lock_scope(state_lock_);
|
||||||
browser_ = NULL;
|
browser_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefFrameHostImpl::SendCommand(
|
||||||
|
const std::string& command,
|
||||||
|
CefRefPtr<CefResponseManager::Handler> responseHandler) {
|
||||||
|
CefRefPtr<CefBrowserHostImpl> browser;
|
||||||
|
int64 frame_id;
|
||||||
|
|
||||||
|
{
|
||||||
|
base::AutoLock lock_scope(state_lock_);
|
||||||
|
browser = browser_;
|
||||||
|
// Commands can only be sent to known frame ids.
|
||||||
|
frame_id = frame_id_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser && frame_id != kInvalidFrameId)
|
||||||
|
browser->SendCommand(frame_id, command, responseHandler);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
|
#include "libcef/common/response_manager.h"
|
||||||
#include "base/synchronization/lock.h"
|
#include "base/synchronization/lock.h"
|
||||||
|
|
||||||
class CefBrowserHostImpl;
|
class CefBrowserHostImpl;
|
||||||
@ -19,7 +20,10 @@ class CefFrameHostImpl : public CefFrame {
|
|||||||
public:
|
public:
|
||||||
CefFrameHostImpl(CefBrowserHostImpl* browser,
|
CefFrameHostImpl(CefBrowserHostImpl* browser,
|
||||||
int64 frame_id,
|
int64 frame_id,
|
||||||
bool is_main_frame);
|
bool is_main_frame,
|
||||||
|
const CefString& url,
|
||||||
|
const CefString& name,
|
||||||
|
int64 parent_frame_id);
|
||||||
virtual ~CefFrameHostImpl();
|
virtual ~CefFrameHostImpl();
|
||||||
|
|
||||||
// CefFrame methods
|
// CefFrame methods
|
||||||
@ -52,9 +56,9 @@ class CefFrameHostImpl : public CefFrame {
|
|||||||
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;
|
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;
|
||||||
|
|
||||||
void SetFocused(bool focused);
|
void SetFocused(bool focused);
|
||||||
void SetURL(const CefString& url);
|
void SetAttributes(const CefString& url,
|
||||||
void SetName(const CefString& name);
|
const CefString& name,
|
||||||
void SetParentId(int64 frame_id);
|
int64 parent_frame_id);
|
||||||
|
|
||||||
// Avoids unnecessary string type conversions.
|
// Avoids unnecessary string type conversions.
|
||||||
void SendJavaScript(const std::string& jsCode,
|
void SendJavaScript(const std::string& jsCode,
|
||||||
@ -71,6 +75,9 @@ class CefFrameHostImpl : public CefFrame {
|
|||||||
static const int64 kInvalidFrameId = -4;
|
static const int64 kInvalidFrameId = -4;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void SendCommand(const std::string& command,
|
||||||
|
CefRefPtr<CefResponseManager::Handler> responseHandler);
|
||||||
|
|
||||||
int64 frame_id_;
|
int64 frame_id_;
|
||||||
bool is_main_frame_;
|
bool is_main_frame_;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user