01 自定义扩展 api 接口
chrome的扩展api,如 chrome.runtime.*, chrome.send.*
等。
chromium 增加自定义 api 接口,在原生代码中添加有两种方式,一种是使用json定义,另外一种是使用idl定义。形似基本一致。
原生的api接口代码根据作用不同,分布在不同位置:
比如:
chrome用的
chrome\browser\extensions\api
chrome\browser\extensions\*
chrome\common\extensions\api
chrome\common\extensions\*
公共使用的
extensions\*
extensions\browser\api
extensions\common\api
extensions\common\mojom
02 添加一个 afree.echoString 接口
在代码 92.4515.0.110 版本添加,需要修改如下内容:
02.01 定义 afree.idl
增加 afree.idl
定义文件,其中event事件暂未实现。
src\chrome\common\extensions\api\afree.idl
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Use the <code>chrome.afree</code> API to afree
namespace afree {
// Afree State.
enum EchoState {
OK,
ERROR
};
// A afree event. This is not a standard afree event because
// afree display keyboards look significantly different from standard
// afree.
dictionary AfreeEvent {
// event id
long evt;
// result info
DOMString errmsg;
// result code
long errcode;
};
callback EchoStringCallback = void(EchoState state, DOMString result);
interface Functions {
// echo string.
static void echoString(DOMString echo, EchoStringCallback callback);
};
interface Events {
// afree event.
static void onAfreeEvent(AfreeEvent evt);
};
};
02.02 实现接口c++文件
src\chrome\browser\extensions\api\afree\afree_api.h
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_AFREE_AFREE_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_AFREE_AFREE_API_H_
#include "extensions/browser/extension_function.h"
namespace extensions {
class AfreeEchoStringFunction : public ExtensionFunction {
public:
AfreeEchoStringFunction() = default;
AfreeEchoStringFunction(
const AfreeEchoStringFunction&) = delete;
AfreeEchoStringFunction& operator=(
const AfreeEchoStringFunction&) = delete;
DECLARE_EXTENSION_FUNCTION("afree.echoString", AFREE_ECHOSTRING)
protected:
~AfreeEchoStringFunction() override = default;
// ExtensionFunction overrides.
ResponseAction Run() override;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_AFREE_AFREE_API_H_
src\chrome\browser\extensions\api\afree\afree_api.cc
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/afree/afree_api.h"
// #include <stddef.h>
// #include <memory>
// #include <utility>
// #include "base/containers/flat_map.h"
// #include "base/guid.h"
// #include "base/metrics/user_metrics.h"
// #include "base/strings/utf_string_conversions.h"
// #include "base/values.h"
// #include "chrome/browser/browser_process.h"
// #include "content/public/browser/web_contents.h"
// #include "extensions/browser/extension_function.h"
// #include "extensions/browser/extension_function_registry.h"
// 这个是自动生成的,在目录"gen\chrome\common\extensions\api"下
#include "chrome/common/extensions/api/afree.h"
// 开发工具调试 Console 中输入
// chrome.afree.echoString("aaaa", function(state, result) {console.log(state + " " + result);});
// 运行结果: OK echo aaaa
namespace afree = extensions::api::afree;
namespace {
// afree::BrowserAfreeManager* GetBrowserAfreeManager(
// content::WebContents* web_contents) {
// if (!web_contents) {
// return nullptr;
// }
// // afree::ContentAfreeService* afree_service =
// // afree::ContentAfreeServiceFactory::FromWebContents(web_contents)
// // ->DriverForFrame(web_contents->GetMainFrame());
// // if (!afree_service)
// // return nullptr;
// // return afree_service->browser_afree_manager();
// return nullptr;
// }
} // namespace
namespace extensions {
// AfreeEchoStringFunction
ExtensionFunction::ResponseAction AfreeEchoStringFunction::Run() {
std::unique_ptr<api::afree::EchoString::Params> parameters =
api::afree::EchoString::Params::Create(*args_);
EXTENSION_FUNCTION_VALIDATE(parameters.get());
return RespondNow(ArgumentList(
api::afree::EchoString::Results::Create(api::afree::EchoState::ECHO_STATE_OK, "echo " + parameters->echo)));
}
} // namespace extensions
02.03 增加编译文件
src\chrome\browser\extensions\BUILD.gn
#在 "api/activity_log_private/activity_log_private_api.h", 下面添加
"api/afree/afree_api.cc",
"api/afree/afree_api.h",
02.04 设置 api 接口权限
在 _api_features.json 文件末尾 }
前添加如下内容:
src\chrome\common\extensions\api\_api_features.json
,
"afree": [{
//"dependencies": ["permission:afree"],
"channel": "stable",
"contexts": ["blessed_extension"]
}, {
"contexts": "all",
"channel": "stable",
"matches": ["<all_urls>"]
}]
在 src\chrome\common\extensions\api\_permission_features.json
文件末尾 }
前添加如下内容:
,
"afree": {
"channel": "stable",
"extension_types": ["extension", "legacy_packaged_app", "hosted_app", "platform_app"]
}
02.05 添加接口定义文件的编译项
在 src\chrome\common\extensions\api\api_sources.gni
添加中接口定义文件。
在 schema_sources_ = [
数组末尾添加 "afree.idl",
schema_sources_ = [
...
afree.idl,
]
...
在 src\chrome\common\extensions\api\generated_externs_list.txt
末尾添加 afree.idl
02.06 添加注册信息及常量定义
src\chrome\common\extensions\permissions\chrome_api_permissions.cc
在 constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
的末尾添加注册信息
constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
...
{APIPermissionID::kAfree, "afree"},
};
在 src\extensions\browser\extension_function_histogram_value.h
文件宏定义末尾根据具体宏定义的值添加自己的宏定义
我修改时,当前最大的值是 AUTOTESTPRIVATE_ACTIVATEAPPWINDOW = 1554
, 所以自己定义的宏设置未 1555,
enum HistogramValue {
...
AUTOTESTPRIVATE_ACTIVATEAPPWINDOW = 1554,
AFREE_ECHOSTRING = 1555,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
};
02.07 定义 APIPermissionID 值
根据 src\extensions\common\mojom\api_permission_id.mojom
中当前最大值,定义自己的 api id。当前最大值 是 kScripting = 230,
,所以把 kFree
定义未 231,
enum APIPermissionID {
...
kScripting = 230,
kAfree = 231,
02.08 暂时未定义 event 事件
暂时未定义具体业务,仅仅做了一个回显。也没有完成event事件。
直接编译即可
ninja -C out\DebugX64 chrome