Chromium扩展(Extension)的页面(Page)加载过程分析
- 格式:doc
- 大小:152.50 KB
- 文档页数:15
Chromium扩展(Extension)的页面(Page)加载过程分析Chromium的Extension Page其实就是网页,因此它们的加载过程与普通网页相同。
常见的Extension Page有Background Page和Popup Page。
其中,Background Page在浏览器窗口初始化完成后自动加载,之后运行在后台中。
Popup Page在用户点击地址栏右边的按钮时加载,并且显示在弹窗中。
本文接下来就分析Extension Page的加载过程。
Extension Page是加载在Extension Process中的,如图1所示:Extension Process实际上就是Render Process。
Chromium的Content层向外提供了一个WebContents类,通过调用这个类的静态成员函数Create就可以在一个Extension Process加载一个指定的Extension Page。
Background Page是一个特殊的网页,它的内容是空的,不过包含有一个background.js。
这个background.js是在Extension的清单文件中指定的。
Popup Page则与普通网页是一样的,它既可以包含有UI元素,也可以包含JavaScript脚本。
接下来,我们就结合源代码,先分析Background Page的加载过程,再分析Popup Page 的加载过程。
Chromium的chrome模块会创建一个ChromeNotificationObserver对象,用来监听每一个新打开的浏览器窗口的NOTIFICATION_BROWSER_WINDOW_READY事件。
这时候上述ChromeNotificationObserver对象的成员函数OnBrowserWindowReady会被调用,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片void ChromeNotificationObserver::OnBrowserWindowReady(Browser* browser) {Profile* profile = browser->profile();......extensions::ProcessManager* manager =ExtensionSystem::Get(profile)->process_manager();......manager->OnBrowserWindowReady();......}这个函数定义在文件external/chromium_org/chrome/browser/extensions/chrome_notification_中。
参数browser指向的是一个Browser对象。
这个Browser对象描述的就是一个新打开的浏览器窗口,ChromeNotificationObserver类的成员函数OnBrowserWindowReady首先调用它的成员函数profile获得浏览器在启动过程中创建的Profile,然后再根据这个Profile获得一个ProcessManager对象。
有了这个ProcessManager对象之后,就可以调用它的成员函数OnBrowserWindowReady,用来通知它有一个新的浏览器窗口打开了。
浏览器启动时创建Profile的过程,以及根据Profile创建ProcessManager对象的过程,可以参考前面Chromium 扩展(Extension)加载过程分析一文。
ProcessManager类的成员函数OnBrowserWindowReady在执行的过程中,就会为当前加载的Extension创建Background Page,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片void ProcessManager::OnBrowserWindowReady() {......CreateBackgroundHostsForProfileStartup();}这个函数定义在文件external/chromium_org/extensions/browser/process_ 中。
ProcessManager类的成员函数OnBrowserWindowReady调用另外一个成员函数CreateBackgroundHostsForProfileStartup为当前加载的Extension创建Background Page,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片void ProcessManager::CreateBackgroundHostsForProfileStartup() {......const ExtensionSet& enabled_extensions =ExtensionRegistry::Get(GetBrowserContext())->enabled_extensions();for (ExtensionSet::const_iterator extension = enabled_extensions.begin();extension != enabled_extensions.end();++extension) {CreateBackgroundHostForExtensionLoad(this, extension->get());......}......}这个函数定义在文件external/chromium_org/extensions/browser/process_中。
在前面Chromium扩展(Extension)加载过程分析一文提到,Chromium的Browser 进程在启动的时候,会将那些状态设置为Enabled的Extension保存在一个Extension Registry 的Enabled List中。
ProcessManager类的成员函数CreateBackgroundHostsForProfileStartup主要就是遍历这个Enabled List中的每一个Extension,并且调用函数CreateBackgroundHostForExtensionLoad检查它们是否指定了Background Page。
如果指定了,那么就会进行加载。
函数CreateBackgroundHostForExtensionLoad的实现如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片static void CreateBackgroundHostForExtensionLoad(ProcessManager* manager, const Extension* extension) {DVLOG(1) << "CreateBackgroundHostForExtensionLoad";if (BackgroundInfo::HasPersistentBackgroundPage(extension))manager->CreateBackgroundHost(extension,BackgroundInfo::GetBackgroundURL(extension));}这个函数定义在文件external/chromium_org/extensions/browser/process_ 中。
函数CreateBackgroundHostForExtensionLoad首先检查参数extension描述的Extension是否指定了类型为persitent的Background Page。
如果指定了,那么就会调用参数manager指向的一个ProcessManager对象的成员函数CreateBackgroundHost对它进行加载。
对于非persitent的Background Page,它们只会在特定事件发生时,才会被加载。
本文主要以类型为persitent的Background Page为例,说明它们的加载过程。
非persitent的Background Page的加载过程,也是类似的。
函数CreateBackgroundHostForExtensionLoad在调用ProcessManager类的成员函数CreateBackgroundHost加载一个Background Page之前,首先要获得这个Background Page的URL。
这个URL是通过调用BackgroundInfo类的静态成员函数GetBackgroundURL获得的,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片GURL BackgroundInfo::GetBackgroundURL(const Extension* extension) {const BackgroundInfo& info = GetBackgroundInfo(extension);if (info.background_scripts_.empty())return info.background_url_;return extension->GetResourceURL(kGeneratedBackgroundPageFilename);}这个函数定义在文件external/chromium_org/extensions/common/manifest_handlers/background_中。
Chromium将其平台上的程序分为扩展(Extension)和应用(App)两种。
两者具有相同的文件结构,在Chromium中都是通过一个Extension类描述,但是后者比前者具有更严格的权限限制。
应用又分为Hosted App(托管应用)和Packaged App(打包应用)两种。
Hosted App只提供一个图标和Manifest文件,并且在Manifest文件中声明了它的Popup Page 和Background Page等URL。
Packaged App则将Popup Page和Background Page文件打包在一起安装在本地。
关于Extension、Hosted App和Packaged App的更详细描述,可以参考Chrome应用基础一文。
我们假设参数extension描述的是一个Extension,并且是一个安装在本地的Extension。