Chromium扩展(Extension)的页面(Page)加载过程分析

本文详细分析了Chromium扩展(Extension)的页面加载过程,重点探讨了Background Page和Popup Page的加载流程。Background Page在浏览器窗口初始化后自动加载并运行在后台,而Popup Page在用户点击扩展按钮时加载。加载过程涉及ChromeNotificationObserver、ProcessManager和WebContents等组件,通过WebContents接口在Extension Process中加载页面。Extension Page的URL形式为chrome-extension://[extension_id]/_generated_background_page.html或chrome-extension://[extension_id]/xxx.html,与普通网页的加载、解析和渲染类似。
摘要由CSDN通过智能技术生成
               

       Chromium的Extension Page其实就是网页,因此它们的加载过程与普通网页相同。常见的Extension Page有Background Page和Popup Page。其中,Background Page在浏览器窗口初始化完成后自动加载,之后运行在后台中。Popup Page在用户点击地址栏右边的按钮时加载,并且显示在弹窗中。本文接下来就分析Extension Page的加载过程。

老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!

       Extension Page是加载在Extension Process中的,如图1所示:


图1 Extension的Background Page和Popup Page的加载示意图

       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会被调用,如下所示:

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_observer.cc中。

       参数browser指向的是一个Browser对象。这个Browser对象描述的就是一个新打开的浏览器窗口,ChromeNotificationObserver类的成员函数OnBrowserWindowReady首先调用它的成员函数profile获得浏览器在启动过程中创建的Profile,然后再根据这个Profile获得一个ProcessManager对象。有了这个ProcessManager对象之后,就可以调用它的成员函数OnBrowserWindowReady,用来通知它有一个新的浏览器窗口打开了。浏览器启动时创建Profile的过程,以及根据Profile创建ProcessManager对象的过程,可以参考前面Chromium扩展(Extension)加载过程分析一文。

        ProcessManager类的成员函数OnBrowserWindowReady在执行的过程中,就会为当前加载的Extension创建Background Page,如下所示:

void ProcessManager::OnBrowserWindowReady() {  ......  CreateBackgroundHostsForProfileStartup();}
       这个函数定义在文件external/chromium_org/extensions/browser/process_manager.cc中。

       ProcessManager类的成员函数OnBrowserWindowReady调用另外一个成员函数CreateBackgroundHostsForProfileStartup为当前加载的Extension创建Background Page,如下所示:

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_manager.cc中。

      在前面Chromium扩展(Extension)加载过程分析一文提到,Chromium的Browser进程在启动的时候,会将那些状态设置为Enabled的Extension保存在一个Extension Registry的Enabled List中。ProcessManager类的成员函数CreateBackgroundHostsForProfileStartup主要就是遍历这个Enabled List中的每一个Extension,并且调用函数CreateBackgroundHostForExtensionLoad检查它们是否指定了Background Page。如果指定了,那么就会进行加载。

      函数CreateBackgroundHostForExtensionLoad的实现如下所示:

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_manager.cc中。

       函数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获得的,如下所示:

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_info.cc中。

       Chromium将其平台上的程序分为扩展(Extension)和应用(App)两种。两者

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值