boca: Set up SWA skeleton
BUG=b:336881992
TEST=Manually verify SWA setup.
Design sketch: go/bocaclient
Change-Id: Ie48c627599b8bd95c6f3b0b56701505fad5d5a1b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5531858
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Jason Zhang <jiajunz@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: April Zhou <aprilzhou@google.com>
Cr-Commit-Position: refs/heads/main@{#1301460}
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 640e0b0..11a1e22 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -440,6 +440,9 @@
"CheckPasswordsAgainstCryptohomeHelper",
base::FEATURE_DISABLED_BY_DEFAULT);
+// Enables or disables Boca feature on ChromeOS
+BASE_FEATURE(kBoca, "Boca", base::FEATURE_DISABLED_BY_DEFAULT);
+
// When enabled alongside the keyboard auto-repeat setting, holding down Ctrl+V
// will cause the clipboard history menu to show. From there, the user can
// select a clipboard history item to replace the initially pasted content.
@@ -1190,9 +1193,6 @@
"FloatingWorkspace",
base::FEATURE_DISABLED_BY_DEFAULT);
-// Enables or disables Floating Workspace feature on ChromeOS
-BASE_FEATURE(kClassHub, "ClassHub", base::FEATURE_DISABLED_BY_DEFAULT);
-
// Enables chrome.fileSystemProvider file systems in Files app Recents view.
BASE_FEATURE(kFSPsInRecents, "FSPsInRecents", base::FEATURE_ENABLED_BY_DEFAULT);
@@ -3333,6 +3333,10 @@
return base::FeatureList::IsEnabled(kCheckPasswordsAgainstCryptohomeHelper);
}
+bool IsBocaEnabled() {
+ return base::FeatureList::IsEnabled(kBoca);
+}
+
bool IsClipboardHistoryLongpressEnabled() {
return base::FeatureList::IsEnabled(kClipboardHistoryLongpress);
}
@@ -3578,10 +3582,6 @@
return base::FeatureList::IsEnabled(kFloatingWorkspaceV2);
}
-bool IsClassHubEnabled() {
- return base::FeatureList::IsEnabled(kClassHub);
-}
-
bool IsFocusModeEnabled() {
return base::FeatureList::IsEnabled(kFocusMode);
}
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 2e34211c9..1f51828 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -130,6 +130,7 @@
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCellularUseSecondEuicc);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kCheckPasswordsAgainstCryptohomeHelper);
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBoca);
COMPONENT_EXPORT(ASH_CONSTANTS)
BASE_DECLARE_FEATURE(kClipboardHistoryLongpress);
COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -368,7 +369,6 @@
BASE_DECLARE_FEATURE(kFirstPartyVietnameseInput);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kFlexAutoEnrollment);
COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kFloatingWorkspace);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kClassHub);
COMPONENT_EXPORT(ASH_CONSTANTS)
extern const base::FeatureParam<base::TimeDelta>
kFloatingWorkspaceMaxTimeAvailableForRestoreAfterLogin;
@@ -1055,7 +1055,7 @@
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFlexAutoEnrollmentEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFloatingWorkspaceEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFloatingWorkspaceV2Enabled();
-COMPONENT_EXPORT(ASH_CONSTANTS) bool isClassHubEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBocaEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFocusModeEnabled();
COMPONENT_EXPORT(ASH_CONSTANTS)
bool ShouldForceEnableServerSideSpeechRecognitionForDev();
diff --git a/ash/webui/boca_ui/BUILD.gn b/ash/webui/boca_ui/BUILD.gn
new file mode 100644
index 0000000..7bd2055
--- /dev/null
+++ b/ash/webui/boca_ui/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD - style license that can be
+# found in the LICENSE file.
+import("//build/config/chromeos/ui_mode.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/preprocess_if_expr.gni")
+import("//ui/webui/resources/tools/generate_grd.gni")
+
+assert(is_chromeos_ash, "Coba App is ash-chrome only")
+
+static_library("boca_ui") {
+ sources = [
+ "boca_ui.cc",
+ "boca_ui.h",
+ "url_constants.h",
+ ]
+ deps = [
+ "resources:resources",
+ "//ash/constants:constants",
+ "//ash/webui/common:chrome_os_webui_config",
+ "//ash/webui/system_apps/public:system_web_app_config",
+ "//content/public/browser",
+ "//ui/webui",
+ ]
+}
diff --git a/ash/webui/boca_ui/OWNERS b/ash/webui/boca_ui/OWNERS
new file mode 100644
index 0000000..b87ddfc
--- /dev/null
+++ b/ash/webui/boca_ui/OWNERS
@@ -0,0 +1,3 @@
+aprilzhou@google.com
+bzielinski@google.com
+vshenvi@google.com
diff --git a/ash/webui/boca_ui/boca_ui.cc b/ash/webui/boca_ui/boca_ui.cc
new file mode 100644
index 0000000..59da48b
--- /dev/null
+++ b/ash/webui/boca_ui/boca_ui.cc
@@ -0,0 +1,40 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/webui/boca_ui/boca_ui.h"
+
+#include "ash/constants/ash_features.h"
+#include "ash/webui/boca_ui/url_constants.h"
+#include "ash/webui/common/chrome_os_webui_config.h"
+#include "ash/webui/grit/ash_boca_ui_resources.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_controller.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace ash {
+
+bool BocaUIConfig::IsWebUIEnabled(content::BrowserContext* browser_context) {
+ return ash::features::IsBocaEnabled();
+}
+
+BocaUI::BocaUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui) {
+ auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
+ auto* html_source = content::WebUIDataSource::CreateAndAdd(
+ browser_context, ash::kChromeBocaAppHost);
+
+ html_source->AddResourcePath("index.html", IDR_ASH_BOCA_UI_INDEX_HTML);
+#if !DCHECK_IS_ON()
+ // If a user goes to an invalid url and non-DCHECK mode (DHECK = debug mode)
+ // is set, serve a default page so the user sees your default page instead
+ // of an unexpected error. But if DCHECK is set, the user will be a
+ // developer and be able to identify an error occurred.
+ html_source->SetDefaultResource(IDR_ASH_BOCA_UI_INDEX_HTML);
+#endif // !DCHECK_IS_ON()
+}
+
+BocaUI::~BocaUI() = default;
+
+WEB_UI_CONTROLLER_TYPE_IMPL(BocaUI)
+} // namespace ash
diff --git a/ash/webui/boca_ui/boca_ui.h b/ash/webui/boca_ui/boca_ui.h
new file mode 100644
index 0000000..39d41be
--- /dev/null
+++ b/ash/webui/boca_ui/boca_ui.h
@@ -0,0 +1,39 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_WEBUI_BOCA_UI_BOCA_UI_H_
+#define ASH_WEBUI_BOCA_UI_BOCA_UI_H_
+
+#include "ash/webui/boca_ui/url_constants.h"
+#include "ash/webui/common/chrome_os_webui_config.h"
+#include "ash/webui/system_apps/public/system_web_app_ui_config.h"
+#include "ui/webui/mojo_web_ui_controller.h"
+#include "ui/webui/untrusted_web_ui_controller.h"
+
+namespace ash {
+class BocaUI;
+
+// WebUI config for Boca SWA.
+class BocaUIConfig : public SystemWebAppUIConfig<BocaUI> {
+ public:
+ BocaUIConfig()
+ : SystemWebAppUIConfig(kChromeBocaAppHost, SystemWebAppType::BOCA) {}
+ bool IsWebUIEnabled(content::BrowserContext* browser_context) override;
+};
+
+// The WebUI for chrome://boca-app/.
+class BocaUI : public ui::MojoWebUIController {
+ public:
+ explicit BocaUI(content::WebUI* web_ui);
+ BocaUI(const BocaUI&) = delete;
+ BocaUI& operator=(const BocaUI&) = delete;
+ ~BocaUI() override;
+
+ private:
+ WEB_UI_CONTROLLER_TYPE_DECL();
+};
+
+} // namespace ash
+
+#endif // ASH_WEBUI_BOCA_UI_BOCA_UI_H_
diff --git a/ash/webui/boca_ui/resources/BUILD.gn b/ash/webui/boca_ui/resources/BUILD.gn
new file mode 100644
index 0000000..9b6e7b08
--- /dev/null
+++ b/ash/webui/boca_ui/resources/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD - style license that can be
+# found in the LICENSE file.
+
+import("//build/config/chromeos/ui_mode.gni")
+import("//ui/webui/resources/tools/build_webui.gni")
+
+assert(is_chromeos_ash)
+
+build_webui("build") {
+ grd_prefix = "ash_boca_ui"
+ static_files = [
+ "index.html",
+ "app_icon_120.png",
+ ]
+
+ # Files not holding a CustomElement element definition, or the CustomElement
+ # does not have a corresponding HTML template.
+ non_web_component_files = [ "index.ts" ]
+
+ ts_composite = true
+
+ grit_output_dir = "$root_gen_dir/ash/webui"
+}
diff --git a/ash/webui/boca_ui/resources/app_icon_120.png b/ash/webui/boca_ui/resources/app_icon_120.png
new file mode 100644
index 0000000..360c165
--- /dev/null
+++ b/ash/webui/boca_ui/resources/app_icon_120.png
Binary files differ
diff --git a/ash/webui/boca_ui/resources/index.html b/ash/webui/boca_ui/resources/index.html
new file mode 100644
index 0000000..1ee1251
--- /dev/null
+++ b/ash/webui/boca_ui/resources/index.html
@@ -0,0 +1,9 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<title>BocaUI</title>
+<h1 id="header">BocaUI</h1>
+</html>
diff --git a/ash/webui/boca_ui/resources/index.ts b/ash/webui/boca_ui/resources/index.ts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ash/webui/boca_ui/resources/index.ts
diff --git a/ash/webui/boca_ui/url_constants.h b/ash/webui/boca_ui/url_constants.h
new file mode 100644
index 0000000..51bf66b
--- /dev/null
+++ b/ash/webui/boca_ui/url_constants.h
@@ -0,0 +1,17 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_WEBUI_BOCA_UI_URL_CONSTANTS_H_
+#define ASH_WEBUI_BOCA_UI_URL_CONSTANTS_H_
+
+namespace ash {
+// Boca App Host.
+inline constexpr char kChromeBocaAppHost[] = "boca-app";
+// Boca App URL.
+inline constexpr char kChromeBocaAppURL[] = "chrome://boca-app/";
+// Boca App Index URL.
+inline constexpr char kChromeBocaAppIndexURL[] = "chrome://boca-app/index.html";
+} // namespace ash
+
+#endif // ASH_WEBUI_BOCA_UI_URL_CONSTANTS_H_
diff --git a/ash/webui/system_apps/public/system_web_app_type.h b/ash/webui/system_apps/public/system_web_app_type.h
index ee873060..42fe7ae 100644
--- a/ash/webui/system_apps/public/system_web_app_type.h
+++ b/ash/webui/system_apps/public/system_web_app_type.h
@@ -121,6 +121,11 @@
// Contact: cros-peripherals@google.com
PRINT_PREVIEW_CROS = 26,
+ // Boca implementation.
+ // Source: //ash/webui/boca_ui/
+ // Contact: cros-edu-eng@google.com
+ BOCA = 27,
+
// When adding a new System App, remember to:
//
// 1. Add a corresponding histogram suffix in WebAppSystemAppInternalName
@@ -160,7 +165,7 @@
//
// 8. Have one of System Web App Platform owners review the CL.
// See: //ash/webui/PLATFORM_OWNERS
- kMaxValue = PRINT_PREVIEW_CROS,
+ kMaxValue = BOCA,
};
} // namespace ash
diff --git a/chrome/browser/apps/app_service/policy_util.cc b/chrome/browser/apps/app_service/policy_util.cc
index 624ce98..e4de3c9 100644
--- a/chrome/browser/apps/app_service/policy_util.cc
+++ b/chrome/browser/apps/app_service/policy_util.cc
@@ -64,7 +64,8 @@
{"firmware_update", ash::SystemWebAppType::FIRMWARE_UPDATE},
{"os_flags", ash::SystemWebAppType::OS_FLAGS},
{"vc_background", ash::SystemWebAppType::VC_BACKGROUND},
- {"print_preview_cros", ash::SystemWebAppType::PRINT_PREVIEW_CROS}});
+ {"print_preview_cros", ash::SystemWebAppType::PRINT_PREVIEW_CROS},
+ {"boca", ash::SystemWebAppType::BOCA}});
constexpr ash::SystemWebAppType GetMaxSystemWebAppType() {
return base::ranges::max(kSystemWebAppsMapping, base::ranges::less{},
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 71ac3aa3..ebb8aba 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -3436,6 +3436,8 @@
"system_logs/virtual_keyboard_log_source.h",
"system_token_cert_db_initializer.cc",
"system_token_cert_db_initializer.h",
+ "system_web_apps/apps/boca_web_app_info.cc",
+ "system_web_apps/apps/boca_web_app_info.h",
"system_web_apps/apps/calculator_app/calculator_app_utils.cc",
"system_web_apps/apps/calculator_app/calculator_app_utils.h",
"system_web_apps/apps/camera_app/camera_app_survey_handler.cc",
@@ -3733,6 +3735,7 @@
"//ash/public/mojom:accelerator_info",
"//ash/public/mojom:hid_preserving_bluetooth_state_controller",
"//ash/quick_pair/common",
+ "//ash/webui/boca_ui",
"//ash/webui/camera_app_ui",
"//ash/webui/common/mojom:sea_pen",
"//ash/webui/connectivity_diagnostics",
@@ -4141,6 +4144,7 @@
"//ash/resources/vector_icons",
"//ash/strings",
"//ash/style",
+ "//ash/webui/boca_ui/resources",
"//ash/webui/camera_app_ui:document_scanning",
"//ash/webui/camera_app_ui:ocr",
"//ash/webui/camera_app_ui/resources/strings",
diff --git a/chrome/browser/ash/system_web_apps/apps/BUILD.gn b/chrome/browser/ash/system_web_apps/apps/BUILD.gn
index 3ef0d20..9e88153 100644
--- a/chrome/browser/ash/system_web_apps/apps/BUILD.gn
+++ b/chrome/browser/ash/system_web_apps/apps/BUILD.gn
@@ -39,6 +39,7 @@
}
deps = [
+ "//ash/webui/boca_ui",
"//ash/webui/demo_mode_app_ui",
"//ash/webui/diagnostics_ui",
"//ash/webui/firmware_update_ui",
diff --git a/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.cc b/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.cc
new file mode 100644
index 0000000..2fa4845b
--- /dev/null
+++ b/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.cc
@@ -0,0 +1,53 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/system_web_apps/apps/boca_web_app_info.h"
+
+#include "ash/constants/ash_features.h"
+#include "ash/webui/boca_ui/url_constants.h"
+#include "ash/webui/grit/ash_boca_ui_resources.h"
+#include "chrome/browser/ash/system_web_apps/apps/system_web_app_install_utils.h"
+#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chromeos/constants/chromeos_features.h"
+
+std::unique_ptr<web_app::WebAppInstallInfo> CreateWebAppInfoForBocaApp() {
+ std::unique_ptr<web_app::WebAppInstallInfo> info =
+ std::make_unique<web_app::WebAppInstallInfo>();
+ info->start_url = GURL(ash::kChromeBocaAppIndexURL);
+ info->scope = GURL(ash::kChromeBocaAppIndexURL);
+ // TODO(aprilzhou): Convert the title to a localized string
+ info->title = u"BOCA";
+ web_app::CreateIconInfoForSystemWebApp(
+ info->start_url,
+ {{"app_icon_120.png", 120, IDR_ASH_BOCA_UI_APP_ICON_120_PNG}}, *info);
+ info->theme_color =
+ web_app::GetDefaultBackgroundColor(/*use_dark_mode=*/false);
+ info->dark_mode_theme_color =
+ web_app::GetDefaultBackgroundColor(/*use_dark_mode=*/true);
+ info->background_color = info->theme_color;
+ info->display_mode = blink::mojom::DisplayMode::kStandalone;
+ info->user_display_mode = web_app::mojom::UserDisplayMode::kStandalone;
+
+ return info;
+}
+
+BocaSystemAppDelegate::BocaSystemAppDelegate(Profile* profile)
+ : ash::SystemWebAppDelegate(ash::SystemWebAppType::BOCA,
+ "Boca",
+ GURL(ash::kChromeBocaAppURL),
+ profile) {}
+
+std::unique_ptr<web_app::WebAppInstallInfo>
+BocaSystemAppDelegate::GetWebAppInfo() const {
+ return CreateWebAppInfoForBocaApp();
+}
+
+bool BocaSystemAppDelegate::ShouldCaptureNavigations() const {
+ return true;
+}
+
+bool BocaSystemAppDelegate::IsAppEnabled() const {
+ return ash::features::IsBocaEnabled();
+}
diff --git a/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.h b/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.h
new file mode 100644
index 0000000..128bd11
--- /dev/null
+++ b/chrome/browser/ash/system_web_apps/apps/boca_web_app_info.h
@@ -0,0 +1,27 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_APPS_BOCA_WEB_APP_INFO_H_
+#define CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_APPS_BOCA_WEB_APP_INFO_H_
+
+#include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h"
+
+namespace web_app {
+struct WebAppInstallInfo;
+} // namespace web_app
+
+// For Boca SWA.
+class BocaSystemAppDelegate : public ash::SystemWebAppDelegate {
+ public:
+ explicit BocaSystemAppDelegate(Profile* profile);
+
+ // ash::SystemWebAppDelegate overrides:
+ std::unique_ptr<web_app::WebAppInstallInfo> GetWebAppInfo() const override;
+ bool ShouldCaptureNavigations() const override;
+ bool IsAppEnabled() const override;
+};
+
+std::unique_ptr<web_app::WebAppInstallInfo> CreateWebAppInfoForBocaApp();
+
+#endif // CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_APPS_BOCA_WEB_APP_INFO_H_
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
index 907dd2c..bb852c4 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager.cc
@@ -39,6 +39,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/version.h"
+#include "chrome/browser/ash/system_web_apps/apps/boca_web_app_info.h"
#include "chrome/browser/ash/system_web_apps/apps/camera_app/camera_system_web_app_info.h"
#include "chrome/browser/ash/system_web_apps/apps/connectivity_diagnostics_system_web_app_info.h"
#include "chrome/browser/ash/system_web_apps/apps/crosh_system_web_app_info.h"
@@ -141,6 +142,9 @@
std::make_unique<vc_background_ui::VcBackgroundUISystemAppDelegate>(
profile));
info_vec.push_back(std::make_unique<PrintPreviewCrosDelegate>(profile));
+ if (features::IsBocaEnabled()) {
+ info_vec.push_back(std::make_unique<BocaSystemAppDelegate>(profile));
+ }
#if !defined(OFFICIAL_BUILD)
info_vec.push_back(std::make_unique<SampleSystemAppDelegate>(profile));
diff --git a/chrome/browser/ash/system_web_apps/types/proto/system_web_app_data.proto b/chrome/browser/ash/system_web_apps/types/proto/system_web_app_data.proto
index e233d6f..a0759a7 100644
--- a/chrome/browser/ash/system_web_apps/types/proto/system_web_app_data.proto
+++ b/chrome/browser/ash/system_web_apps/types/proto/system_web_app_data.proto
@@ -37,6 +37,7 @@
FACE_ML = 24;
VC_BACKGROUND = 25;
PRINT_PREVIEW_CROS = 26;
+ BOCA = 27;
};
optional SystemWebAppType system_app_type = 1;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 5fa8e0e..6ce36603 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3781,6 +3781,7 @@
"//ash/quick_pair/repository",
"//ash/quick_pair/ui",
"//ash/style:style",
+ "//ash/webui/boca_ui",
"//ash/webui/camera_app_ui",
"//ash/webui/color_internals",
"//ash/webui/common:chrome_os_webui_config",
diff --git a/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc b/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
index c0edaedd..d66ab17 100644
--- a/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
+++ b/chrome/browser/ui/webui/ash/chrome_web_ui_configs_chromeos.cc
@@ -17,6 +17,7 @@
#include "chrome/browser/app_mode/app_mode_utils.h" // nogncheck
#include "chrome/browser/feedback/feedback_dialog_utils.h" // nogncheck
+#include "ash/webui/boca_ui/boca_ui.h"
#include "ash/webui/camera_app_ui/camera_app_ui.h"
#include "ash/webui/color_internals/color_internals_ui.h"
#include "ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.h"
@@ -221,6 +222,7 @@
map.AddWebUIConfig(std::make_unique<AssistantOptInUIConfig>());
map.AddWebUIConfig(std::make_unique<AudioUIConfig>());
map.AddWebUIConfig(std::make_unique<BluetoothPairingDialogUIConfig>());
+ map.AddWebUIConfig(std::make_unique<BocaUIConfig>());
map.AddWebUIConfig(std::make_unique<BorealisInstallerUIConfig>());
map.AddWebUIConfig(std::make_unique<CertificateManagerDialogUIConfig>());
map.AddWebUIConfig(std::make_unique<cloud_upload::CloudUploadUIConfig>());
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 87e4b16..81bbfbf 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -234,6 +234,7 @@
"$root_gen_dir/ash/public/cpp/resources/ash_public_unscaled_resources.pak",
"$root_gen_dir/ash/system/mahi/resources/mahi_resources.pak",
"$root_gen_dir/ash/system/video_conference/resources/vc_resources.pak",
+ "$root_gen_dir/ash/webui/ash_boca_ui_resources.pak",
"$root_gen_dir/ash/webui/ash_camera_app_resources.pak",
"$root_gen_dir/ash/webui/ash_color_internals_resources.pak",
"$root_gen_dir/ash/webui/ash_demo_mode_app_resources.pak",
@@ -318,6 +319,7 @@
"//ash/public/cpp/resources:ash_public_unscaled_resources",
"//ash/system/mahi/resources:mahi_resources",
"//ash/system/video_conference/resources:vc_resources",
+ "//ash/webui/boca_ui/resources:resources",
"//ash/webui/color_internals/resources:resources",
"//ash/webui/common/resources:resources",
"//ash/webui/common/resources/office_fallback:resources",
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index f3ca54d7..ff0b789 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -777,6 +777,10 @@
"chromeos/ash/resources/internal/ash_internal_strings.grd": {
"messages": [5780],
},
+ "<(SHARED_INTERMEDIATE_DIR)/ash/webui/boca_ui/resources/resources.grd": {
+ "META": {"sizes": {"includes": [50],}},
+ "includes": [5790],
+ },
"<(SHARED_INTERMEDIATE_DIR)/ash/webui/camera_app_ui/ash_camera_app_resources.grd": {
"META": {"sizes": {"includes": [300],}},
"includes": [5800],
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index f615670a..471b94b9d89 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -4541,6 +4541,7 @@
</histogram_suffixes>
<histogram_suffixes name="WebAppSystemAppInternalName" separator=".">
+ <suffix name="Boca" label="Boca"/>
<suffix name="Camera" label="Camera"/>
<suffix name="ConnectivityDiagnostics" label="Connectivity Diagnostics"/>
<suffix name="Crosh" label="Crosh"/>