[Extensions] Make extensions/common:common_constants component-friendly

The //extensions layer is currently not component-friendly - it is a
bunch of targets with source_sets, which means that if components depend
on these targets, they are pulled in multiple times. Among other things,
this is very bad for singletons (which are no longer singletons).

A number of //components depend on //extensions; however, all but
//components/sessions only appear to depend on the
//extensions/common:common_constants target.

Make //extensions/common:common_constants a component-friendly target
and introduce a top-level //extensions component target (which currently
only includes //extensions/common:common_constants). This allows
//components to depend on this target, and gives us a component that we
can slowly add items to to make the //extensions layer itself a full
component.

Bug: 1286881
Change-Id: I7d90aa119c5d7611a0311150b3c034159c37ec3b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3380398
Reviewed-by: Leonard Grey <[email protected]>
Reviewed-by: Elly Fong-Jones <[email protected]>
Commit-Queue: Devlin Cronin <[email protected]>
Cr-Commit-Position: refs/heads/main@{#960670}
diff --git a/extensions/BUILD.gn b/extensions/BUILD.gn
index 0a884d1..53ddd25 100644
--- a/extensions/BUILD.gn
+++ b/extensions/BUILD.gn
@@ -9,391 +9,414 @@
 import("//tools/grit/repack.gni")
 import("//ui/base/ui_features.gni")
 
-assert(enable_extensions)
 assert(
     !(enable_autofill_assistant_api && is_official_build),
     "The AutofillAssistant Extension API must be disabled in official builds.")
 
-group("extensions_resources") {
-  public_deps = [
-    ":extensions_browser_resources",
-    ":extensions_renderer_resources",
-    ":extensions_resources_grd",
-  ]
-}
-
-grit("extensions_resources_grd") {
-  source = "extensions_resources.grd"
-  outputs = [
-    "grit/extensions_resources.h",
-    "extensions_resources.pak",
-  ]
-}
-
-grit("extensions_browser_resources") {
-  source = "browser/resources/extensions_browser_resources.grd"
-  outputs = [
-    "grit/extensions_browser_resources.h",
-    "grit/extensions_browser_resources_map.cc",
-    "grit/extensions_browser_resources_map.h",
-    "extensions_browser_resources_100_percent.pak",
-    "extensions_browser_resources_200_percent.pak",
-  ]
-}
-
-grit("extensions_renderer_resources") {
-  source = "renderer/resources/extensions_renderer_resources.grd"
-  defines = [ "is_chromecast=$is_chromecast" ]
-  outputs = [
-    "grit/extensions_renderer_resources.h",
-    "extensions_renderer_resources.pak",
-  ]
-  grit_flags = [
-    "-E",
-    "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
-  ]
-
-  deps = [
-    "//extensions/common:mojom_js",
-    "//extensions/common/api:mojom_js",
-    "//services/device/public/mojom:mojom_js",
-  ]
-}
-
-static_library("test_support") {
-  testonly = true
-  sources = [
-    "browser/api/declarative/test_rules_registry.cc",
-    "browser/api/declarative/test_rules_registry.h",
-    "browser/api/storage/settings_test_util.cc",
-    "browser/api/storage/settings_test_util.h",
-    "browser/api_test_utils.cc",
-    "browser/api_test_utils.h",
-    "browser/api_unittest.cc",
-    "browser/api_unittest.h",
-    "browser/app_window/test_app_window_contents.cc",
-    "browser/app_window/test_app_window_contents.h",
-    "browser/content_verifier/test_utils.cc",
-    "browser/content_verifier/test_utils.h",
-    "browser/extension_error_test_util.cc",
-    "browser/extension_error_test_util.h",
-    "browser/extensions_test.cc",
-    "browser/extensions_test.h",
-    "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.cc",
-    "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h",
-    "browser/mock_extension_system.cc",
-    "browser/mock_extension_system.h",
-    "browser/mock_external_provider.cc",
-    "browser/mock_external_provider.h",
-    "browser/scoped_ignore_content_verifier_for_test.cc",
-    "browser/scoped_ignore_content_verifier_for_test.h",
-    "browser/test_event_router.cc",
-    "browser/test_event_router.h",
-    "browser/test_extension_registry_observer.cc",
-    "browser/test_extension_registry_observer.h",
-    "browser/test_extensions_browser_client.cc",
-    "browser/test_extensions_browser_client.h",
-    "browser/test_image_loader.cc",
-    "browser/test_image_loader.h",
-    "browser/test_management_policy.cc",
-    "browser/test_management_policy.h",
-    "browser/test_runtime_api_delegate.cc",
-    "browser/test_runtime_api_delegate.h",
-    "common/extension_builder.cc",
-    "common/extension_builder.h",
-    "common/manifest_test.cc",
-    "common/manifest_test.h",
-    "common/permissions/mock_manifest_permission.cc",
-    "common/permissions/mock_manifest_permission.h",
-    "common/permissions/permission_message_test_util.cc",
-    "common/permissions/permission_message_test_util.h",
-    "common/scoped_testing_manifest_handler_registry.cc",
-    "common/scoped_testing_manifest_handler_registry.h",
-    "renderer/test_extensions_renderer_client.cc",
-    "renderer/test_extensions_renderer_client.h",
-    "test/extension_background_page_waiter.cc",
-    "test/extension_background_page_waiter.h",
-    "test/extension_state_tester.cc",
-    "test/extension_state_tester.h",
-    "test/extension_test_message_listener.cc",
-    "test/extension_test_message_listener.h",
-    "test/extension_test_notification_observer.cc",
-    "test/extension_test_notification_observer.h",
-    "test/logging_timer.cc",
-    "test/logging_timer.h",
-    "test/result_catcher.cc",
-    "test/result_catcher.h",
-    "test/test_content_script_load_waiter.cc",
-    "test/test_content_script_load_waiter.h",
-    "test/test_content_utility_client.cc",
-    "test/test_content_utility_client.h",
-    "test/test_extension_dir.cc",
-    "test/test_extension_dir.h",
-    "test/test_extensions_client.cc",
-    "test/test_extensions_client.h",
-    "test/test_permission_message_provider.cc",
-    "test/test_permission_message_provider.h",
-  ]
-
-  deps = [
-    ":extensions_resources",
-    "//base",
-    "//build:chromeos_buildflags",
-    "//chrome/common:buildflags",
-    "//components/crx_file",
-    "//components/guest_view/browser:test_support",
-    "//components/keyed_service/content",
-    "//components/pref_registry",
-    "//components/prefs:test_support",
-    "//components/sync_preferences:test_support",
-    "//components/update_client",
-    "//components/user_prefs",
-    "//content/public/common",
-    "//content/test:test_support",
-    "//extensions/browser",
-    "//extensions/browser:test_support",
-    "//extensions/browser/api",
-    "//extensions/browser/updater",
-    "//extensions/common",
-    "//extensions/common:core_api_provider",
-    "//extensions/common/api",
-    "//extensions/common/api:extensions_features",
-    "//extensions/renderer",
-    "//net:test_support",
-    "//services/network/public/mojom",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//third_party/cld_3/src/src:cld_3",
-    "//third_party/zlib/google:zip",
-  ]
-
-  # Generally, //extensions should not depend on //chromeos. However, a number
-  # of the APIs and the extensions shell already do. We should try to avoid
-  # expanding these dependencies.
-  if (is_chromeos_ash) {
-    deps += [ "//chromeos/login/login_state" ]
-  }
-
-  if (is_chromeos_lacros) {
-    deps += [ "//chromeos/lacros:test_support" ]
-  }
-
-  public_deps = [ "//content/public/browser" ]
-}
-
-repack("shell_and_test_pak") {
-  testonly = true
-
-  sources = [
-    "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
-    "$root_gen_dir/content/content_resources.pak",
-    "$root_gen_dir/content/dev_ui_content_resources.pak",
-    "$root_gen_dir/content/shell/shell_resources.pak",
-    "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak",
-    "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak",
-    "$root_gen_dir/extensions/extensions_renderer_resources.pak",
-    "$root_gen_dir/extensions/extensions_resources.pak",
-    "$root_gen_dir/extensions/shell/app_shell_resources.pak",
-    "$root_gen_dir/extensions/strings/extensions_strings_en-US.pak",
-    "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
-    "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
-    "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
-    "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
-    "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
-    "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
-    "$root_gen_dir/ui/strings/ax_strings_en-US.pak",
-    "$root_gen_dir/ui/strings/ui_strings_en-US.pak",
-  ]
-
-  output = "$root_out_dir/extensions_shell_and_test.pak"
-
-  deps = [
-    ":extensions_resources",
-    "//content:content_resources",
-    "//content:dev_ui_content_resources",
-    "//content/browser/devtools:devtools_resources",
-    "//content/shell:resources",
-    "//device/bluetooth/strings",
-    "//extensions/shell:resources",
-    "//extensions/strings",
-    "//mojo/public/js:resources",
-    "//third_party/blink/public:resources",
-    "//third_party/blink/public:scaled_resources_100_percent",
-    "//third_party/blink/public/strings",
-    "//ui/resources",
-    "//ui/strings",
-  ]
-}
-
-test("extensions_unittests") {
-  use_xvfb = use_xvfb_in_this_config
-
-  sources = [
-    "test/extensions_unittests_main.cc",
-    "test/logging_timer_unittest.cc",
-  ]
-
-  data = [
-    "test/data/",
-    "//chrome/test/data/extensions/",
-    "//components/test/data/cast_certificate/",
-    "$root_out_dir/content_shell.pak",
-    "$root_out_dir/extensions_shell_and_test.pak",
-  ]
-
-  deps = [
-    ":extensions_resources",
-    ":shell_and_test_pak",
-    ":test_support",
-    "//base/test:test_support",
-    "//content/public/common",
-    "//content/test:test_support",
-    "//extensions/browser:unit_tests",
-    "//extensions/common",
-    "//extensions/common:unit_tests",
-    "//extensions/renderer:unit_tests",
-    "//extensions/shell:unit_tests",
-    "//services/data_decoder:lib",
-    "//services/service_manager/public/cpp/test:test_support",
-    "//ui/gl:test_support",
-  ]
-
-  data_deps = [ "//third_party/mesa_headers" ]
-
-  if (is_fuchsia) {
-    additional_manifest_fragments = [
-      "//build/config/fuchsia/test/jit_capabilities.test-cmx",
-      "//build/config/fuchsia/test/network_capabilities.test-cmx",
+if (is_component_build) {
+  component("extensions") {
+    visibility = [
+      "//extensions/common:common_constants",
+      "//extensions/common:export",
+    ]
+    public_deps = [
+      "//extensions/common:constants_impl",
+      "//extensions/common:export_impl",
     ]
   }
 }
 
-test("extensions_browsertests") {
-  use_xvfb = use_xvfb_in_this_config
-
-  data = [
-    "//extensions/test/data/",
-    "//net/tools/testserver/",
-    "//third_party/pywebsocket3/src/mod_pywebsocket/",
-    "$root_out_dir/extensions_shell_and_test.pak",
-  ]
-
-  deps = [
-    "//extensions/browser:browser_tests",
-    "//extensions/shell:browser_tests",
-  ]
-
-  data_deps = [ "//third_party/mesa_headers" ]
+# Used by targets that compile into the implementation.
+config("component_implementation") {
+  defines = [ "EXTENSIONS_COMPONENT_IMPLEMENTATION" ]
 }
 
-# TODO(rockot) bug 505926: These should be moved to extensions_browsertests but have
-# old dependencies on chrome files. The chrome dependencies should be removed
-# and these moved to the extensions_browsertests target. Currently, we solve
-# the problem by making this a source set and linking it into
-# //chrome/test:browser_tests.
-source_set("chrome_extensions_browsertests") {
-  testonly = true
-  sources = [
-    "browser/api/app_window/app_window_apitest.cc",
-    "browser/api/bluetooth/bluetooth_apitest.cc",
-    "browser/api/bluetooth/bluetooth_private_apitest.cc",
-    "browser/api/serial/serial_apitest.cc",
-    "browser/api/usb/usb_manual_apitest.cc",
-    "browser/app_window/app_window_browsertest.cc",
-    "browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc",
-    "renderer/script_context_browsertest.cc",
-  ]
-
-  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
-
-  # These are the deps from browser_tests minus some internal Chrome ones that
-  # aren't allowed to be included here and that aren't needed.
-  deps = [
-    "//base",
-    "//base:i18n",
-    "//base/test:test_support",
-    "//build:chromeos_buildflags",
-    "//chrome/browser",
-    "//chrome/common/extensions/api",
-    "//chrome/renderer",
-    "//chrome/test:test_support",
-    "//components/autofill/content/browser:risk_proto",
-    "//components/autofill/content/renderer:test_support",
-    "//components/captive_portal/core:test_support",
-    "//components/dom_distiller/content/browser",
-    "//components/dom_distiller/core:test_support",
-    "//components/guest_view/browser:test_support",
-    "//components/javascript_dialogs",
-    "//components/resources",
-    "//components/strings",
-    "//components/sync",
-    "//components/sync:test_support_model",
-    "//components/translate/core/common",
-    "//crypto:platform",
-    "//crypto:test_support",
-    "//device/bluetooth:mocks",
-    "//extensions/browser/api/bluetooth",
-    "//extensions/common/api",
-    "//extensions/renderer",
-    "//google_apis:test_support",
-    "//media:test_support",
-    "//net",
-    "//net:test_support",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//testing/perf",
-    "//third_party/blink/public:blink",
-    "//third_party/icu",
-    "//third_party/leveldatabase",
-    "//third_party/libaddressinput",
-    "//third_party/webrtc_overrides:webrtc_component",
-    "//third_party/widevine/cdm:headers",
-    "//ui/accessibility:test_support",
-    "//ui/base:test_support",
-    "//ui/compositor:test_support",
-    "//ui/resources",
-    "//ui/web_dialogs:test_support",
-    "//v8",
-  ]
-
-  if (is_chromeos_ash) {
-    deps += [ "//components/user_manager:test_support" ]
+# TODO(crbug.com/731689): Assert that extensions are enabled.
+# We can't do this here directly because some platforms where extensions aren't
+# enabled depend on //extensions/common:common_constants, which in turn depends
+# on the //extensions component target in component builds.
+if (enable_extensions) {
+  group("extensions_resources") {
+    public_deps = [
+      ":extensions_browser_resources",
+      ":extensions_renderer_resources",
+      ":extensions_resources_grd",
+    ]
   }
-}
 
-# TODO(rockot) bug 505926: This should be deleted for the same reason as
-# chrome_extensions_browsertests.
-source_set("chrome_extensions_interactive_uitests") {
-  testonly = true
-  sources = [ "browser/guest_view/mime_handler_view/mime_handler_view_interactive_uitest.cc" ]
+  grit("extensions_resources_grd") {
+    source = "extensions_resources.grd"
+    outputs = [
+      "grit/extensions_resources.h",
+      "extensions_resources.pak",
+    ]
+  }
 
-  defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+  grit("extensions_browser_resources") {
+    source = "browser/resources/extensions_browser_resources.grd"
+    outputs = [
+      "grit/extensions_browser_resources.h",
+      "grit/extensions_browser_resources_map.cc",
+      "grit/extensions_browser_resources_map.h",
+      "extensions_browser_resources_100_percent.pak",
+      "extensions_browser_resources_200_percent.pak",
+    ]
+  }
 
-  # These are the deps from interactive_uitests minus some internal Chrome
-  # ones that aren't allowed to be included here and that aren't needed.
-  deps = [
-    "//chrome/browser",
-    "//chrome/browser/devtools",
-    "//chrome/renderer",
-    "//chrome/test:test_support",
-    "//components/sync",
-    "//content/app/resources",
-    "//crypto:platform",
-    "//crypto:test_support",
-    "//google_apis:test_support",
-    "//net",
-    "//net:net_resources",
-    "//net:test_support",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//third_party/hunspell",
-    "//third_party/icu",
-    "//third_party/libpng",
-    "//third_party/zlib",
-    "//ui/base:test_support",
-    "//ui/resources:ui_test_pak",
-    "//ui/web_dialogs:test_support",
-  ]
+  grit("extensions_renderer_resources") {
+    source = "renderer/resources/extensions_renderer_resources.grd"
+    defines = [ "is_chromecast=$is_chromecast" ]
+    outputs = [
+      "grit/extensions_renderer_resources.h",
+      "extensions_renderer_resources.pak",
+    ]
+    grit_flags = [
+      "-E",
+      "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
+    ]
+
+    deps = [
+      "//extensions/common:mojom_js",
+      "//extensions/common/api:mojom_js",
+      "//services/device/public/mojom:mojom_js",
+    ]
+  }
+
+  static_library("test_support") {
+    testonly = true
+    sources = [
+      "browser/api/declarative/test_rules_registry.cc",
+      "browser/api/declarative/test_rules_registry.h",
+      "browser/api/storage/settings_test_util.cc",
+      "browser/api/storage/settings_test_util.h",
+      "browser/api_test_utils.cc",
+      "browser/api_test_utils.h",
+      "browser/api_unittest.cc",
+      "browser/api_unittest.h",
+      "browser/app_window/test_app_window_contents.cc",
+      "browser/app_window/test_app_window_contents.h",
+      "browser/content_verifier/test_utils.cc",
+      "browser/content_verifier/test_utils.h",
+      "browser/extension_error_test_util.cc",
+      "browser/extension_error_test_util.h",
+      "browser/extensions_test.cc",
+      "browser/extensions_test.h",
+      "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.cc",
+      "browser/guest_view/mime_handler_view/test_mime_handler_view_guest.h",
+      "browser/mock_extension_system.cc",
+      "browser/mock_extension_system.h",
+      "browser/mock_external_provider.cc",
+      "browser/mock_external_provider.h",
+      "browser/scoped_ignore_content_verifier_for_test.cc",
+      "browser/scoped_ignore_content_verifier_for_test.h",
+      "browser/test_event_router.cc",
+      "browser/test_event_router.h",
+      "browser/test_extension_registry_observer.cc",
+      "browser/test_extension_registry_observer.h",
+      "browser/test_extensions_browser_client.cc",
+      "browser/test_extensions_browser_client.h",
+      "browser/test_image_loader.cc",
+      "browser/test_image_loader.h",
+      "browser/test_management_policy.cc",
+      "browser/test_management_policy.h",
+      "browser/test_runtime_api_delegate.cc",
+      "browser/test_runtime_api_delegate.h",
+      "common/extension_builder.cc",
+      "common/extension_builder.h",
+      "common/manifest_test.cc",
+      "common/manifest_test.h",
+      "common/permissions/mock_manifest_permission.cc",
+      "common/permissions/mock_manifest_permission.h",
+      "common/permissions/permission_message_test_util.cc",
+      "common/permissions/permission_message_test_util.h",
+      "common/scoped_testing_manifest_handler_registry.cc",
+      "common/scoped_testing_manifest_handler_registry.h",
+      "renderer/test_extensions_renderer_client.cc",
+      "renderer/test_extensions_renderer_client.h",
+      "test/extension_background_page_waiter.cc",
+      "test/extension_background_page_waiter.h",
+      "test/extension_state_tester.cc",
+      "test/extension_state_tester.h",
+      "test/extension_test_message_listener.cc",
+      "test/extension_test_message_listener.h",
+      "test/extension_test_notification_observer.cc",
+      "test/extension_test_notification_observer.h",
+      "test/logging_timer.cc",
+      "test/logging_timer.h",
+      "test/result_catcher.cc",
+      "test/result_catcher.h",
+      "test/test_content_script_load_waiter.cc",
+      "test/test_content_script_load_waiter.h",
+      "test/test_content_utility_client.cc",
+      "test/test_content_utility_client.h",
+      "test/test_extension_dir.cc",
+      "test/test_extension_dir.h",
+      "test/test_extensions_client.cc",
+      "test/test_extensions_client.h",
+      "test/test_permission_message_provider.cc",
+      "test/test_permission_message_provider.h",
+    ]
+
+    deps = [
+      ":extensions_resources",
+      "//base",
+      "//build:chromeos_buildflags",
+      "//chrome/common:buildflags",
+      "//components/crx_file",
+      "//components/guest_view/browser:test_support",
+      "//components/keyed_service/content",
+      "//components/pref_registry",
+      "//components/prefs:test_support",
+      "//components/sync_preferences:test_support",
+      "//components/update_client",
+      "//components/user_prefs",
+      "//content/public/common",
+      "//content/test:test_support",
+      "//extensions/browser",
+      "//extensions/browser:test_support",
+      "//extensions/browser/api",
+      "//extensions/browser/updater",
+      "//extensions/common",
+      "//extensions/common:core_api_provider",
+      "//extensions/common/api",
+      "//extensions/common/api:extensions_features",
+      "//extensions/renderer",
+      "//net:test_support",
+      "//services/network/public/mojom",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//third_party/cld_3/src/src:cld_3",
+      "//third_party/zlib/google:zip",
+    ]
+
+    # Generally, //extensions should not depend on //chromeos. However, a number
+    # of the APIs and the extensions shell already do. We should try to avoid
+    # expanding these dependencies.
+    if (is_chromeos_ash) {
+      deps += [ "//chromeos/login/login_state" ]
+    }
+
+    if (is_chromeos_lacros) {
+      deps += [ "//chromeos/lacros:test_support" ]
+    }
+
+    public_deps = [ "//content/public/browser" ]
+  }
+
+  repack("shell_and_test_pak") {
+    testonly = true
+
+    sources = [
+      "$root_gen_dir/content/browser/devtools/devtools_resources.pak",
+      "$root_gen_dir/content/content_resources.pak",
+      "$root_gen_dir/content/dev_ui_content_resources.pak",
+      "$root_gen_dir/content/shell/shell_resources.pak",
+      "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak",
+      "$root_gen_dir/extensions/extensions_browser_resources_100_percent.pak",
+      "$root_gen_dir/extensions/extensions_renderer_resources.pak",
+      "$root_gen_dir/extensions/extensions_resources.pak",
+      "$root_gen_dir/extensions/shell/app_shell_resources.pak",
+      "$root_gen_dir/extensions/strings/extensions_strings_en-US.pak",
+      "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
+      "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
+      "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
+      "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
+      "$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
+      "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
+      "$root_gen_dir/ui/strings/ax_strings_en-US.pak",
+      "$root_gen_dir/ui/strings/ui_strings_en-US.pak",
+    ]
+
+    output = "$root_out_dir/extensions_shell_and_test.pak"
+
+    deps = [
+      ":extensions_resources",
+      "//content:content_resources",
+      "//content:dev_ui_content_resources",
+      "//content/browser/devtools:devtools_resources",
+      "//content/shell:resources",
+      "//device/bluetooth/strings",
+      "//extensions/shell:resources",
+      "//extensions/strings",
+      "//mojo/public/js:resources",
+      "//third_party/blink/public:resources",
+      "//third_party/blink/public:scaled_resources_100_percent",
+      "//third_party/blink/public/strings",
+      "//ui/resources",
+      "//ui/strings",
+    ]
+  }
+
+  test("extensions_unittests") {
+    use_xvfb = use_xvfb_in_this_config
+
+    sources = [
+      "test/extensions_unittests_main.cc",
+      "test/logging_timer_unittest.cc",
+    ]
+
+    data = [
+      "test/data/",
+      "//chrome/test/data/extensions/",
+      "//components/test/data/cast_certificate/",
+      "$root_out_dir/content_shell.pak",
+      "$root_out_dir/extensions_shell_and_test.pak",
+    ]
+
+    deps = [
+      ":extensions_resources",
+      ":shell_and_test_pak",
+      ":test_support",
+      "//base/test:test_support",
+      "//content/public/common",
+      "//content/test:test_support",
+      "//extensions/browser:unit_tests",
+      "//extensions/common",
+      "//extensions/common:unit_tests",
+      "//extensions/renderer:unit_tests",
+      "//extensions/shell:unit_tests",
+      "//services/data_decoder:lib",
+      "//services/service_manager/public/cpp/test:test_support",
+      "//ui/gl:test_support",
+    ]
+
+    data_deps = [ "//third_party/mesa_headers" ]
+
+    if (is_fuchsia) {
+      additional_manifest_fragments = [
+        "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+        "//build/config/fuchsia/test/network_capabilities.test-cmx",
+      ]
+    }
+  }
+
+  test("extensions_browsertests") {
+    use_xvfb = use_xvfb_in_this_config
+
+    data = [
+      "//extensions/test/data/",
+      "//net/tools/testserver/",
+      "//third_party/pywebsocket3/src/mod_pywebsocket/",
+      "$root_out_dir/extensions_shell_and_test.pak",
+    ]
+
+    deps = [
+      "//extensions/browser:browser_tests",
+      "//extensions/shell:browser_tests",
+    ]
+
+    data_deps = [ "//third_party/mesa_headers" ]
+  }
+
+  # TODO(rockot) bug 505926: These should be moved to extensions_browsertests but have
+  # old dependencies on chrome files. The chrome dependencies should be removed
+  # and these moved to the extensions_browsertests target. Currently, we solve
+  # the problem by making this a source set and linking it into
+  # //chrome/test:browser_tests.
+  source_set("chrome_extensions_browsertests") {
+    testonly = true
+    sources = [
+      "browser/api/app_window/app_window_apitest.cc",
+      "browser/api/bluetooth/bluetooth_apitest.cc",
+      "browser/api/bluetooth/bluetooth_private_apitest.cc",
+      "browser/api/serial/serial_apitest.cc",
+      "browser/api/usb/usb_manual_apitest.cc",
+      "browser/app_window/app_window_browsertest.cc",
+      "browser/guest_view/mime_handler_view/mime_handler_view_browsertest.cc",
+      "renderer/script_context_browsertest.cc",
+    ]
+
+    defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+
+    # These are the deps from browser_tests minus some internal Chrome ones that
+    # aren't allowed to be included here and that aren't needed.
+    deps = [
+      "//base",
+      "//base:i18n",
+      "//base/test:test_support",
+      "//build:chromeos_buildflags",
+      "//chrome/browser",
+      "//chrome/common/extensions/api",
+      "//chrome/renderer",
+      "//chrome/test:test_support",
+      "//components/autofill/content/browser:risk_proto",
+      "//components/autofill/content/renderer:test_support",
+      "//components/captive_portal/core:test_support",
+      "//components/dom_distiller/content/browser",
+      "//components/dom_distiller/core:test_support",
+      "//components/guest_view/browser:test_support",
+      "//components/javascript_dialogs",
+      "//components/resources",
+      "//components/strings",
+      "//components/sync",
+      "//components/sync:test_support_model",
+      "//components/translate/core/common",
+      "//crypto:platform",
+      "//crypto:test_support",
+      "//device/bluetooth:mocks",
+      "//extensions/browser/api/bluetooth",
+      "//extensions/common/api",
+      "//extensions/renderer",
+      "//google_apis:test_support",
+      "//media:test_support",
+      "//net",
+      "//net:test_support",
+      "//skia",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//testing/perf",
+      "//third_party/blink/public:blink",
+      "//third_party/icu",
+      "//third_party/leveldatabase",
+      "//third_party/libaddressinput",
+      "//third_party/webrtc_overrides:webrtc_component",
+      "//third_party/widevine/cdm:headers",
+      "//ui/accessibility:test_support",
+      "//ui/base:test_support",
+      "//ui/compositor:test_support",
+      "//ui/resources",
+      "//ui/web_dialogs:test_support",
+      "//v8",
+    ]
+
+    if (is_chromeos_ash) {
+      deps += [ "//components/user_manager:test_support" ]
+    }
+  }
+
+  # TODO(rockot) bug 505926: This should be deleted for the same reason as
+  # chrome_extensions_browsertests.
+  source_set("chrome_extensions_interactive_uitests") {
+    testonly = true
+    sources = [ "browser/guest_view/mime_handler_view/mime_handler_view_interactive_uitest.cc" ]
+
+    defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
+
+    # These are the deps from interactive_uitests minus some internal Chrome
+    # ones that aren't allowed to be included here and that aren't needed.
+    deps = [
+      "//chrome/browser",
+      "//chrome/browser/devtools",
+      "//chrome/renderer",
+      "//chrome/test:test_support",
+      "//components/sync",
+      "//content/app/resources",
+      "//crypto:platform",
+      "//crypto:test_support",
+      "//google_apis:test_support",
+      "//net",
+      "//net:net_resources",
+      "//net:test_support",
+      "//skia",
+      "//testing/gmock",
+      "//testing/gtest",
+      "//third_party/hunspell",
+      "//third_party/icu",
+      "//third_party/libpng",
+      "//third_party/zlib",
+      "//ui/base:test_support",
+      "//ui/resources:ui_test_pak",
+      "//ui/web_dialogs:test_support",
+    ]
+  }
 }
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index c7e95be..ecca9989 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -11,7 +11,41 @@
 
 # TODO(crbug.com/731689): Assert that extensions are enabled.
 
-source_set("common_constants") {
+group("common_constants") {
+  if (is_component_build) {
+    public_deps = [ "//extensions" ]
+  } else {
+    public_deps = [ ":constants_impl" ]
+  }
+}
+
+group("export") {
+  if (is_component_build) {
+    public_deps = [ "//extensions" ]
+  } else {
+    public_deps = [ ":export_impl" ]
+  }
+}
+
+source_set("export_impl") {
+  visibility = [
+    "//extensions",
+    "//extensions/common:*",
+  ]
+
+  configs += [ "//extensions:component_implementation" ]
+
+  sources = [ "extensions_export.h" ]
+}
+
+source_set("constants_impl") {
+  visibility = [
+    "//extensions",
+    "//extensions/common:common_constants",
+  ]
+
+  configs += [ "//extensions:component_implementation" ]
+
   sources = [
     "constants.cc",
     "constants.h",
@@ -22,6 +56,7 @@
     "//base",
     "//build:chromeos_buildflags",
     "//components/services/app_service/public/mojom",
+    "//extensions/common:export_impl",
   ]
 
   deps = [ "//build:chromecast_buildflags" ]
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index 306ae76..f6e8647f 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -118,6 +118,10 @@
 
 namespace extension_misc {
 
+const int kUnknownTabId = -1;
+const int kUnknownWindowId = -1;
+const int kCurrentWindowId = -2;
+
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_CHROMECAST)
 // The extension id for the built-in component extension.
 const char kChromeVoxExtensionId[] = "mndnfokpggljbaajbnioimlmbfngpief";
diff --git a/extensions/common/constants.h b/extensions/common/constants.h
index 862266b..dd15849 100644
--- a/extensions/common/constants.h
+++ b/extensions/common/constants.h
@@ -8,134 +8,148 @@
 #include "base/files/file_path.h"
 #include "base/strings/string_piece_forward.h"
 #include "build/chromeos_buildflags.h"
+#include "extensions/common/extensions_export.h"
 
 namespace extensions {
 
 // Scheme we serve extension content from.
-extern const char kExtensionScheme[];
+EXTENSIONS_EXPORT extern const char kExtensionScheme[];
 
 // The name of the manifest inside an extension.
-extern const base::FilePath::CharType kManifestFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kManifestFilename[];
 
 // The name of the differential fingerprint file inside an extension.
-extern const base::FilePath::CharType kDifferentialFingerprintFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kDifferentialFingerprintFilename[];
 
 // The name of locale folder inside an extension.
-extern const base::FilePath::CharType kLocaleFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kLocaleFolder[];
 
 // The name of the messages file inside an extension.
-extern const base::FilePath::CharType kMessagesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kMessagesFilename[];
 
 // The name of the gzipped messages file inside an extension.
-extern const base::FilePath::CharType kGzippedMessagesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kGzippedMessagesFilename[];
 
 // The base directory for subdirectories with platform-specific code.
-extern const base::FilePath::CharType kPlatformSpecificFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kPlatformSpecificFolder[];
 
 // A directory reserved for metadata, generated either by the webstore
 // or chrome.
-extern const base::FilePath::CharType kMetadataFolder[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kMetadataFolder[];
 
 // Name of the verified contents file within the metadata folder.
-extern const base::FilePath::CharType kVerifiedContentsFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kVerifiedContentsFilename[];
 
 // Name of the computed hashes file within the metadata folder.
-extern const base::FilePath::CharType kComputedHashesFilename[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kComputedHashesFilename[];
 
 // Name of the indexed ruleset directory for the Declarative Net Request API.
-extern const base::FilePath::CharType kIndexedRulesetDirectory[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kIndexedRulesetDirectory[];
 
 // The name of the directory inside the profile where extensions are
 // installed to.
-extern const char kInstallDirectoryName[];
+EXTENSIONS_EXPORT extern const char kInstallDirectoryName[];
 
 // The name of a temporary directory to install an extension into for
 // validation before finalizing install.
-extern const char kTempExtensionName[];
+EXTENSIONS_EXPORT extern const char kTempExtensionName[];
 
 // The file to write our decoded message catalogs to, relative to the
 // extension_path.
-extern const char kDecodedMessageCatalogsFilename[];
+EXTENSIONS_EXPORT extern const char kDecodedMessageCatalogsFilename[];
 
 // The filename to use for a background page generated from
 // background.scripts.
-extern const char kGeneratedBackgroundPageFilename[];
+EXTENSIONS_EXPORT extern const char kGeneratedBackgroundPageFilename[];
 
 // Path to imported modules.
-extern const char kModulesDir[];
+EXTENSIONS_EXPORT extern const char kModulesDir[];
 
 // The file extension (.crx) for extensions.
-extern const base::FilePath::CharType kExtensionFileExtension[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kExtensionFileExtension[];
 
 // The file extension (.pem) for private key files.
-extern const base::FilePath::CharType kExtensionKeyFileExtension[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kExtensionKeyFileExtension[];
 
 // Default frequency for auto updates, if turned on.
-extern const int kDefaultUpdateFrequencySeconds;
+EXTENSIONS_EXPORT extern const int kDefaultUpdateFrequencySeconds;
 
 // The name of the directory inside the profile where per-app local settings
 // are stored.
-extern const base::FilePath::CharType kLocalAppSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kLocalAppSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension local
 // settings are stored.
-extern const base::FilePath::CharType kLocalExtensionSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kLocalExtensionSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-app synced settings
 // are stored.
-extern const base::FilePath::CharType kSyncAppSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kSyncAppSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension synced
 // settings are stored.
-extern const base::FilePath::CharType kSyncExtensionSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kSyncExtensionSettingsDirectoryName[];
 
 // The name of the directory inside the profile where per-extension persistent
 // managed settings are stored.
-extern const base::FilePath::CharType kManagedSettingsDirectoryName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType
+    kManagedSettingsDirectoryName[];
 
 // The name of the database inside the profile where chrome-internal
 // extension state resides.
-extern const base::FilePath::CharType kStateStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kStateStoreName[];
 
 // The name of the database inside the profile where declarative extension
 // rules are stored.
-extern const base::FilePath::CharType kRulesStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kRulesStoreName[];
 
 // The name of the database inside the profile where persistent dynamic user
 // script metadata is stored.
-extern const base::FilePath::CharType kScriptsStoreName[];
+EXTENSIONS_EXPORT extern const base::FilePath::CharType kScriptsStoreName[];
 
 // Statistics are logged to UMA with these strings as part of histogram name.
 // They can all be found under Extensions.Database.Open.<client>. Changing this
 // needs to synchronize with histograms.xml, AND will also become incompatible
 // with older browsers still reporting the previous values.
-extern const char kSettingsDatabaseUMAClientName[];
-extern const char kRulesDatabaseUMAClientName[];
-extern const char kStateDatabaseUMAClientName[];
-extern const char kScriptsDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kSettingsDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kRulesDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kStateDatabaseUMAClientName[];
+EXTENSIONS_EXPORT extern const char kScriptsDatabaseUMAClientName[];
 
 // The URL query parameter key corresponding to multi-login user index.
-extern const char kAuthUserQueryKey[];
+EXTENSIONS_EXPORT extern const char kAuthUserQueryKey[];
 
 // Mime type strings
-extern const char kMimeTypeJpeg[];
-extern const char kMimeTypePng[];
+EXTENSIONS_EXPORT extern const char kMimeTypeJpeg[];
+EXTENSIONS_EXPORT extern const char kMimeTypePng[];
 
 // The extension id of the Web Store component application.
-extern const char kWebStoreAppId[];
+EXTENSIONS_EXPORT extern const char kWebStoreAppId[];
 
 // The key used for signing some pieces of data from the webstore.
-extern const uint8_t kWebstoreSignaturesPublicKey[];
-extern const size_t kWebstoreSignaturesPublicKeySize;
+EXTENSIONS_EXPORT extern const uint8_t kWebstoreSignaturesPublicKey[];
+EXTENSIONS_EXPORT extern const size_t kWebstoreSignaturesPublicKeySize;
 
 // A preference for storing the extension's update URL data.
-extern const char kUpdateURLData[];
+EXTENSIONS_EXPORT extern const char kUpdateURLData[];
 
 // Thread identifier for the main renderer thread (as opposed to a service
 // worker thread).
 // This is the default thread id used for extension event listeners registered
 // from a non-service worker context
-extern const int kMainThreadId;
+EXTENSIONS_EXPORT extern const int kMainThreadId;
 
 // Enumeration of possible app launch sources.
 // This should be kept in sync with LaunchSource in
@@ -201,13 +215,13 @@
 namespace extension_misc {
 
 // Matches chrome.tabs.TAB_ID_NONE.
-const int kUnknownTabId = -1;
+EXTENSIONS_EXPORT extern const int kUnknownTabId;
 
 // Matches chrome.windows.WINDOW_ID_NONE.
-const int kUnknownWindowId = -1;
+EXTENSIONS_EXPORT extern const int kUnknownWindowId;
 
 // Matches chrome.windows.WINDOW_ID_CURRENT.
-const int kCurrentWindowId = -2;
+EXTENSIONS_EXPORT extern const int kCurrentWindowId;
 
 enum ExtensionIcons {
   EXTENSION_ICON_GIGANTOR = 512,
@@ -221,125 +235,125 @@
 };
 
 // The extension id of the ChromeVox extension.
-extern const char kChromeVoxExtensionId[];
+EXTENSIONS_EXPORT extern const char kChromeVoxExtensionId[];
 
 // The extension id of the feedback component extension.
-extern const char kFeedbackExtensionId[];
+EXTENSIONS_EXPORT extern const char kFeedbackExtensionId[];
 
 // The extension id of the PDF extension.
-extern const char kPdfExtensionId[];
+EXTENSIONS_EXPORT extern const char kPdfExtensionId[];
 
 // The extension id of the Office Viewer component extension.
-extern const char kQuickOfficeComponentExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeComponentExtensionId[];
 
 // The extension id of the Office Viewer extension on the internal webstore.
-extern const char kQuickOfficeInternalExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeInternalExtensionId[];
 
 // The extension id of the Office Viewer extension.
-extern const char kQuickOfficeExtensionId[];
+EXTENSIONS_EXPORT extern const char kQuickOfficeExtensionId[];
 
 // The extension id used for testing mimeHandlerPrivate.
-extern const char kMimeHandlerPrivateTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kMimeHandlerPrivateTestExtensionId[];
 
 // The extension id of the Chrome component application.
-extern const char kChromeAppId[];
+EXTENSIONS_EXPORT extern const char kChromeAppId[];
 
 // Fake extension ID for the Lacros chrome browser application.
-extern const char kLacrosAppId[];
+EXTENSIONS_EXPORT extern const char kLacrosAppId[];
 
 // The extension id of the Files Manager application.
-extern const char kFilesManagerAppId[];
+EXTENSIONS_EXPORT extern const char kFilesManagerAppId[];
 
 // The extension id of the Calculator application.
-extern const char kCalculatorAppId[];
+EXTENSIONS_EXPORT extern const char kCalculatorAppId[];
 
 // The extension id of the demo Calendar application.
-extern const char kCalendarDemoAppId[];
+EXTENSIONS_EXPORT extern const char kCalendarDemoAppId[];
 
 // The extension id of the GMail application.
-extern const char kGmailAppId[];
+EXTENSIONS_EXPORT extern const char kGmailAppId[];
 
 // The extension id of the demo Google Docs application.
-extern const char kGoogleDocsDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsDemoAppId[];
 
 // The extension id of the Google Docs PWA.
-extern const char kGoogleDocsPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsPwaAppId[];
 
 // The extension id of the Google Drive application.
-extern const char kGoogleDriveAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDriveAppId[];
 
 // The extension id of the Google Meet PWA.
-extern const char kGoogleMeetPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleMeetPwaAppId[];
 
 // The extension id of the demo Google Sheets application.
-extern const char kGoogleSheetsDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsDemoAppId[];
 
 // The extension id of the Google Sheets PWA.
-extern const char kGoogleSheetsPwaAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsPwaAppId[];
 
 // The extension id of the demo Google Slides application.
-extern const char kGoogleSlidesDemoAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSlidesDemoAppId[];
 
 // The extension id of the Google Keep application.
-extern const char kGoogleKeepAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleKeepAppId[];
 
 // The extension id of the Youtube application.
-extern const char kYoutubeAppId[];
+EXTENSIONS_EXPORT extern const char kYoutubeAppId[];
 
 // The extension id of the Youtube PWA.
-extern const char kYoutubePwaAppId[];
+EXTENSIONS_EXPORT extern const char kYoutubePwaAppId[];
 
 // The extension id of the Spotify PWA.
-extern const char kSpotifyAppId[];
+EXTENSIONS_EXPORT extern const char kSpotifyAppId[];
 
 // The extension id of the BeFunky PWA.
-extern const char kBeFunkyAppId[];
+EXTENSIONS_EXPORT extern const char kBeFunkyAppId[];
 
 // The extension id of the Clipchamp PWA.
-extern const char kClipchampAppId[];
+EXTENSIONS_EXPORT extern const char kClipchampAppId[];
 
 // The extension id of the GeForce NOW PWA.
-extern const char kGeForceNowAppId[];
+EXTENSIONS_EXPORT extern const char kGeForceNowAppId[];
 
 // The extension id of the Zoom PWA.
-extern const char kZoomAppId[];
+EXTENSIONS_EXPORT extern const char kZoomAppId[];
 
 // The extension id of the Google Docs application.
-extern const char kGoogleDocsAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleDocsAppId[];
 
 // The extension id of the Google Sheets application.
-extern const char kGoogleSheetsAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSheetsAppId[];
 
 // The extension id of the Google Slides application.
-extern const char kGoogleSlidesAppId[];
+EXTENSIONS_EXPORT extern const char kGoogleSlidesAppId[];
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 // The extension id of the default Demo Mode Highlights app.
-extern const char kHighlightsAppId[];
+EXTENSIONS_EXPORT extern const char kHighlightsAppId[];
 
 // The extension id of the atlas Demo Mode Highlights app.
-extern const char kHighlightsAtlasAppId[];
+EXTENSIONS_EXPORT extern const char kHighlightsAtlasAppId[];
 
 // The extension id of the default Demo Mode screensaver app.
-extern const char kScreensaverAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverAppId[];
 
 // The extension id of the atlas Demo Mode screensaver app.
-extern const char kScreensaverAtlasAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverAtlasAppId[];
 
 // The extension id of the krane Demo Mode screensaver app. That app is only
 // run on KRANE-ZDKS devices.
-extern const char kScreensaverKraneZdksAppId[];
+EXTENSIONS_EXPORT extern const char kScreensaverKraneZdksAppId[];
 
 // The id of the testing extension allowed in the signin profile.
-extern const char kSigninProfileTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kSigninProfileTestExtensionId[];
 
 // The id of the testing extension allowed in guest mode.
-extern const char kGuestModeTestExtensionId[];
+EXTENSIONS_EXPORT extern const char kGuestModeTestExtensionId[];
 
 // Returns true if this app is part of the "system UI". Generally this is UI
 // that that on other operating systems would be considered part of the OS,
 // for example the file manager.
-bool IsSystemUIApp(base::StringPiece extension_id);
+EXTENSIONS_EXPORT bool IsSystemUIApp(base::StringPiece extension_id);
 #endif
 
 // Returns if the app is managed by extension default apps. This is a hardcoded
@@ -348,29 +362,29 @@
 // TODO(https://crbug.com/1257275): remove after deault app migration is done.
 // This function is copied from
 // chrome/browser/web_applications/extension_status_utils.h.
-bool IsPreinstalledAppId(const std::string& app_id);
+EXTENSIONS_EXPORT bool IsPreinstalledAppId(const std::string& app_id);
 
 // The extension id for the production version of Hangouts.
-extern const char kProdHangoutsExtensionId[];
+EXTENSIONS_EXPORT extern const char kProdHangoutsExtensionId[];
 
 // Extension ids used by Hangouts.
-extern const char* const kHangoutsExtensionIds[6];
+EXTENSIONS_EXPORT extern const char* const kHangoutsExtensionIds[6];
 
 // Error message when enterprise policy blocks scripting of webpage.
-extern const char kPolicyBlockedScripting[];
+EXTENSIONS_EXPORT extern const char kPolicyBlockedScripting[];
 
 // The default block size for hashing used in content verification.
-extern const int kContentVerificationDefaultBlockSize;
+EXTENSIONS_EXPORT extern const int kContentVerificationDefaultBlockSize;
 
 // The origin of the CryptoToken component extension, which implements the
 // deprecated U2F Security Key API.
 // TODO(1224886): Delete together with CryptoToken code.
-extern const char kCryptotokenExtensionId[];
+EXTENSIONS_EXPORT extern const char kCryptotokenExtensionId[];
 
 // The name of the CryptoToken component extension deprecation trial, which
 // allows making requests to the extension after it has been default disabled.
 // TODO(1224886): Delete together with CryptoToken code.
-extern const char kCryptotokenDeprecationTrialName[];
+EXTENSIONS_EXPORT extern const char kCryptotokenDeprecationTrialName[];
 
 }  // namespace extension_misc
 
diff --git a/extensions/common/extensions_export.h b/extensions/common/extensions_export.h
new file mode 100644
index 0000000..b6ff78f
--- /dev/null
+++ b/extensions/common/extensions_export.h
@@ -0,0 +1,30 @@
+// Copyright 2022 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 EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
+#define EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+
+#if defined(WIN32)
+
+#if defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+#define EXTENSIONS_EXPORT __declspec(dllexport)
+#else
+#define EXTENSIONS_EXPORT __declspec(dllimport)
+#endif  // defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(EXTENSIONS_COMPONENT_IMPLEMENTATION)
+#define EXTENSIONS_EXPORT __attribute__((visibility("default")))
+#else
+#define EXTENSIONS_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define EXTENSIONS_EXPORT
+#endif
+
+#endif  // EXTENSIONS_COMMON_EXTENSIONS_EXPORT_H_
diff --git a/extensions/common/manifest_handlers/mime_types_handler.cc b/extensions/common/manifest_handlers/mime_types_handler.cc
index bb86605..a74df21 100644
--- a/extensions/common/manifest_handlers/mime_types_handler.cc
+++ b/extensions/common/manifest_handlers/mime_types_handler.cc
@@ -26,7 +26,7 @@
 // This has to by in sync with MimeHandlerType enum.
 // Note that if multiple versions of quickoffice are installed, the
 // higher-indexed entry will clobber earlier entries.
-constexpr const char* const kMIMETypeHandlersAllowlist[] = {
+const char* kMIMETypeHandlersAllowlist[] = {
     extension_misc::kPdfExtensionId,
     extension_misc::kQuickOfficeComponentExtensionId,
     extension_misc::kQuickOfficeInternalExtensionId,