文章目录
前言
参考
-
Content API //
-
Getting Around the Chromium Source Code Directory Structure ——Code paths for common operations //
content & content shell
- content:浏览器通用的模块,并提供一些简单易用的接口给开发者,该接口即为Content API。
- content shell:为了方便测试,chromium实现了基于content api的简单测试程序
- 仅仅是一个壳(shell),调用了content API并实现了部分必需的回调接口,可以用来测试和其他一些简单的功能。
- Chromium Embedded Framework (CEF) : 目的是提供一套嵌入式的接口,最初的版本是基于早期的RendererHost和chrome浏览器的很多内部接口开发而来的,在CEF3中,其主要依赖于公开的Content API来实现的。
content
- /content/shell/app/shell_main.cc : content_shell.exe的程序入口:初始化后进入 content _main.cc
- /src/content/public:Embedder API (contain only interfaces, enums, structs and (rarely) static functions)
- Content API:支持所有的HTML5功能和GPU硬件加速功能
content shell
- content/browser/shell.cc/
Shell::AddNewContents
: 创建新的shell。Shell
继承自WebContentsDelegate
、WebContentsObserver
。重写前者的AddNewContents
。
- WebContents
- content/browser/webcontents/web_contents_impl.cc/
WebContentsImpl::SetDelegate(WebContentsDelegate* delegate)
:WebContentsImpl
继承自WebContents
… 。重写了前者的SetDelegate
。
content API
- /content/public 暴露出content 的API。 Content API 即是内核提供的接口。
- content API 的目的:
- 让Chrome的开发者们摆脱content内部的复杂工作原理和机制;
- 给content和chrome划分清楚的界限来帮助开发者或者嵌入式的使用者们。
- 每个部分的接口一般也可以分成两类,
- 一类是嵌入者调用的接口。(embedder可以是Chrome浏览器,CEF3和content shell)
- 一类是嵌入者实现的回调接口,被content API的内部实现所调用,例如参与实现的逻辑,事件的监听等。
- 接口头文件中使用的类指针 大量使用了 前置声明 ,(直接在前面声明这个类, 而不是直接include),这使得不用展开类,节约了编译时间。
- 因为都只是用了类的指针,只需要声明即可,不需要整个类的大小等信息。
content::ContentMain
:应该被embedder 的main 所调用,用于对所有进程的初始设置。- embedder 可以通过
ContentMainDelegate
定制 启动。如果给delegate
传入 null,就不会覆盖默认启动。
- embedder 可以通过
ContentMainRunner
:负责content 的初始化、运行、shutdown。Run
接口 在ContentMain
=> ``
启动
- 入口函数
content/shell/app/shell_main.cc/wWinMain
- 这是content_shell.exe的程序入口,主要做一些初始化工作,例如初始化沙箱,然后就进入了content_main.cc。
- 就算是进入content 层了? 这里就是content API了。
- 执行ContentMainRunner的Create, Initialize, Run等方法。
- shell 层, 通过自己的delegate 的成员函数
RunProcess()
,作为 后续RunBrowser 中的回调,完成自己的逻辑。
开始content层
content_main.cc/ContentMain();
content_main.cc/RunContentProcess();
ContentMainRunner::Run();
//- RunBrowser();
- mojo::core::InitFeatures()
- RunBrowserProcessMain()
- BrowserMain();
- MainRun :initialize & run
- RunMainMessageLoop();
content!content::BrowserMainRunnerImpl::Run()
content!content::BrowserMainLoop::RunMainMessageLoop()
base::RunLoop->Run()
=>base!base::RunLoop::Run()
chrome 的启动过程
Chromium Source Code Directory Structure —— Code paths for common operations
- app startup
- 加载 chrome/app/main.cc 中的
WinMain
- 在子目录中加载
chrome.dll
。
- 在子目录中加载
- 加载
chrome_dll
中的chrome_main.cc
中的ChromeMain
.- 其初始化普通组件,加载
BrowserMain
或者RendererMain
(根据命令行标志查看是否是子进程)BrowserMain
初始化、有不同的模式运行 webapps。- 调用 browser_init.cc 中的
LaunchWithProfile
在chrome/browser/ui/browser.cc 中产生一个新的Browser
对象。- 该对象封装了app 中的一个顶层窗口。第一个标签在这个时候被添加。
- 其初始化普通组件,加载
- 加载 chrome/app/main.cc 中的
- Tab startup & initial navigation
- 调用 weblayer/browser/browser_impl.cc 中 的
BrowserImpl::AddTab
添加一个新的tab- 它将在 browser/tab_contents/tab_contents.cc中生成一个新的
TabContents
对象。
- 它将在 browser/tab_contents/tab_contents.cc中生成一个新的
TabContents
通过chrome/browser/tab_contents/render_view_host_manager.cc 中RenderViewHostManager::Init
函数创建一个RenderViewHost
(chrome/browser/render_view_host_manager.cc)- 根据SiteInstance,
RenderViewHost
要么产生一个新的渲染器进程,要么复用一个现有的RenderProcessHost
(Browser 中代表单个renderer子进程的对象)
- 根据SiteInstance,
- chrome/browser/tab_contents/navigation_controller.cc中的
NavigationController
为tab 内容所拥有,使用NavigationController::LoadURL
中导航到新标签的URL。
- 调用 weblayer/browser/browser_impl.cc 中 的
- Navigating from the URL bar
- 当用户在URL栏中输入一个条目时, 确终的目标URL并将其传递给
AutocompleteEdit::OpenURL
。
- 当用户在URL栏中输入一个条目时, 确终的目标URL并将其传递给
weblayer
- weblayer 构建于 content 之上,期望能掩盖 content API,是高层次的嵌入式 API ,用于构建浏览器。
- 与
content
只关注沙盒化多进程 Web 平台不同,WebLayer 包括现代浏览器功能和谷歌的整合。 - 它是Chrome浏览器的可重用版本,可能会共享部分UI,支持所有现代HTML5和浏览器功能(如权限的UI、自动填充、安全浏览等…)。
- 与
- 他的设计目标为:
- 足够强,以建立一个现代的浏览器
- 嵌入者应该自由的获得新的 Web 平台能力,不用去持续修改 UI 、code。
- 隐藏子进程,需要在渲染器中运行的代码都需要成为WebLayer的一部分。(不鼓励 script inject)
目录结构
- public :C++、JAVA 接口,app应该只用这些接口
- shell: 简单实例
- test : test harnesses 、测试辅助代码
- tools :帮助脚本
- app :每个进程其实运行的内部代码
- browser :browser 进程运行的内部代码
- common :browser 进程和其子进程运行的内部代码
- renderer:render 进程运行的代码
- utility :utility 进程运行的代码
WebLayer shell
- 是个跑在WebLayer 的简单 shell
- 和content shell 一样编一个跑一下就知道了。比content 的UI完整多了。
autoninja -C out/Default weblayer_shell
out/Default/bin/weblayer_shell
WebLayer public API
- public 目录下,包含了WebLayer public API,又JAVA、C++ 两种接口。
- 其构建于content 之上,不会暴漏 content API 出来。
- JAVA接口是C++ 接口的简单包装。
- WebLayer public API 是 google 在19年推出,首先在android 端发力。PSA: WebLayer, a new embedding API
CEF
- Chromium Embedded Framework (CEF):
- 基于chromium 的web 浏览器控件。(08年开始)(一个简单的框架,用于将chromium嵌入到其他APP中)
- 核心为:调用content API的接口和实现content API的回调接口,来组织和包装成CEF3自己的接口以被其他开发者所使用
- 不同于 chromium,CEF 主要应用于第三方 APP 的浏览器嵌入。
- CEF 通过 提供稳定API、release 分支(跟踪chromium的发行)、二进制发行版,以隔绝chromium、blink 的复杂底层逻辑。
- CEF 大部分特性都有默认的实现,提供了丰富的功能,几乎不用用户集成。
- 常用于:
- 向 native APP 嵌入支持H5 的浏览器控件。
- 创建 轻量级 shell APP,以使用 web 技术开发 UI。
- 在自己的绘图框架 APP 中离屏渲染。
- 对 Web属性和Web APP 的自动测试。
- CEF 特性:
- 易于集成现有或新的APP 中,支持大部分 语言和OS。
- 使host APP 可以控制 resource loading, navigation, context menus, printing 等,媲美 chrome 的性能和H5 能力。
- CEF 好深度定制吗