Chromium添加Extension api

Chromium添加Extension api

前言

extension api分为仅对chrome有效和对所有插件有效(来源于chromium文档未验证),以下以对所有插件有效做示例

环境

chroumium版本 70.0.3538.513

过程

声明导出的模块

在extensions/common/api/_api_features.json添加

1
2
3
4
5
"example": {
"channel": "stable",
"contexts": ["blessed_extension"],
"matches": ["<all_urls>"]
}

1 用来声明导出模块适用的范围和导出模块的名称

2 _api_features.json在extensions/common/api和chrome/common/extensions/api中都存在,根据范围不同在不同文件添加

编写IDL文件

添加extensions\common\api\example.idl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//
namespace example {

callback StartCallback = void(DOMString ret);

// 声明对外的函数接口有哪些
interface Functions {
static void start(StartCallback callback);
};

// 声明对外的事件有哪些
interface Events {
static void onFinished(DOMString ret);
};

};

1 第一行必须为注释,否则会编译失败

2 函数是使用callback的方式返回值,不论是否同步或异步

3 extensions/common/api和chrome/common/extensions/api中都可以添加,根据范围不同在不同文件添加

编写C++

添加extensions\browser\api\example
在目录下添加example_api.h和example_api.cc

example_api.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef __EXAMPLE_H__
#define __EXAMPLE_H__
#include "extensions/browser/extension_function.h"

namespace extensions {
namespace api {

class ExampleStartFunction : public UIThreadExtensionFunction {
public:
// 声明扩展的函数
DECLARE_EXTENSION_FUNCTION("example.start", EXAMPLE_START)
ExampleStartFunction();
// 函数实际执行
ResponseAction Run() override;

private:
void DoTask();
void OnFinished();

protected:
~ExampleStartFunction() override;
};
} // namespace api
} // namespace extensions
#endif

EXAMPLE_START枚举需要在extensions\browser\extension_event_histogram_value.h里面添加

example_api.cc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "example_api.h"
#include <thread>
#include "base/task/post_task.h"
#include "extensions/browser/event_router.h"
// 自动生成的文件
#include "extensions/common/api/example.h"

namespace extensions {
namespace api {

ExampleStartFunction::ExampleStartFunction() {}

ExampleStartFunction::~ExampleStartFunction() {}

ExtensionFunction::ResponseAction ExampleStartFunction::Run() {
base::PostTaskAndReply(
FROM_HERE,
base::BindOnce(&ExampleStartFunction::DoTask, base::RetainedRef(this)),
base::BindOnce(&ExampleStartFunction::OnFinished,
base::RetainedRef(this)));
return RespondLater();
}

void ExampleStartFunction::DoTask() {
std::this_thread::sleep_for(std::chrono::seconds(10));
}

void ExampleStartFunction::OnFinished() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
// 触发event,前端可以添加监听获得
EventRouter::Get(context_)->DispatchEventToExtension(
extension_id(),
std::make_unique<Event>(
extensions::events::ONFINISHED, api::example::OnFinished::kEventName,
api::example::OnFinished::Create("finished event")));
Respond(OneArgument(std::make_unique<base::Value>("task finished")));
}
} // namespace api
} // namespace extensions

ONFINISHED枚举在extensions\browser\extension_event_histogram_value.h里面添加

1 文件名以"模块名_api.h"结尾,否则生成时无法找到

2 生成文件有问题可以删除重新生成\src\out\Debug\gen\extensions\browser\api\generated_api_registration.h

3 chrome\browser\extensions\api和extensions\browser\api中都可以添加,根据范围不同在不同文件添加

添加编译文件

在extensions\browser\api\example里添加BUILD.gn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import("//extensions/buildflags/buildflags.gni")

assert(enable_extensions,
"Cannot depend on extensions because enable_extensions=false.")

source_set("example") {
sources = [
"example_api.cc",
"example_api.h",
]

deps = [
"//extensions/common/api",
]

public_deps = [
"//extensions/browser:browser_sources",
]
}

在extensions\browser\api\BUILD.gn中public_deps里添加

1
"//extensions/browser/api/example"

在extensions\common\api\schema.gni中extensions_api_schema_files_里添加

1
"example.idl",

验证

可以使用以下的扩展进行验证

Extension下载

参考资料

https://www.chromium.org/developers/design-documents/extensions/proposed-changes/creating-new-apis