Chromium项目之content_shell简介(windows)

一、content_shell介绍

content shell是一个基于content api的简单测试程序, 它仅仅是一个壳,调用了content API并实现了部分必需的回调接口,可以用来测试和其他一些简单的功能。

由于chromium项目无比巨大,大到基本上无从下手,想要直接去了解chromium是一件非常痛苦的事情,所以官方提供了cef以及content_shell,而且content_shell又远比cef要简单得多。

 

 

二、content_shell项目结构

1、content_shell/app/shell_main.cc

这是content_shell.exe的程序入口,主要做一些初始化工作,例如初始化沙箱,然后就进入了content_main.cc,执行ContentMainRunner的Create, Initialize, Run等方法.

2、content_shell_crash_service/tools/content_shell_crash_service.cc

这是用来监视程序crash的,几乎这个项目里面的每个进程都会有这一块,跟breakpad一起工作,捕获程序的异常生成dump,这个对我们现在研究的content api没多大关系,略过吧.

3、content_shel_lib

content_shell的主要实现都在content_shel_lib,介绍content_shel_lib之前先说下content api.

1)、content_shel_lib/app

主要做资源加载、命令行的解释以及创建进程(renderer、gpu等)与进程息息相关的功能。

2)、content_shel_lib/browser

content shell的大部分功能逻辑都在这里实现,其中包括资源、界面、网络、下载、html5支持,js解析等等,url请求等等。

3)、content_shel_lib/common

实现一些公共的接口,进程、公钥等相关,renderer以及browser会频繁的调用到这个模块。

4)、content_shel_lib/renderer

       主要实现一些回调函数给browser调用。

5)、content_shel_lib/utility

封装一些接口提供给browser调用。

 

三、简单介绍下content api

Content API不仅提供了公开和稳定的接口,而且它从诞生以来一个重要的目标就是要支持所有的HTML5功能和GPU硬件加速功能,这可以让它的使用者们不需要很多的工作即可以得到好的HTML5支持和硬件加速机制。同时,借助于现有的多进程架构,一些chromium中的新功能例如沙箱模型等也在其中得到了支持.

Content API的相关的接口定义文件均在content/public目录下,按照功能分成六个部分:每个部分的接口一般也可以分成两类,第一类是嵌入者(embedder,这里可以是Chrome浏览器,CEF3和content shell)调用的接口,另一类是嵌入者实现的回调接口,被content API的内部实现所调用,例如参与实现的逻辑,事件的监听等。

下面详细介绍一下Content API包含哪些部分:

1)  app

这部分主要是跟应用程序或者进程的创建和初始化相关。

第一类,主要包括创建进程的初始化函数,content的初始化和关闭;

第二类,主要是实现回调函数,告诉嵌入者启动完成,进程启动,进程推出,沙盒模型初始化开始和结束等等。

2)  browser

第一类包括,对一些HTML5功能和其他一些高级功能实现的参与,例如resource,sensor,notification,speech recognition, web worker,download, web intents,等等;

第二类包括ContentBrowserClient,主要是实现部分逻辑,被Browser端(或者进程)调用,还有就是一些事件的回调函数.

3)  common

主要定义一些公共的接口,被render和browser共享,例如一些进程相关,参数,gpu相关等等

4)  render

第一类包含获取RenderThread的消息循环,注册v8 extension,计算JavaScript表达式等等

第二类包括ContentRendererClient,主要是实现部分逻辑,被Browser端(或者进程)调用,还有就是一些事件的回调函数

5)  utility

工具类接口,主要包括让嵌入者参与content API中的线程创建和消息的过滤。

6)gpu

创建gpu进程进行gpu加速

7)child

       具体功能有待研究,content_shell没有直接调用到此模块的接口。

 

四、关于content目录结构说明

  • Embedder API is under src/content/public
  • content/public should contain only interfaces, structs and (rarely) static functions
  •  If a mojom is only used inside content, it should be in content/common
  •  If it's an interface that is implemented or called by content's embedder, then it belongs in content/public/common.
  • all code under content should be in the "content" namespace
  • content implementation code should use other implementations directly and not go through the interface (i.e. code in content/renderer should use RenderViewImpl instead of content::RenderView)
  • only expose methods in the public API that embedders need. If a method is only used by other code in content, it belongs in foo_impl.h and not foo.h.

 

以上几点来自于chromium官方文档,http://www.chromium.org/developers/content-module/content-api,

选了几点个人认为比较重要的贴出来。

 

 


五、content shell 与content api 的关系

1、 content_shell调用的所有接口的头文件都在content/public目录下

2、 content_shell还包含了content/common目录下的个别头文件,这些文件只是某些通用的功能的实现,并不属于content api。

3、 content_shell还包含了少数其他模块的头文件,base、build、components、cc、media、ui、sandbox、net、ipc、device、testing、url、mojo、storage、services、third_party、chromeos、grit、skia、v8、ppapi、mojo

4、 content_shell通过包含content api头文件调用相关api,api的实现的.cc文件在content目录下的其他目录(可能在public下,也可能在跟public同级的其他目录下),通过lib方式使用。

5、 content api 的头文件跟实现文件太分裂,有些是在同一目录下,有些是在不同目录下,这点还没有领会其真正用意。

### 无法获取驱动程序的解决方案 当遇到 `Unable to obtain driver using Selenium Manager: Selenium Manager failed` 的错误时,通常是因为 Selenium WebDriver 配置不正确或者环境变量未设置妥当。以下是可能的原因以及对应的解决方法: #### 原因分析 1. **WebDriver 版本兼容性问题**: 如果使用的浏览器版本与 WebDriver 不匹配,则可能导致此错误。 2. **Selenium Manager 失败**: 自动化工具尝试通过 Selenium Manager 下载并配置合适的 WebDriver,但如果网络连接不稳定或下载路径受限,则会引发失败。 3. **操作系统权限不足**: 在某些情况下,缺少必要的管理员权限可能会阻止 WebDriver 正常启动。 --- #### 解决方案 ##### 方法一:手动指定 WebDriver 路径 可以通过显式定义 WebDriver 的位置来规避自动管理器的问题。例如,在 Python 中可以这样操作: ```python from selenium import webdriver options = webdriver.ChromeOptions() driver_path = "/path/to/chromedriver" driver = webdriver.Chrome(executable_path=driver_path, options=options) ``` 这种方法绕过了 Selenium Manager 并直接指定了可执行文件的位置[^1]。 ##### 方法二:更新 Selenium 和 WebDriver 确保安装的是最新版 Selenium 库及其对应浏览器的 WebDriver。对于 Chrome 浏览器而言,需确认其版本号并与之相适应的 chromedriver 是否已就绪。如果不确定当前浏览器的具体版本,可通过以下方式查询: - 对于 Windows 用户,打开命令提示符输入 `chrome --version`; - macOS 或 Linux 则分别运行 `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version` 或者 `google-chrome --version`. 随后访问 [ChromeDriver 官方网站](https://sites.google.com/a/chromium.org/chromedriver/downloads),找到适配的版本进行替换。 ##### 方法三:调整隐藏 API 政策 (Hidden API Policy) 针对部分 Android 设备上发生的 ADB Command Failed 错误(退出码为 255),可能是由于系统限制调用了受保护的方法所致。此时需要修改设备上的全局属性以允许这些接口被访问。具体步骤如下: 1. 使用 adb shell 进入终端; 2. 执行命令删除现有策略记录:`settings delete global hidden_api_policy_pre_p_apps; settings delete global hidden_api_policy_p_apps; settings delete global hidden_api_policy` ; 3. 添加新的宽松型规则:`settings put global hidden_api_policy 1` ; 上述更改使得应用程序能够突破常规约束从而正常工作[^2]. ##### 方法四:检查防火墙及代理设置 有时企业内部网络安全措施也会干扰外部资源加载过程中的通信环节。因此建议临时关闭杀毒软件实时防护功能或是将相关网址加入白名单列表里再试一次看看效果如何变化. --- ### 示例代码片段 下面提供了一个简单的例子展示如何初始化一个带参数选项的新实例对象: ```python from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.common.by import By import os service = ChromeService('/usr/local/bin/chromedriver') # 替换为你本地的实际路径 prefs = {"profile.default_content_setting_values.notifications": 2} opt = webdriver.ChromeOptions() opt.add_experimental_option('prefs', prefs) try: browser = webdriver.Chrome(service=service,options=opt) except Exception as e: print(f"Error occurred while initializing the driver:{e}") finally: pass ``` --- ### 总结 综上所述,要彻底消除此类异常状况的发生概率可以从以下几个方面入手考虑改进措施——升级组件至最新稳定发行版;合理规划依赖关系链路结构设计思路方向转变寻求更优解法替代传统做法等等[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值