随笔-67  评论-7  文章-0 

怎样在chrome中内置扩展,以及一些简单的定制

本文中chromium 版本为54

参考资料:

chromium如何新增extension API以及添加内部扩展

http://slides.com/luyuan/grit#/


 

一、嵌入扩展

 

1. 复制扩展的资源文件夹,到 src\chrome\browser\resources\ 文件夹下,

其中manifest.json文件的“key”的来源:通过载入一个自定义的crx插件然后在chromiumappdata下找到该插件的key,该key可能被用于计算extension-id,如果扩展无法调用接口,有可能是key不对,在src\base\base64.ccBase64Decode函数处做检查。

(chromium中用开发者模式添加你的扩展,找到用户数据中以id命名的文件夹,得到manifest.json中的key)

如果没有这个key,chromium启动就会崩溃。

 

2. 在src\chrome\browser\extensions\component_loader.cc文件下

AddDefaultComponentExtensions()函数中添加:

 
  Add(IDR_EXTENSION_MANIFEST,
      base::FilePath(FILE_PATH_LITERAL("extension_name")));

 

 
IDR_EXTENSION_MANIFEST的定义见下面
 
 

3.在src\chrome\browser\browser_resources.grd 文件下,定义一个ID IDR_EXTENSION_MANIFEST跟扩展mainfest.json的关联

 

   
   <include name="IDR_EXTENSION_MANIFEST" file="resources\extension_dir\manifest.json" type="BINDATA" />

 

 
  这里的resources\就是上面(1)中的 src\chrome\browser\resources\
 

4.在src\chrome\browser\extensions\component_extensions_whitelist\whitelist.cc文件,   

 bool IsComponentExtensionWhitelisted(int manifest_resource_id)函数中添加:

 case IDR_EXTENSION_MANIFEST:

 

 

 

5.把web资源添加到src\chrome\browser\resources\component_extension_resources.grd文件中,用于资源打包必须把除了mainfest.json文件之外的其他独立文件都加进来

附件:python脚本,从extension目录生成相应的xml声明

 

二、其它修改

1.安装后首次运行的欢迎页面URL

src\chrome\app\resources\locale_settings.grd 中修改 IDS_WELCOME_PAGE_URL

 

 

2.改图标

   替换

   src\chrome\app\theme\chromium

   src\chrome\app\theme\default_100_percent\chromium

   src\chrome\app\theme\default_200_percent\chromium

   下面相关的图片

   exe图标在资源文件src/chrome/app/chrome_exe.rc中定义IDR_MAINFRAME,chrome.dll里也定义了一个IDR_MAINFRAME,在chrome_dll.rc中。

 

3.菜单修改

以新建标签为例:

符号定义:src\chrome\app\chrome_command_ids.h(49):#define IDC_NEW_TAB                     34014  

命令执行:src\chrome\browser\ui\browser_command_controller.cc(367):    case IDC_NEW_TAB:  

初始化状态:src\chrome\browser\ui\browser_command_controller.cc(802)  BrowserCommandController::InitCommandState

添加菜单项:src\chrome\browser\ui\toolbar\app_menu_model.cc(787):  AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);  

 

4.改产品名称

 

  • src\chrome\app\chromium_strings.grd 中的 IDS_PRODUCT_NAME 和其它带Chromium字样的字符串,IDS_PRODUCT_NAME 也出现在关于页面中
  • src\chrome\app\resources\chromium_strings_XX.xtb 等语言相关的文件中的Chromium字样,主要是<translation id = "2910007522516064972">&Chromium Browser সম্পর্কে< / translation>这句(关于chrome...)
  • src\components\components_chromium_strings.grd : IDS_VERSION_UI_LICENSE (关于...页面下面的感谢声明)
  • src\components\strings\components_chromium_strings_en-GB.xtb  <translation id="4365115785552740256"> 同上,还有其它语言的
  • <translation id="459535195905078186">Chromium 应用</translation>   改成  <translation id="459535195905078186">Chromium Browser 应用</translation>

 

 

5.移除缺少Google API 密钥……”的警告

找到src\chrome\browser\ui\startup\startup_browser_creator_impl.cc GoogleApiKeysInfoBarDelegate::Create一句

    GoogleApiKeysInfoBarDelegate::Create(InfoBarService::FromWebContents( 
        browser->tab_strip_model()->GetActiveWebContents()));

 

,注释掉。

注:这个警告是编译时 google_api_key = "no" 的结果,不使用api key,你定制的浏览器就没法登录google账户。

 

 

6.在代码中加命令行参数

  src\chrome\app\chrome_main_delegate.cc ChromeMainDelegate::BasicStartupComplete 中

bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
 
  base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  // add custom switches 
  command_line.AppendSwitch(switches::kProcessPerSite);
  command_line.AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);  

  

  

7.获取chrome APP的app-id

进入 chrome://extensions/ =》 开发者模式 =》 加载APP =》 详细信息 =》创建快捷方式 =》 快捷方式属性里有 --app-id=xxxxxx

 

8.修改navigator.userAgent/appVersion的值

src\third_party\WebKit\Source\core\loader\FrameLoader.cpp 
String FrameLoader::userAgent() const
第一行
String userAgent = client()->userAgent();
改为:
String userAgent = String::format("%s 你想加的内容/1.0.0.5", client()->userAgent().utf8().data());

注:因为沙箱的原因,这样硬编码只是权宜之计,最好是跟browser process通信获得本地配置文件中的版本信息。
 
 

附件:

grd_generator.py

# -*- coding: utf-8 -*-

import os

from Tools.scripts.treesync import raw_input


def traverse(rootDir):
    for lists in os.listdir(rootDir):
        path = os.path.join(rootDir, lists)
        if os.path.isfile(path):
            if os.path.basename(path) == 'manifest.json':
                continue
            rel_path = os.path.relpath(path, parent_dir)
            symbol = rel_path.replace('\\', '_').replace('-', '_').replace('.', '_').upper()
            print('<include name="IDR_' + symbol + '" file="' + rel_path + '" type="BINDATA" />')
        # print(path)
        if os.path.isdir(path):
            traverse(path)


dir = raw_input('请输入扩展文件夹路径:').strip('\n')
parent_dir = os.path.abspath(os.path.join(dir, os.pardir))
traverse(dir)

 

posted on 2017-02-14 14:54 honker 阅读(...) 评论(...) 编辑 收藏