基於chromium103版本
1. 自定義擴充套件API介面
chromium預設擴充套件api介面中有chrome.runtime.*,和chrome.send.*等,現在我們就仿照chrome.runtime方式來定義自己的介面,供給外掛或者網頁使用。
其實chromium 增加自定義 api 介面,在原生程式碼中新增有兩種方式,一種是使用json定義,另外一種是使用idl定義。json方式比較繁瑣,不太便利,新版本chromium基本推薦使用IDL方式來定義介面。
原生的api介面程式碼根據作用不同,分佈在不同位置:
chrome使用的API所在位置(檔案路徑在src/chrome/browser/extensions/):
1 chrome\browser\extensions\api 2 chrome\browser\extensions\* 3 chrome\common\extensions\api 4 chrome\common\extensions\*
chrome公共使用所在位置(檔案路徑在src/extensions/browser/):
1 extensions\* 2 extensions\browser\api 3 extensions\common\api 4 extensions\common\mojom
2. 自定義一個介面myInterface.print
3. 新增一個myInterface.idl檔案
src\chrome\common\extensions\api\myInterface.idl
1 // Use the <code>chrome.myInterface</code> API to myInterface 2 namespace myInterface{ 3 // myInterface State. 4 enum EchoState { 5 OK, 6 ERROR 7 }; 8 callback EchoStateCallback = void(EchoState state, DOMString out); 9 10 interface Functions { 11 // pring string. 12 static void print(DOMString input, EchoStateCallback callback); 13 }; 14 };
4. 實現C++介面標頭檔案(在下面檔案路徑新增一個myInterface.h)
src\chrome\browser\extensions\api\myInterface\myInterface_api.h
1 #ifndef CHROME_BROWSER_EXTENSIONS_API_MYINTERFACE_MYINTERFACE_API_H_ 2 #define CHROME_BROWSER_EXTENSIONS_API_MYINTERFACE_MYINTERFACE_API_H_ 3 4 #include "extensions/browser/extension_function.h" 5 6 namespace extensions { 7 8 class MyInterfacePrintFunction : public ExtensionFunction { 9 public: 10 MyInterfacePrintFunction () = default; 11 MyInterfacePrintFunction ( 12 const MyInterfacePrintFunction &) = delete; 13 MyInterfacePrintFunction & operator=( 14 const MyInterfacePrintFunction &) = delete; 15 DECLARE_EXTENSION_FUNCTION("myInterface.print", MYINTERFACE_PRINT) 16 17 protected: 18 ~MyInterfacePrintFunction () override = default; 19 20 // ExtensionFunction overrides. 21 ResponseAction Run() override; 22 }; 23 24 25 } // namespace extensions 26 27 #endif // CHROME_BROWSER_EXTENSIONS_API_MYINTERFACE_MYINTERFACE_API_H_
5. 實現C++介面CC檔案(在下面檔案路徑新增一個myInterface.cc)
src\chrome\browser\extensions\api\myInterface\myInterface_api.cc
1 #include "chrome/browser/extensions/api/myInterface/myInterface_api.h" 2 // 這個是自動生成的,在目錄"gen\chrome\common\extensions\api"下 3 #include "chrome/common/extensions/api/myInterface.h" 4 5 namespace extensions { 6 7 //MyInterfacePrintFunction 8 ExtensionFunction::ResponseAction MyInterfacePrintFunction::Run() { 9 std::unique_ptr<api::myInterface::print::Params> param = 10 api::myInterface::print::Params::Create(*args_); 11 EXTENSION_FUNCTION_VALIDATE(param.get()); 12 13 return RespondNow(ArgumentList( 14 api::myInterface::print::Results::Create(api::myInterface::EchoState::ECHO_STATE_OK, "echo " + param->input))); 15 } 16 17 } // namespace extensions
6. 新增編譯檔案
src\chrome\browser\extensions\BUILD.gn
1 "api/myInterface/myInterface_api.cc", 2 "api/myInterface/myInterface_api.h",
7. 設定 api 介面許可權
在 _api_features.json 檔案末尾新增如下內容:
src\chrome\common\extensions\api\_api_features.json
1 , 2 "myInterface": [{ 3 "channel": "stable", 4 "contexts": ["blessed_extension"] 5 }, { 6 "contexts": "all", 7 "channel": "stable", 8 "matches": ["<all_urls>"] 9 }]
在 _permission_features.json檔案末尾新增如下內容:
src\chrome\common\extensions\api\_permission_features.json
1 , 2 "myInterface": { 3 "channel": "stable", 4 "extension_types": ["extension", "legacy_packaged_app", "hosted_app", "platform_app"] 5 }
8. 新增介面定義檔案編譯項
在api_sources.gni新增中介面定義檔案:
src\chrome\common\extensions\api\api_sources.gni
1 schema_sources_ = [ 2 ... 3 myInterface.idl, 4 ]
在 src\chrome\common\extensions\api\generated_externs_list.txt
末尾新增 afree.idl
9. 新增註冊資訊及常數定義
在src\chrome\common\extensions\permissions\chrome_api_permissions.cc檔案中,找到constexpr APIPermissionInfo::InitInfo permissions_to_register[] =,新增如下內容:
constexpr APIPermissionInfo::InitInfo permissions_to_register[] = { ... {APIPermissionID::kMyInterface, "myInterface"}, };
在 src\extensions\browser\extension_function_histogram_value.h
檔案宏定義末尾根據具體宏定義的值新增自己的宏定義,在最大值的基礎上加1
1 enum HistogramValue { 2 ... 3 AUTOTESTPRIVATE_ACTIVATEAPPWINDOW = 1864, 4 MYINTERFACE_PRINT = 1865, 5 // Last entry: Add new entries above, then run: 6 // python tools/metrics/histograms/update_extension_histograms.py 7 ENUM_BOUNDARY 8 };
10. 定義 APIPermissionID 值
在src\extensions\common\mojom\api_permission_id.mojom
中,定義自己的 api id,在最大值的基礎上加1
1 enum APIPermissionID { 2 ... 3 kScripting = 566, 4 kMyInterface= 567,
... 5 }
11. 編譯生成即可
ninja -C out\DebugX64 chrome
12. 呼叫方法
chrome.myInterface.print("hello world",function(state,out){console.log(state,out)})