I am new to Chromium development.
Add a new parent menu to the top right menu of Chromium, create a submenu called Help and Settings, for example, and click the internal URL (ex: test://settings or test://help custom) when you click on each submenu. If one scheme is difficult, I would like to open the HTML I wrote through chrome://test-settings or chrome://help. But I’ve been trying for two weeks and I keep getting stuck.
With the code I’ve modified so far, I can see the submenu in the menu and click on it, but it doesn’t show up in the console:
[2558072:2558072:0710/121539.983950:INFO:chrome_web_ui_controller_factory.cc(414)] Debug LHS: URL spec is securitynet://help/
[2558072:2558072:0710/121539.983991:INFO:chrome_web_ui_controller_factory.cc(415)] Debug LHS: URL scheme is securitynet
[2558072:2558072:0710/121539.984023:INFO:chrome_web_ui_controller_factory.cc(416)] Debug LHS: URL host is help
[2558072:2558072:0710/121539.984054:INFO:chrome_web_ui_controller_factory.cc(417)] Debug LHS: URL host_piece is help
[2558072:2558072:0710/121539.984083:INFO:chrome_web_ui_controller_factory.cc(418)] Debug LHS: URL path is /
[2558072:2558072:0710/121539.984116:INFO:chrome_web_ui_controller_factory.cc(422)] Processing LHS1 SecurityNet VPN URL: securitynet://help/
[2558072:2558072:0710/121539.984147:INFO:chrome_web_ui_controller_factory.cc(423)] Processing URL host is help
[2558072:2558072:0710/121539.984181:INFO:chrome_web_ui_controller_factory.cc(425)] Creating SecurityNetVpnHelpUI
[2558072:2558072:0710/121539.984216:INFO:securitynet_vpn_ui.cc(16)] lhs SecurityNetVpnHelpUI called
[2558072:2558072:0710/121539.984294:INFO:securitynet_vpn_ui.cc(21)] AddResourcePath securityNetVpnHelpUI called
[2558072:2558072:0710/121539.984338:INFO:securitynet_vpn_ui.cc(23)] SetDefaultResource securityNetVpnHelpUI called
[2558072:2558072:0710/121539.984369:INFO:securitynet_vpn_ui.cc(25)] Current WebUI Bindings: 3
[2558072:2558072:0710/121540.000615:INFO:chrome_web_ui_controller_factory.cc(414)] Debug LHS: URL spec is securitynet://help/
[2558072:2558072:0710/121540.000696:INFO:chrome_web_ui_controller_factory.cc(415)] Debug LHS: URL scheme is securitynet
[2558072:2558072:0710/121540.000735:INFO:chrome_web_ui_controller_factory.cc(416)] Debug LHS: URL host is help
[2558072:2558072:0710/121540.000767:INFO:chrome_web_ui_controller_factory.cc(417)] Debug LHS: URL host_piece is help
[2558072:2558072:0710/121540.000798:INFO:chrome_web_ui_controller_factory.cc(418)] Debug LHS: URL path is /
[2558072:2558072:0710/121540.000832:INFO:chrome_web_ui_controller_factory.cc(422)] Processing LHS1 SecurityNet VPN URL: securitynet://help/
[2558072:2558072:0710/121540.000863:INFO:chrome_web_ui_controller_factory.cc(423)] Processing URL host is help
[2558072:2558072:0710/121540.000910:INFO:chrome_web_ui_controller_factory.cc(425)] Creating SecurityNetVpnHelpUI
[2558072:2558072:0710/121540.001025:FATAL:render_frame_host_impl.cc(6596)] Check failed: false. Calling AllowBindings for a process not locked to WebUI:{ securitynet://help/ }
It logs and just quits.
I am attaching code that I modified or added arbitrarily. Please advise if you can.
generated_resources.grd
<message name="IDS_SECURITYNET_VPN_MENU" desc="The label of the SecuritynetVPN menu item">
SecuritynetVPN
</message>
<message name="IDS_SECURITYNET_VPN_HELP" desc="The label of the SecuritynetVPN Help submenu item">
SecuritynetVPN Help
</message>
<message name="IDS_SECURITYNET_VPN_SETTINGS" desc="The label of the SecuritynetVPN Settings submenu item">
SecuritynetVPN Settings
</message>
</messages>
<includes>
<include name="IDR_SECURITYNET_VPN_HELP_HTML" file="../browser/resources/securitynet/help.html" type="BINDATA" />
<include name="IDR_SECURITYNET_VPN_SETTINGS_HTML" file="../browser/resources/securitynet/settings.html" type="BINDATA" />
</includes>
chrome_web_ui_controller_factory.cc
//securitynet
template <>
WebUIController* NewWebUI<SecurityNetVpnHelpUI>(WebUI* web_ui, const GURL& url) {
return new SecurityNetVpnHelpUI(web_ui);
}
template <>
WebUIController* NewWebUI<SecurityNetVpnSettingsUI>(WebUI* web_ui, const GURL& url) {
return new SecurityNetVpnSettingsUI(web_ui);
}
WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
Profile* profile,
const GURL& url) {
LOG(INFO) << "Debug LHS: URL spec is " << url.spec();
LOG(INFO) << "Debug LHS: URL scheme is " << url.scheme();
LOG(INFO) << "Debug LHS: URL host is " << url.host();
LOG(INFO) << "Debug LHS: URL host_piece is " << url.host_piece();
LOG(INFO) << "Debug LHS: URL path is " << url.path();
//securitynet
if (url.SchemeIs(chrome::kSecuritynetVPNScheme)) {
LOG(INFO) << "Processing LHS1 SecurityNet VPN URL: " << url.spec();
LOG(INFO) << "Processing URL host is " << url.host();
if (url.host() == "help") {
LOG(INFO) << "Creating SecurityNetVpnHelpUI";
return &NewWebUI<SecurityNetVpnHelpUI>;
} else if (url.host() == "settings") {
LOG(INFO) << "Creating SecurityNetVpnSettingsUI";
return &NewWebUI<SecurityNetVpnSettingsUI>;
}
LOG(WARNING) << "Unknown SecurityNet VPN URL: " << url.spec();
}
app_menu_model.cc
void AppMenuModel::Build() {
// Build (and, by extension, Init) should only be called once.
DCHECK_EQ(0u, GetItemCount());
// securitynet:SecuritynetVPN 메뉴 추가
auto securitynet_vpn_sub_menu = std::make_unique<ui::SimpleMenuModel>(this);
securitynet_vpn_sub_menu->AddItemWithStringId(IDC_SECURITYNET_VPN_HELP, IDS_SECURITYNET_VPN_HELP);
securitynet_vpn_sub_menu->AddItemWithStringId(IDC_SECURITYNET_VPN_SETTINGS, IDS_SECURITYNET_VPN_SETTINGS);
AddSubMenuWithStringIdAndVectorIcon(this, IDC_SECURITYNET_VPN_MENU, IDS_SECURITYNET_VPN_MENU, securitynet_vpn_sub_menu.get(), kNewWindowIcon);
sub_menus_.push_back(std::move(securitynet_vpn_sub_menu));
void AppMenuModel::ExecuteCommand(int command_id, int event_flags) {
switch (command_id) {
// ... (기존 case 문들)
case IDC_SECURITYNET_VPN_HELP:
chrome::OpenSecuritynetVPNHelp(browser_);
break;
case IDC_SECURITYNET_VPN_SETTINGS:
chrome::OpenSecuritynetVPNSettings(browser_);
break;
default:
break;
// ... (기존 default case)
}
chrome_content_client.cc
void ChromeContentClient::AddAdditionalSchemes(Schemes* schemes) {
for (auto* standard_scheme : kChromeStandardURLSchemes)
schemes->standard_schemes.push_back(standard_scheme);
// SecurityNet VPN 스키마 추가
schemes->standard_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->secure_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->cors_enabled_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->csp_bypassing_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->local_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->no_access_schemes.push_back(chrome::kSecuritynetVPNScheme);
schemes->service_worker_schemes.push_back(chrome::kSecuritynetVPNScheme);
LOG(INFO) << "SecurityNet VPN scheme added to additional schemes";
securitynet_vpn_ui.cc
#include "chrome/browser/ui/webui/securitynet_vpn_ui.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "base/logging.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/bindings_policy.h"
SecurityNetVpnHelpUI::SecurityNetVpnHelpUI(content::WebUI* web_ui)
: TopChromeWebUIController(web_ui, /*enable_chrome_send=*/true) {
LOG(INFO) << "lhs SecurityNetVpnHelpUI called";
web_ui->SetBindings(content::BINDINGS_POLICY_WEB_UI);
LOG(INFO) << "Current WebUI Bindings: " << web_ui->GetBindings();
content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
web_ui->GetWebContents()->GetBrowserContext(),
chrome::kSecuritynetVPNScheme);
source->AddResourcePath("help.html", IDR_SECURITYNET_VPN_HELP_HTML);
LOG(INFO) << "AddResourcePath securityNetVpnHelpUI called";
source->SetDefaultResource(IDR_SECURITYNET_VPN_HELP_HTML);
LOG(INFO) << "SetDefaultResource securityNetVpnHelpUI called";
content::RenderFrameHost* frame_host = web_ui->GetWebContents()->GetPrimaryMainFrame();
frame_host->AllowBindings(content::BINDINGS_POLICY_WEB_UI);
LOG(INFO) << "Frame Host Bindings After: " << frame_host->GetEnabledBindings();
}
SecurityNetVpnHelpUI::~SecurityNetVpnHelpUI() = default;
SecurityNetVpnSettingsUI::SecurityNetVpnSettingsUI(content::WebUI* web_ui)
: TopChromeWebUIController(web_ui, /*enable_chrome_send=*/true) {
LOG(INFO) << "lhs SecurityNetVpnSettingsUI called";
web_ui->SetBindings(content::BINDINGS_POLICY_WEB_UI);
LOG(INFO) << "Current WebUI Bindings: " << web_ui->GetBindings();
content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
web_ui->GetWebContents()->GetBrowserContext(),
chrome::kSecuritynetVPNScheme);
source->AddResourcePath("settings.html", IDR_SECURITYNET_VPN_SETTINGS_HTML);
LOG(INFO) << "AddResourcePath SecurityNetVpnSettingsUI called";
source->SetDefaultResource(IDR_SECURITYNET_VPN_SETTINGS_HTML);
LOG(INFO) << "SetDefaultResource SecurityNetVpnSettingsUI called";
content::RenderFrameHost* frame_host = web_ui->GetWebContents()->GetPrimaryMainFrame();
frame_host->AllowBindings(content::BINDINGS_POLICY_WEB_UI);
LOG(INFO) << "Frame Host Bindings After: " << frame_host->GetEnabledBindings();
}
SecurityNetVpnSettingsUI::~SecurityNetVpnSettingsUI() = default;
securitynet_vpn_ui.h
#ifndef CHROME_BROWSER_UI_WEBUI_SECURITYNET_VPN_SECURITYNET_VPN_UI_H_
#define CHROME_BROWSER_UI_WEBUI_SECURITYNET_VPN_SECURITYNET_VPN_UI_H_
#include "chrome/browser/ui/webui/top_chrome/top_chrome_web_ui_controller.h"
class SecurityNetVpnHelpUI : public TopChromeWebUIController {
public:
explicit SecurityNetVpnHelpUI(content::WebUI* web_ui);
~SecurityNetVpnHelpUI() override;
SecurityNetVpnHelpUI(const SecurityNetVpnHelpUI&) = delete;
SecurityNetVpnHelpUI& operator=(const SecurityNetVpnHelpUI&) = delete;
};
class SecurityNetVpnSettingsUI : public TopChromeWebUIController {
public:
explicit SecurityNetVpnSettingsUI(content::WebUI* web_ui);
~SecurityNetVpnSettingsUI() override;
SecurityNetVpnSettingsUI(const SecurityNetVpnSettingsUI&) = delete;
SecurityNetVpnSettingsUI& operator=(const SecurityNetVpnSettingsUI&) = delete;
};
#endif // CHROME_BROWSER_UI_WEBUI_SECURITYNET_VPN_SECURITYNET_VPN_UI_H_
chrome/common/webui_url_constants.cc
namespace chrome {
const char kSecuritynetVPNScheme[] = "securitynet";
const char kSecuritynetVPNHelpHost[] = "help";
const char kSecuritynetVPNSettingsHost[] = "settings";
When you click on the submenu of the menu, it moves to securitynet://help in the address bar and loads help.html.
heeseok lee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.