在前面webview创建过程分析(三)中我们了解了AwContents的初始化过程,其中还有一个点也就是native的初始化部分没有将,今天主要来看下AwContents的native是如何实现的。
private static native long nativeInit(AwBrowserContext browserContext);
AwContents会调用nativeInit方法来进行native层的初始化工作,而AwContents对应的jni层代码在AwContents_jni.h文件中。natveInit对应的jni代码为
JNI_GENERATOR_EXPORT jlong Java_org_chromium_android_1webview_AwContents_nativeInit(
JNIEnv* env,
jclass jcaller,
jobject browserContext) {
return JNI_AwContents_Init(env, base::android::JavaParamRef<jobject>(env, browserContext));
}
我们来看下JNI_AwContents_Init的实现,实现代码在aw_contents.cc中
static jlong JNI_AwContents_Init(JNIEnv* env,
const JavaParamRef<jobject>& browser_context) {
// TODO(joth): Use |browser_context| to get the native BrowserContext, rather
// than hard-code the default instance lookup here.
std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
// Return an 'uninitialized' instance; most work is deferred until the
// subsequent SetJavaPeers() call.
return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
}
这里最主要的逻辑就是创建了WebContents对象和AwContents对象,接下来我们看下这两个对象创建过程中都涉及到哪些逻辑
WebContents创建过程
1.构建WebContents::CreateParams参数
WebContents::CreateParams::CreateParams(BrowserContext* context)
: CreateParams(context, nullptr) {}
WebContents::CreateParams::CreateParams(BrowserContext* context,
scoped_refptr<SiteInstance> site)
: browser_context(context),
site_instance(std::move(site)),
opener_render_process_id(content::ChildProcessHost::kInvalidUniqueID),
opener_render_frame_id(MSG_ROUTING_NONE),
opener_suppressed(false),
created_with_opener(false),
routing_id(MSG_ROUTING_NONE),
main_frame_routing_id(MSG_ROUTING_NONE),
main_frame_widget_routing_id(MSG_ROUTING_NONE),
initially_hidden(false),
guest_delegate(nullptr),
context(nullptr),
renderer_initiated_creation(false),
desired_renderer_state(kOkayToHaveRendererProcess),
starting_sandbox_flags(blink::WebSandboxFlags::kNone) {}
这个参数的创建过程主要是进行一些变量的初始化。
2.WebContents::Create方法分析
std::unique_ptr<WebContents> WebContents::Create(
const WebContents::CreateParams& params) {
return WebContentsImpl::CreateWithOpener(params, FindOpenerRFH(params));
}
这里主要是调用WebContentsImpl的CreateWithOpener方法
std::unique_ptr<WebContentsImpl> WebContentsImpl::CreateWithOpener(
const WebContents::CreateParams& params,
RenderFrameHostImpl* opener_rfh) {
TRACE_EVENT0("browser", "WebContentsImpl::CreateWithOpener");
FrameTreeNode* opener = nullptr;
if (opener_rfh)
opener = opener_rfh->frame_tree_node();
std::unique_ptr<WebContentsImpl> new_contents(
new WebContentsImpl(params.browser_context));
........
new_contents->Init(params);
return new_contents;
从这里可以知道前面需要的WebContents对象实际上是WebContentsImpl
这里主要分为两步:
1.创建WebContentsImpl
2.调用WebContentsImpl的Init方法
创建WebContentsImpl
WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
: delegate_(nullptr),
controller_(this, browser_context),
render_view_host_delegate_view_(nullptr),
created_with_opener_(false),
node_(this),
frame_tree_(new NavigatorImpl(&controller_, this),
this,
this,
this,
this),
......
在WebContentsImpl的创建中主要会创建一个controller_和frame_tree_
cotroller_的创建过程
NavigationControllerImpl::NavigationControllerImpl(
NavigationControllerDelegate* delegate,
BrowserContext* browser_context)
: browser_context_(browser_context),
pending_entry_(nullptr),
failed_pending_entry_id_(0),
last_committed_entry_index_(-1),
pending_entry_index_(-1),
transient_entry_index_(-1),
delegate_(delegate),
ssl_manager_(this),
needs_reload_(false),
is_initial_navigation_(true),
in_navigate_to_pending_entry_(false),
pending_reload_(ReloadType::NONE),
get_timestamp_callback_(base::Bind(&base::Time::Now)),
last_committed_reload_type_(ReloadType::NONE) {
DCHECK(browser_context_);
}
这个controller_是NavigationControllerImpl的一个实例,NavigationControllerImpl是继承NavigationController,它包含了LoadUrl,CanGoBack等方法,这个类的作用在我们研究webview加载页面的过程中会又更深入的研究。在这里只是创建了一个NavigationControllerImpl对象,为其中的browser_context_和delegate_进行赋值,这里的delegate_就是WebContentsImpl对象
frame_tree_的创建过程
在创建frame_tree_之前会先构建NavigatorImpl对象。
NavigatorImpl::NavigatorImpl(NavigationControllerImpl* navigation_controller,
NavigatorDelegate* delegate)
: controller_(navigation_controller), delegate_(delegate) {}
NavigatorImpl主要把之前创建的NavigationControllerImpl对象放到自己的controller_中和之前的WebContentsImpl(也就是这里的NavigatorDelegate)对象放到delegate_中,以便后续使用。接下来看下frame_tree_的实现
FrameTree::FrameTree(Navigator* navigator,
RenderFrameHostDelegate* render_frame_delegate,
RenderViewHostDelegate* render_view_delegate,
RenderWidgetHostDelegate* render_widget_delegate,
RenderFrameHostManager::Delegate* manager_delegate)
: render_frame_delegate_(render_frame_delegate),
render_view_delegate_(render_view_delegate),
render_widget_delegate_(render_widget_delegate),
manager_delegate_(manager_delegate),
root_(new FrameTreeNode(this,
navigator,
nullptr,
// The top-level frame must always be in a
// document scope.
blink::WebTreeScopeType::kDocument,
std::string(),
std::string(),
false,
base::UnguessableToken::Create(),
FrameOwnerProperties(),
blink::FrameOwnerElementType::kNone)),
focused_frame_tree_node_id_(FrameTreeNode::kFrameTreeNodeInvalidId),
load_progress_(0.0) {}
这里先将FrameTree需要的一些变量进行赋值,注意这里的RenderFrameHostDelegate,RenderViewHostDelegate,RenderWidgetHostDelegate和RenderFrameHostManager::Delegate对像都是同一个WebContentsImpl对象,为这些变量赋完值之后会创建FrameTree的根节点root_,节点类型是FrameTreeNode,下面看下FrameTreeNode的实现
FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
Navigator* navigator,
FrameTreeNode* parent,
blink::WebTreeScopeType scope,
const std::string& name,
const std::string& unique_name,
bool is_created_by_script,
const base::UnguessableToken& devtools_frame_token,
const FrameOwnerProperties& frame_owner_properties,
blink::FrameOwnerElementType owner_type)
: frame_tree_(frame_tree),
navigator_(navigator),
render_manager_(this, frame_tree->manager_delegate()),
frame_tree_node_id_(next_frame_tree_node_id_++),
parent_(parent),
depth_(parent ? parent->depth_ + 1 : 0u),
opener_(nullptr),
original_opener_(nullptr),
has_committed_real_load_(false),
is_collapsed_(false),
......
FrameTreeNode的创建过程主要也是为一些变量的赋值,比如frame_tree_,navigator等,同时会为这个节点创建一个manager,也就是这里的render_manager_,他是一个RenderFrameHostManager对象
RenderFrameHostManager::RenderFrameHostManager(FrameTreeNode* frame_tree_node,
Delegate* delegate)
: frame_tree_node_(frame_tree_node),
delegate_(delegate),
weak_factory_(this) {
DCHECK(frame_tree_node_);
}
RenderFrameHostManager对象在初始化时会将对应的FrameTree节点和Delegate对象保存下来,这里的delegate还是之前创建的WebContentsImpl对象。这里FrameTree中每个节点都会有一个render_manager_。
这样整个FrameTree就创建完了,里面包含了一个跟节点root_
调用WebContentsImpl的Init方法
FrameTree创建完成之后我们看下WebContentsImpl的Init方法的实现
void WebContentsImpl::Init(const WebContents::CreateParams& params) {
// This is set before initializing the render manager since
// RenderFrameHostManager::Init calls back into us via its delegate to ask if
// it should be hidden.
visibility_ =
params.initially_hidden ? Visibility::HIDDEN : Visibility::VISIBLE;
if (!params.last_active_time.is_null())
last_active_time_ = params.last_active_time;
scoped_refptr<SiteInstance> site_instance = params.site_instance;
if (!site_instance)
//1.创建SiteInstance
site_instance = SiteInstance::Create(params.browser_context);
if (params.desired_renderer_state == CreateParams::kNoRendererProcess) {
static_cast<SiteInstanceImpl*>(site_instance.get())
->PreventAssociationWithSpareProcess();
}
//2.创建各个id
int32_t view_routing_id = params.routing_id;
int32_t main_frame_widget_routing_id = params.main_frame_widget_routing_id;
if (main_frame_widget_routing_id == MSG_ROUTING_NONE) {
view_routing_id = site_instance->GetProcess()->GetNextRoutingID();
main_frame_widget_routing_id =
site_instance->GetProcess()->GetNextRoutingID();
}
DCHECK_NE(view_routing_id, main_frame_widget_routing_id);
//Init
GetRenderManager()->Init(
site_instance.get(), view_routing_id, params.main_frame_routing_id,
main_frame_widget_routing_id, params.renderer_initiated_creation);
// blink::FrameTree::setName always keeps |unique_name| empty in case of a
// main frame - let's do the same thing here.
std::string unique_name;
frame_tree_.root()->SetFrameName(params.main_frame_name, unique_name);
WebContentsViewDelegate* delegate =
GetContentClient()->browser()->GetWebContentsViewDelegate(this);
if (GuestMode::IsCrossProcessFrameGuest(this)) {
view_.reset(new WebContentsViewChildFrame(
this, delegate, &render_view_host_delegate_view_));
} else {
//4.创建WebContentsView
view_.reset(CreateWebContentsView(this, delegate,
&render_view_host_delegate_view_));
if (browser_plugin_guest_) {
view_ = std::make_unique<WebContentsViewGuest>(
this, browser_plugin_guest_.get(), std::move(view_),
&render_view_host_delegate_view_);
}
}
CHECK(render_view_host_delegate_view_);
CHECK(view_.get());
gfx::Size initial_size = params.initial_size;
view_->CreateView(initial_size, params.context);
#if BUILDFLAG(ENABLE_PLUGINS)
plugin_content_origin_whitelist_.reset(
new PluginContentOriginWhitelist(this));
#endif
registrar_.Add(this,
NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
NotificationService::AllBrowserContextsAndSources());
screen_orientation_provider_.reset(new ScreenOrientationProvider(this));
manifest_manager_host_.reset(new ManifestManagerHost(this));
#if defined(OS_ANDROID)
date_time_chooser_.reset(new DateTimeChooserAndroid());
#endif
// BrowserPluginGuest::Init needs to be called after this WebContents has
// a RenderWidgetHostViewGuest. That is, |view_->CreateView| above.
if (browser_plugin_guest_)
browser_plugin_guest_->Init();
for (size_t i = 0; i < g_created_callbacks.Get().size(); i++)
g_created_callbacks.Get().at(i).Run(this);
// If the WebContents creation was renderer-initiated, it means that the
// corresponding RenderView and main RenderFrame have already been created.
// Ensure observers are notified about this.
if (params.renderer_initiated_creation) {
GetRenderViewHost()->GetWidget()->set_renderer_initialized(true);
GetRenderViewHost()->DispatchRenderViewCreated();
GetRenderManager()->current_frame_host()->SetRenderFrameCreated(true);
}
// Create the renderer process in advance if requested.
if (params.desired_renderer_state ==
CreateParams::kInitializeAndWarmupRendererProcess) {
if (!GetRenderManager()->current_frame_host()->IsRenderFrameLive()) {
GetRenderManager()->InitRenderView(GetRenderViewHost(), nullptr);
}
}
// Ensure that observers are notified of the creation of this WebContents's
// main RenderFrameHost. It must be done here for main frames, since the
// NotifySwappedFromRenderManager expects view_ to already be created and that
// happens after RenderFrameHostManager::Init.
NotifySwappedFromRenderManager(
nullptr, GetRenderManager()->current_frame_host(), true);
}
这个Init方法的代码比较长,我们分几个部分来研究下
1.创建SiteInstance
由于WebContentsImpl创建的时候params里的site_instance是空的,所以这里会先调用SiteInstance的Create方法来创建一个SiteInstance,这里的逻辑比较简单,就是创建几个相关的对象,下面是这里涉及到的一些代码
scoped_refptr<SiteInstance> SiteInstance::Create(
BrowserContext* browser_context) {
DCHECK(browser_context);
return SiteInstanceImpl::Create(browser_context);
}
scoped_refptr<SiteInstanceImpl> SiteInstanceImpl::Create(
BrowserContext* browser_context) {
DCHECK(browser_context);
return base::WrapRefCounted(
new SiteInstanceImpl(new BrowsingInstance(browser_context)));
}
2.创建各个id
这一步主要是为main_frame_widget_routing_id等一些变量赋值
3.GetRenderManager->Init分析
先看下GetRenderManager这个方法的实现
RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
return frame_tree_.root()->render_manager();
}
它返回的是一个RenderFrameHostManager对象,这个对象是在前面创建根节点FrameTreeNode的时候创建的,这个manager对象是用来管理FrameTree的根节点的。
下面再看下RenderFrameHostManager的Init方法
void RenderFrameHostManager::Init(SiteInstance* site_instance,
int32_t view_routing_id,
int32_t frame_routing_id,
int32_t widget_routing_id,
bool renderer_initiated_creation) {
DCHECK(site_instance);
SetRenderFrameHost(CreateRenderFrameHost(site_instance, view_routing_id,
frame_routing_id, widget_routing_id,
delegate_->IsHidden(),
renderer_initiated_creation));
// Notify the delegate of the creation of the current RenderFrameHost.
// Do this only for subframes, as the main frame case is taken care of by
// WebContentsImpl::Init.
if (!frame_tree_node_->IsMainFrame()) {
delegate_->NotifySwappedFromRenderManager(
nullptr, render_frame_host_.get(), false);
}
}
这里的主要逻辑是调用CreateRenderFrameHost来创建一个RenderFrameHost对象,然后设置给本地变量,我们接下来看下CreateRenderFrameHost的实现
std::unique_ptr<RenderFrameHostImpl>
RenderFrameHostManager::CreateRenderFrameHost(
SiteInstance* site_instance,
int32_t view_routing_id,
int32_t frame_routing_id,
int32_t widget_routing_id,
bool hidden,
bool renderer_initiated_creation) {
if (frame_routing_id == MSG_ROUTING_NONE)
frame_routing_id = site_instance->GetProcess()->GetNextRoutingID();
// Create a RVH for main frames, or find the existing one for subframes.
FrameTree* frame_tree = frame_tree_node_->frame_tree();
RenderViewHostImpl* render_view_host = nullptr;
//1.判断是不是MainFrame
if (frame_tree_node_->IsMainFrame()) {
//2.创建RenderViewHost
render_view_host = frame_tree->CreateRenderViewHost(
site_instance, view_routing_id, frame_routing_id, widget_routing_id,
false, hidden);
// TODO(avi): It's a bit bizarre that this logic lives here instead of in
// CreateRenderFrame(). It turns out that FrameTree::CreateRenderViewHost
// doesn't /always/ create a new RenderViewHost. It first tries to find an
// already existing one to reuse by a SiteInstance lookup. If it finds one,
// then the supplied routing IDs are completely ignored.
// CreateRenderFrame() could do this lookup too, but it seems redundant to
// do this lookup in two places. This is a good yak shave to clean up, or,
// if just ignored, should be an easy cleanup once RenderViewHostImpl has-a
// RenderWidgetHostImpl. https://crbug.com/545684
if (view_routing_id == MSG_ROUTING_NONE) {
widget_routing_id = render_view_host->GetWidget()->GetRoutingID();
} else {
DCHECK_NE(view_routing_id, widget_routing_id);
DCHECK_EQ(view_routing_id, render_view_host->GetRoutingID());
}
} else {
render_view_host = frame_tree->GetRenderViewHost(site_instance);
CHECK(render_view_host);
}
//3.RenderFrameHostFactory::Create方法
return RenderFrameHostFactory::Create(
site_instance, render_view_host, frame_tree->render_frame_delegate(),
frame_tree, frame_tree_node_, frame_routing_id, widget_routing_id, hidden,
renderer_initiated_creation);
}
我们把RenderFrameHostImpl的创建过程分为3个部分来讲解
a.判断是不是MainFrame
判断是不是MainFrame的逻辑为
bool FrameTreeNode::IsMainFrame() const {
return frame_tree_->root() == this;
}
由于这里的frame_tree_node_对应的是该RenderFrameHostManager中的FrameTree的一个节点,而该RenderFrameHostManager对象就是前面通过FrameTree的根节点root_得到的,所以这里的IsMainFrame为true。顺便说下每个webview都有一个MainFrame,用来承载网页内容,如果网页中有嵌入iframe标签的话会再创建一个FrameTreeNode,该node对应的Frame为SubFrame,即不是MainFrame。
b.创建RenderViewHost
下面我们看下CreateRenderViewHost的实现逻辑
RenderViewHostImpl* FrameTree::CreateRenderViewHost(
SiteInstance* site_instance,
int32_t routing_id,
int32_t main_frame_routing_id,
int32_t widget_routing_id,
bool swapped_out,
bool hidden) {
if (RenderViewHostImpl* existing_rvh = GetRenderViewHost(site_instance))
return existing_rvh;
RenderViewHostImpl* rvh =
static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create(
site_instance, render_view_delegate_, render_widget_delegate_,
routing_id, main_frame_routing_id, widget_routing_id, swapped_out,
hidden));
render_view_host_map_[site_instance->GetId()] = base::WrapUnique(rvh);
return rvh;
}
这里主要通过RenderViewHostFactory::Create方法创建一个RenderViewHostImpl对象,然后将这个对象放在render_view_host_map_的map中,以便后续可以直接使用。下面看下RenderViewHostFactory::Create的实现
// static
RenderViewHost* RenderViewHostFactory::Create(
SiteInstance* instance,
RenderViewHostDelegate* delegate,
RenderWidgetHostDelegate* widget_delegate,
int32_t routing_id,
int32_t main_frame_routing_id,
int32_t widget_routing_id,
bool swapped_out,
bool hidden) {
// RenderViewHost creation can be either browser-driven (by the user opening a
// new tab) or renderer-driven (by script calling window.open, etc).
//
// In the browser-driven case, the routing ID of the view is lazily assigned:
// this is signified by passing MSG_ROUTING_NONE for |routing_id|.
if (routing_id == MSG_ROUTING_NONE) {
DCHECK_EQ(widget_routing_id, MSG_ROUTING_NONE);
routing_id = instance->GetProcess()->GetNextRoutingID();
widget_routing_id = instance->GetProcess()->GetNextRoutingID();
} else {
// Otherwise, in the renderer-driven case, the routing ID of the view is
// already set. This is due to the fact that a sync render->browser IPC is
// involved. In order to quickly reply to the sync IPC, the routing IDs are
// assigned as early as possible. The IO thread immediately sends a reply to
// the sync IPC, while deferring the creation of the actual Host objects to
// the UI thread.
}
if (factory_) {
return factory_->CreateRenderViewHost(instance, delegate, widget_delegate,
routing_id, main_frame_routing_id,
widget_routing_id, swapped_out);
}
return new RenderViewHostImpl(
instance,
base::WrapUnique(RenderWidgetHostFactory::Create(
widget_delegate, instance->GetProcess(), widget_routing_id, nullptr,
hidden)),
delegate, routing_id, main_frame_routing_id, swapped_out,
true /* has_initialized_audio_host */);
}
这里主要是调用RenderViewHostImpl的构造方法创建一个RenderViewHostImpl对象,由于RenderViewHostImpl的创建过程比较复杂,涉及到Render进程的启动等逻辑,这块我们在后面再分析。
回到前面CreateRenderFrameHost的逻辑中,在创建完RenderViewHostImpl之后会调用RenderFrameHostFactory的Create方法
c.RenderFrameHostFactory::Create
std::unique_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
int32_t widget_routing_id,
bool hidden,
bool renderer_initiated_creation) {
if (factory_) {
return factory_->CreateRenderFrameHost(
site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
routing_id, widget_routing_id, hidden, renderer_initiated_creation);
}
return base::WrapUnique(new RenderFrameHostImpl(
site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
routing_id, widget_routing_id, hidden, renderer_initiated_creation));
}
这里主要也是通过RenderFrameHostImpl来构建一个RenderFrameHost对象,把之前创建的RenderViewHostImpl对象存贮在自己变量中。
接下来再回到WebContentsImpl的Init中来
4.创建WebContentsView
WebContentsView* CreateWebContentsView(
WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate,
RenderViewHostDelegateView** render_view_host_delegate_view) {
WebContentsViewAndroid* rv = new WebContentsViewAndroid(
web_contents, delegate);
*render_view_host_delegate_view = rv;
return rv;
}
在android平台会创建一个WebContentsViewAndroid
这样整个WebContentsImpl的Init方法基本就介绍完了。
再回到JNI_AwContents_Init中,即
static jlong JNI_AwContents_Init(JNIEnv* env,
const JavaParamRef<jobject>& browser_context) {
// TODO(joth): Use |browser_context| to get the native BrowserContext, rather
// than hard-code the default instance lookup here.
std::unique_ptr<WebContents> web_contents(content::WebContents::Create(
content::WebContents::CreateParams(AwBrowserContext::GetDefault())));
// Return an 'uninitialized' instance; most work is deferred until the
// subsequent SetJavaPeers() call.
return reinterpret_cast<intptr_t>(new AwContents(std::move(web_contents)));
}
在创建完WebContentsImpl之后会创建AwContents对象。
AwContents::AwContents(std::unique_ptr<WebContents> web_contents)
: content::WebContentsObserver(web_contents.get()),
browser_view_renderer_(
this,
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})),
web_contents_(std::move(web_contents)) {
base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1);
icon_helper_.reset(new IconHelper(web_contents_.get()));
icon_helper_->SetListener(this);
web_contents_->SetUserData(android_webview::kAwContentsUserDataKey,
std::make_unique<AwContentsUserData>(this));
browser_view_renderer_.RegisterWithWebContents(web_contents_.get());
CompositorID compositor_id;
if (web_contents_->GetRenderViewHost() &&
web_contents_->GetRenderViewHost()->GetProcess()) {
compositor_id.process_id =
web_contents_->GetRenderViewHost()->GetProcess()->GetID();
compositor_id.routing_id =
web_contents_->GetRenderViewHost()->GetWidget()->GetRoutingID();
}
browser_view_renderer_.SetActiveCompositorID(compositor_id);
render_view_host_ext_.reset(
new AwRenderViewHostExt(this, web_contents_.get()));
permission_request_handler_.reset(
new PermissionRequestHandler(this, web_contents_.get()));
AwAutofillClient* autofill_manager_delegate =
AwAutofillClient::FromWebContents(web_contents_.get());
if (autofill_manager_delegate)
InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData());
content::SynchronousCompositor::SetClientForWebContents(
web_contents_.get(), &browser_view_renderer_);
AwContentsLifecycleNotifier::OnWebViewCreated();
}
这里主要是创建browser_view_renderer_,它是一个BrowserViewRenderer对象
BrowserViewRenderer::BrowserViewRenderer(
BrowserViewRendererClient* client,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
: client_(client),
ui_task_runner_(ui_task_runner),
current_compositor_frame_consumer_(nullptr),
compositor_(nullptr),
is_paused_(false),
view_visible_(false),
window_visible_(false),
attached_to_window_(false),
was_attached_(false),
hardware_enabled_(false),
dip_scale_(0.f),
page_scale_factor_(1.f),
min_page_scale_factor_(0.f),
max_page_scale_factor_(0.f),
on_new_picture_enable_(false),
clear_view_(false),
offscreen_pre_raster_(false),
weak_ptr_factory_(this) {}
这里的client就是前面AwContents对象。