计算机,  随想

Chrome文档精读

TODO

study the usage of base::Thread Thread pool: Sequence or Virtual thread Task runner

Multi-process Architecture

Managing renderer processes

Each renderer process has a global RenderProcess object that manages communication with the parent browser process and maintains global state. The browser maintains a corresponding RenderProcessHost for each renderer process, which manages browser state and communication for the renderer. The browser and the renderers communicate using Mojo or Chromium’s legacy IPC system.

In the renderer process:

  • The RenderProcess handles Mojo setup and legacy IPC with the corresponding RenderProcessHost in the browser. There is exactly one RenderProcess object per renderer process.
  • The RenderFrame object communicates with its corresponding RenderFrameHost in the browser process (via Mojo), and the Blink layer. This object represents the contents of one web document in a tab or subframe.

In the browser process:

  • The Browser object represents a top-level browser window.
  • The RenderProcessHost object represents the browser side of a single browser ↔ renderer IPC connection. There is one RenderProcessHost in the browser process for each renderer process.
  • The RenderFrameHost object encapsulates communication with the RenderFrame, and RenderWidgetHost handles the input and painting for RenderWidget in the browser.

Chromium has split out a number of other components into separate processes as well, sometimes in platform-specific ways. For example, it now has a separate GPU process, network service, and storage service. Sandboxed utility processes can also be used for small or risky tasks, as one way to satisfy the Rule of Two for security.

Process 进程

简单来说,出于安全、稳定和隔离性的考虑,每个网站(而不是每个标签页)都会起一个独立的进程。具体可以看Chrome更多工具里的任务管理器。每个进程的崩溃不会影响整个浏览器。

For stability, putting web site instances in separate processes limits the impact of a renderer process crash or hang, allowing other content to continue working. For performance, this allows different web site instances to run in parallel with better responsiveness, at the cost of some memory overhead for each process.

For security, strictly using separate processes for different web sites allows significantly stronger defenses against malicious web sites. In addition to running web content within a low-privilege sandbox that limits an attacker‘s access to the user’s machine, Chromium’s multi-process architecture can support Site Isolation, where each renderer process is only allowed to access data from a single site. Site Isolation involves:

  • Locked Renderer Processes: A renderer process can be limited to documents and workers from a single web site or origin, even if such documents are in iframes.
  • Browser-Enforced Restrictions: The privileged browser process can monitor IPC messages from locked processes to limit their actions or access to site data (e.g., using ChildProcessSecurityPolicy::CanAccessDataForOrigin). This prevents compromised renderer processes from asking for cross-site data, using permissions granted to other sites, etc.
  • Network Response Limitations: Chromium can ensure that locked renderer processes are only allowed to receive sensitive data (e.g., HTML, XML, JSON) from their designated site or origin, while still allowing cross-origin subresource requests (e.g., images, media) as needed for compatibility. This is achieved using Cross-Origin Read Blocking (CORB) or Opaque Response Blocking (ORB).

Principal Instance (implemented by SiteInstance): A principal instance is the core unit of Chromium‘s process model. Any two documents with the same principal in the same browsing context group (see below) must live in the same process, because they have synchronous access to each other’s content

Threads 线程

Chrome has a multi-process architecture and each process is heavily multi-threaded. The main goal is to keep the main thread (a.k.a. “UI” thread in the browser process) and IO thread (each process‘s thread for receiving IPC) responsive. This means offloading any blocking I/O or other expensive operations to other threads. Our approach is to use message passing as the way of communicating between threads. We discourage locking and thread-safe objects. Instead, objects live on only one (often virtual — we’ll get to that later!) thread and we pass messages between those threads for communication.

Task : a function pointer with optionally associated state

Cancelling a Task: Using base::WeakPtr can be used to ensure that any callback bound to an object is canceled when that object is destroyed.

In Chrome this is base::OnceCallback and base::RepeatingCallback created via base::BindOnce

A task is a base::OnceClosure added to a queue for asynchronous execution.

Task runner: An interface through which tasks can be posted. In Chrome this is base::TaskRunner.

其他概念

学习webcontents.h

The content/ layer of Chromium has a class called WebContents, which is one of the most basic building blocks of all of Chromium. This document describes how WebContentses are used to build tabs in browser windows.

WebContents is the core class in content/. A WebContents renders web content (usually HTML) in a rectangular area.

Instantiating one is simple:

//   std::unique_ptr<content::WebContents> web_contents(
//       content::WebContents::Create(
//           content::WebContents::CreateParams(browser_context)));
//   gfx::NativeView view = web_contents->GetNativeView();

// Each WebContents has exactly one NavigationController; each NavigationController belongs to one WebContents. The NavigationController canbe obtained from GetController(), and is used to load URLs into the WebContents, navigate it backwards/forwards, etc. See navigation_controller.h

Blink

Blink is a rendering engine of the web platform. Roughly speaking, Blink implements everything that renders content inside a browser tab:

Blink is embedded by many customers such as Chromium, Android WebView and Opera via content public APIs.

From the code base perspective, “Blink” normally means //third_party/blink/. From the project perspective, “Blink” normally means projects that implement web platform features. Code that implements web platform features span //third_party/blink/, //content/renderer/, //content/browser/ and other places.

Page, Frame, Document, ExecutionContext and DOMWindow

A Page corresponds to a concept of a tab (if OOPIF explained below is not enabled). Each renderer process may contain multiple tabs.
A Frame corresponds to a concept of a frame (the main frame or an iframe). Each Page may contain one or more Frames that are arranged in a tree hierarchy.
A DOMWindow corresponds to a window object in JavaScript. Each Frame has one DOMWindow.
A Document corresponds to a window.document object in JavaScript. Each Frame has one Document.
An ExecutionContext is a concept that abstracts a Document (for the main thread) and a WorkerGlobalScope (for a worker thread).

Renderer process : Page = 1 : N.

Page : Frame = 1 : M.

Frame : DOMWindow : Document (or ExecutionContext) = 1 : 1 : 1 at any point in time, but the mapping may change over time. For example, consider the following code:

iframe.contentWindow.location.href = “https://example.com”;

In this case, a new DOMWindow and a new Document are created for https://example.com. However, the Frame may be reused.

Isolate, Context, World

Isolate corresponds to a physical thread. Isolate : physical thread in Blink = 1 : 1. The main thread has its own Isolate. A worker thread has its own Isolate.

Context corresponds to a global object (In case of a Frame, it’s a window object of the Frame). Since each frame has its own window object, there are multiple Contexts in a renderer process. When you call V8 APIs, you have to make sure that you’re in the correct context.

To realize the isolation, the main thread creates one main world for the web page and one isolated world for each content script. The main world and the isolated worlds can access the same C++ DOM objects but their JavaScript objects are isolated. This isolation is realized by creating multiple V8 wrappers for one C++ DOM object; i.e., one V8 wrapper per world.

blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame();
v8::Local<v8::Context> context = web_frame->MainWorldScriptContext();

V8 API

V8 uses handles to point to V8 objects. The most common handle is v8::Local<>, which is used to point to V8 objects from a machine stack. v8::Local<> must be used after allocating v8::HandleScope on the machine stack. v8::Local<> should not be used outside the machine stack:

v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
v8::Local<v8::Context> context = web_frame->MainWorldScriptContext();
v8::Context::Scope context_scope(context);

Introduction

What is a “tab helper”? It is a WebContentsObserver owned by the WebContents itself. Let’s break that down.

WebContentsObserver

WebContentsObserver is a simple interface that allows an object to observe events in the life of a WebContents. 观察者模式,观察webcontent

最后更新于 2025年1月6日 by qlili

0 0 votes
Article Rating
guest

0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x