lacros-primary enables Lacros PWAs

Whenever chrome://flags/#lacros-primary is enabled, desktop PWAs are
managed by Lacros instead of Ash.

This is already the case when chrome://flags/#web-apps-crosapi is
enabled, but now chrome://flags/#lacros-primary is independently
sufficient.

Note that Ash tests with Ash managing desktop PWAs disable both flags:
https://chromium-review.googlesource.com/c/chromium/src/+/3246692


Bug: 1261978
Change-Id: I52311061f2e6c9381fd0623a8854b236304036c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3239710
Commit-Queue: Eric Willigers <ericwilligers@chromium.org>
Reviewed-by: Dominick Ng <dominickn@chromium.org>
Reviewed-by: Erik Chen <erikchen@chromium.org>
Reviewed-by: David Bertoni <dbertoni@chromium.org>
Reviewed-by: Alexander Bolodurin <alexbn@chromium.org>
Cr-Commit-Position: refs/heads/main@{#935561}
diff --git a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
index 11b50889..aadaeb90 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_chromeos.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/supervised_user/grit/supervised_user_unscaled_resources.h"
 #include "chrome/browser/web_applications/app_service/web_apps.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "components/account_id/account_id.h"
 #include "components/app_restore/features.h"
@@ -51,7 +52,7 @@
 
 AppServiceProxyChromeOs::AppServiceProxyChromeOs(Profile* profile)
     : AppServiceProxyBase(profile) {
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     browser_app_instance_tracker_ =
         std::make_unique<apps::BrowserAppInstanceTracker>(profile_,
                                                           app_registry_cache_);
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index 23e535df..2b4e81c6 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/apps/app_service/menu_util.h"
 #include "chrome/browser/ash/crosapi/browser_manager.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
@@ -131,7 +132,7 @@
 
 void StandaloneBrowserApps::StopApp(const std::string& app_id) {
   DCHECK_EQ(extension_misc::kLacrosAppId, app_id);
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     return;
   }
   DCHECK(browser_app_instance_registry_);
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
index 8282492..66bfa13 100644
--- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
+++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/services/app_service/public/cpp/crosapi_utils.h"
@@ -31,7 +32,7 @@
 WebAppsCrosapi::WebAppsCrosapi(Profile* profile) : profile_(profile) {
   // This object may be created when the flag is on or off, but only register
   // the publisher if the flag is on.
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     apps::AppServiceProxyChromeOs* proxy =
         apps::AppServiceProxyFactory::GetForProfile(profile);
     mojo::Remote<apps::mojom::AppService>& app_service = proxy->AppService();
@@ -186,7 +187,7 @@
     // need to check BrowserAppInstanceRegistry directly. Remove this when
     // InstanceRegistry updates are implemented.
     bool app_running =
-        base::FeatureList::IsEnabled(features::kWebAppsCrosapi)
+        web_app::IsWebAppsCrosapiEnabled()
             ? proxy->BrowserAppInstanceRegistry()->IsAppRunning(app_id)
             : proxy->InstanceRegistry().ContainsAppId(app_id);
     if (app_running) {
@@ -317,7 +318,7 @@
 }
 
 void WebAppsCrosapi::OnApps(std::vector<apps::mojom::AppPtr> deltas) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi))
+  if (!web_app::IsWebAppsCrosapiEnabled())
     return;
   for (auto& subscriber : subscribers_) {
     subscriber->OnApps(apps_util::CloneStructPtrVector(deltas),
@@ -338,7 +339,7 @@
 
 void WebAppsCrosapi::OnCapabilityAccesses(
     std::vector<apps::mojom::CapabilityAccessPtr> deltas) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi))
+  if (!web_app::IsWebAppsCrosapiEnabled())
     return;
   for (auto& subscriber : subscribers_) {
     subscriber->OnCapabilityAccesses(apps_util::CloneStructPtrVector(deltas));
diff --git a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
index 49aade5..c75a9e4 100644
--- a/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
+++ b/chrome/browser/ash/app_restore/full_restore_app_launch_handler_browsertest.cc
@@ -43,6 +43,7 @@
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_id.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/browser/web_applications/web_application_info.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -2566,7 +2567,7 @@
   void ModifyAppReadiness(apps::mojom::Readiness readiness) {
     apps::mojom::AppType app_type = apps::mojom::AppType::kWeb;
     if (crosapi::browser_util::IsLacrosEnabled() &&
-        base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+        web_app::IsWebAppsCrosapiEnabled()) {
       app_type = apps::mojom::AppType::kSystemWeb;
     }
 
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index 2b8b6ce..1b82328c 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/policy/profile_policy_connector.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
@@ -771,8 +772,7 @@
     params->startup_urls = std::move(initial_browser_action.urls);
   }
 
-  params->web_apps_enabled =
-      base::FeatureList::IsEnabled(features::kWebAppsCrosapi);
+  params->web_apps_enabled = web_app::IsWebAppsCrosapiEnabled();
   params->standalone_browser_is_primary = IsLacrosPrimaryBrowser();
   params->device_properties = GetDeviceProperties();
   params->device_settings = GetDeviceSettings();
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index b33eabd..2e8d061 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -70,6 +70,7 @@
 #include "chrome/browser/speech/tts_ash.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h"
 #include "chrome/browser/ui/ash/holding_space/holding_space_keyed_service_factory.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chromeos/components/cdm_factory_daemon/cdm_factory_daemon_proxy_ash.h"
 #include "chromeos/components/sensors/ash/sensor_hal_dispatcher.h"
@@ -223,7 +224,7 @@
 
 void CrosapiAsh::BindBrowserAppInstanceRegistry(
     mojo::PendingReceiver<mojom::BrowserAppInstanceRegistry> receiver) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     return;
   }
   Profile* profile = ProfileManager::GetPrimaryUserProfile();
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
index 39fb263..f6801c4d 100644
--- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
+++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/extensions/extension_apitest.h"
 #include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "components/crash/content/browser/error_reporting/mock_crash_endpoint.h"
 #include "content/public/test/browser_task_environment.h"
@@ -313,7 +314,7 @@
 // window.
 IN_PROC_BROWSER_TEST_P(CrashReportPrivateCalledFromSwaTest,
                        CalledFromWebContentsInWebAppWindow) {
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     // TODO(crbug.com/1234938): Support Crosapi (web apps running in Lacros).
     return;
   }
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
index 0399127..86048bd9 100644
--- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
+++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -64,6 +64,7 @@
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/login/demo_mode/demo_session.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/arc_util.h"
 #include "components/arc/mojom/intent_helper.mojom.h"
@@ -253,7 +254,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     // Avoid accessing the WebAppProvider when web apps are enabled in Lacros
     // (and thus disabled in Ash).
-    if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+    if (web_app::IsWebAppsCrosapiEnabled()) {
       function->FinishCreateWebApp(std::string(),
                                    /*install_success=*/false);
       return;
@@ -553,7 +554,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Avoid accessing the WebAppProvider when web apps are enabled in Lacros (and
   // thus disabled in Ash).
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     std::move(callback).Run(InstallOrLaunchWebAppResult::kUnknownError);
     return;
   }
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
index fafea24e..d22385a1 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_shelf_controller.cc
@@ -39,6 +39,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chromeos/ui/base/window_properties.h"
@@ -168,7 +169,7 @@
   if (!widget || !widget->is_top_level())
     return;
 
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi) &&
+  if (web_app::IsWebAppsCrosapiEnabled() &&
       crosapi::browser_util::IsLacrosWindow(window)) {
     // Ignore all Lacros windows, handled by BrowserAppShelfController.
     return;
diff --git a/chrome/browser/ui/ash/shelf/browser_status_monitor.cc b/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
index 0efa3cb..bc84ede 100644
--- a/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
+++ b/chrome/browser/ui/ash/shelf/browser_status_monitor.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_handle.h"
@@ -115,7 +116,7 @@
 }
 
 void BrowserStatusMonitor::ActiveUserChanged(const std::string& user_email) {
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     return;
   }
   // When the active profile changes, all windowed and tabbed apps owned by the
@@ -167,7 +168,7 @@
 
 void BrowserStatusMonitor::UpdateAppItemState(content::WebContents* contents,
                                               bool remove) {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   DCHECK(contents);
   DCHECK(initialized_);
   // It is possible to come here from Browser::SwapTabContent where the contents
@@ -181,7 +182,7 @@
 }
 
 void BrowserStatusMonitor::UpdateBrowserItemState() {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   DCHECK(initialized_);
   shelf_controller_->UpdateBrowserItemState();
 }
@@ -193,7 +194,7 @@
   DCHECK(insert_result.second);
 #endif
 
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     if (IsAppBrowser(browser) &&
         multi_user_util::IsProfileFromActiveUser(browser->profile())) {
       AddAppBrowserToShelf(browser);
@@ -208,7 +209,7 @@
   DCHECK_EQ(num_removed, 1U);
 #endif
 
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     if (IsAppBrowser(browser) &&
         multi_user_util::IsProfileFromActiveUser(browser->profile())) {
       RemoveAppBrowserFromShelf(browser);
@@ -249,7 +250,7 @@
         OnTabInserted(tab_strip_model, contents.contents);
       }
     }
-    if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+    if (!web_app::IsWebAppsCrosapiEnabled()) {
       UpdateBrowserItemState();
     }
   } else if (change.type() == TabStripModelChange::kRemoved) {
@@ -294,7 +295,7 @@
 }
 
 void BrowserStatusMonitor::AddAppBrowserToShelf(Browser* browser) {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   DCHECK(IsAppBrowser(browser));
   DCHECK(initialized_);
 
@@ -311,7 +312,7 @@
 }
 
 void BrowserStatusMonitor::RemoveAppBrowserFromShelf(Browser* browser) {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   DCHECK(IsAppBrowser(browser));
   DCHECK(initialized_);
 
@@ -325,13 +326,13 @@
 }
 
 bool BrowserStatusMonitor::IsAppBrowserInShelf(Browser* browser) {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   return browser_to_app_id_map_.find(browser) != browser_to_app_id_map_.end();
 }
 
 bool BrowserStatusMonitor::IsAppBrowserInShelfWithAppId(
     const std::string& app_id) {
-  DCHECK(!base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+  DCHECK(!web_app::IsWebAppsCrosapiEnabled());
   for (const auto& iter : browser_to_app_id_map_) {
     if (iter.second == app_id)
       return true;
@@ -342,7 +343,7 @@
 void BrowserStatusMonitor::OnActiveTabChanged(
     content::WebContents* old_contents,
     content::WebContents* new_contents) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     Browser* browser = nullptr;
     // Use |new_contents|. |old_contents| could be nullptr.
     DCHECK(new_contents);
@@ -371,7 +372,7 @@
 void BrowserStatusMonitor::OnTabReplaced(TabStripModel* tab_strip_model,
                                          content::WebContents* old_contents,
                                          content::WebContents* new_contents) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     DCHECK(old_contents && new_contents);
     Browser* browser = chrome::FindBrowserWithWebContents(new_contents);
 
@@ -400,7 +401,7 @@
 
 void BrowserStatusMonitor::OnTabInserted(TabStripModel* tab_strip_model,
                                          content::WebContents* contents) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     UpdateAppItemState(contents, false /*remove*/);
     // If the contents does not have a visible navigation entry, wait until a
     // navigation status changes before setting the browser window Shelf ID
@@ -418,7 +419,7 @@
 }
 
 void BrowserStatusMonitor::OnTabClosing(content::WebContents* contents) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     UpdateAppItemState(contents, true /*remove*/);
     RemoveWebContentsObserver(contents);
   }
@@ -434,7 +435,7 @@
 
 void BrowserStatusMonitor::OnTabNavigationFinished(
     content::WebContents* contents) {
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     return;
   }
   UpdateAppItemState(contents, false /*remove*/);
@@ -467,7 +468,7 @@
 void BrowserStatusMonitor::SetShelfIDForBrowserWindowContents(
     Browser* browser,
     content::WebContents* web_contents) {
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!web_app::IsWebAppsCrosapiEnabled()) {
     shelf_controller_->SetShelfIDForBrowserWindowContents(browser,
                                                           web_contents);
   }
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
index 57d5722..8d0b7624d 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -79,6 +79,7 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/settings/chromeos/app_management/app_management_uma.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
 #include "chrome/common/pref_names.h"
@@ -255,7 +256,7 @@
   app_window_controllers_.emplace_back(std::move(app_service_controller));
   // Create the browser monitor which will inform the shelf of status changes.
   browser_status_monitor_ = std::make_unique<BrowserStatusMonitor>(this);
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     browser_app_shelf_controller_ = std::make_unique<BrowserAppShelfController>(
         profile, *model_, *shelf_item_factory_, *shelf_spinner_controller_);
   }
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_item_factory.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_item_factory.cc
index 7ee3e48e..b9bdeda 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_item_factory.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_item_factory.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/ui/ash/shelf/arc_playstore_shortcut_shelf_item_controller.h"
 #include "chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.h"
 #include "chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 
@@ -40,7 +41,7 @@
       apps::AppServiceProxyFactory::GetInstance()->GetForProfile(profile);
   apps::mojom::AppType app_type = proxy->AppRegistryCache().GetAppType(app_id);
 
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (web_app::IsWebAppsCrosapiEnabled()) {
     switch (app_type) {
       case apps::mojom::AppType::kWeb:
       case apps::mojom::AppType::kSystemWeb:
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index 7433abc..5ec3672 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -756,7 +756,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
 void WebAppPublisherHelper::StopApp(const std::string& app_id) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (!base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (!IsWebAppsCrosapiEnabled()) {
     return;
   }
 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/web_applications/app_service/web_apps.cc b/chrome/browser/web_applications/app_service/web_apps.cc
index 14d8d00..f8be312 100644
--- a/chrome/browser/web_applications/app_service/web_apps.cc
+++ b/chrome/browser/web_applications/app_service/web_apps.cc
@@ -57,8 +57,7 @@
 // to kSystemWeb for this case and the kWeb app type will be published from
 // the publisher for Lacros web apps.
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (crosapi::browser_util::IsLacrosEnabled() &&
-      base::FeatureList::IsEnabled(features::kWebAppsCrosapi)) {
+  if (crosapi::browser_util::IsLacrosEnabled() && IsWebAppsCrosapiEnabled()) {
     return apps::mojom::AppType::kSystemWeb;
   }
 #endif
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
index 5595fdfd..0072d02 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -38,6 +38,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/ash/policy/handlers/system_features_disable_list_policy_handler.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "components/policy/core/common/policy_pref_names.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -78,7 +79,7 @@
   // to construct a WebAppPolicyManager.
   bool enable_pwa_support = true;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  enable_pwa_support = !base::FeatureList::IsEnabled(features::kWebAppsCrosapi);
+  enable_pwa_support = !IsWebAppsCrosapiEnabled();
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
       ->PostTask(FROM_HERE,
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager.cc b/chrome/browser/web_applications/preinstalled_web_app_manager.cc
index 4c456ed..f9fdcff 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager.cc
@@ -44,6 +44,7 @@
 #include "chrome/browser/web_applications/web_app_constants.h"
 #include "chrome/browser/web_applications/web_app_install_utils.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
@@ -419,7 +420,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // With Lacros, web apps are not installed using the Ash browser.
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi))
+  if (IsWebAppsCrosapiEnabled())
     preinstalling_enabled = false;
 #endif
 
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc
index 619a315..432dcb1 100644
--- a/chrome/browser/web_applications/web_app_provider.cc
+++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -72,7 +72,7 @@
   // If features::kWebAppsCrosapi is enabled, Ash browser only manages system
   // web apps (return nullptr here). Otherwise, Ash browser manages all web apps
   // (return WebAppProvider).
-  return base::FeatureList::IsEnabled(features::kWebAppsCrosapi)
+  return IsWebAppsCrosapiEnabled()
              ? nullptr
              : WebAppProviderFactory::GetForProfile(profile);
 #else
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc
index a6ac33e..87b5a58 100644
--- a/chrome/browser/web_applications/web_app_registrar.cc
+++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -36,8 +36,7 @@
 // With Lacros, only system web apps are exposed using the Ash browser.
 bool WebAppExposed(const WebApp& web_app) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi) &&
-      !web_app.IsSystemApp()) {
+  if (IsWebAppsCrosapiEnabled() && !web_app.IsSystemApp()) {
     return false;
   }
 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc
index 70d39a6c..0def9bd 100644
--- a/chrome/browser/web_applications/web_app_sync_bridge.cc
+++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -453,8 +453,7 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     // We do not install non-system web apps in Ash when Lacros web apps are
     // enabled.
-    DCHECK(web_app->IsSystemApp() ||
-           !base::FeatureList::IsEnabled(features::kWebAppsCrosapi));
+    DCHECK(web_app->IsSystemApp() || !IsWebAppsCrosapiEnabled());
 #endif
     registrar_->registry().emplace(std::move(app_id), std::move(web_app));
   }
diff --git a/chrome/browser/web_applications/web_app_utils.cc b/chrome/browser/web_applications/web_app_utils.cc
index 9f0915f..104ee3ac 100644
--- a/chrome/browser/web_applications/web_app_utils.cc
+++ b/chrome/browser/web_applications/web_app_utils.cc
@@ -24,6 +24,7 @@
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "ash/constants/ash_features.h"
 #include "base/feature_list.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/common/chrome_features.h"
@@ -69,7 +70,7 @@
 bool AreWebAppsUserInstallable(Profile* profile) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // With Lacros, web apps are not installed using the Ash browser.
-  if (base::FeatureList::IsEnabled(features::kWebAppsCrosapi))
+  if (IsWebAppsCrosapiEnabled())
     return false;
 #endif
   return AreWebAppsEnabled(profile) && !profile->IsGuestSession() &&
@@ -167,7 +168,7 @@
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
   // With Crosapi, Ash no longer participates in sync.
   // On Chrome OS before Crosapi, sync always locally installs an app.
-  return !base::FeatureList::IsEnabled(features::kWebAppsCrosapi);
+  return !IsWebAppsCrosapiEnabled();
 #else
   return false;
 #endif
@@ -262,6 +263,13 @@
       l10n_util::GetStringUTF8(IDS_WEB_APP_FILE_HANDLING_LIST_SEPARATOR)));
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+bool IsWebAppsCrosapiEnabled() {
+  return base::FeatureList::IsEnabled(features::kWebAppsCrosapi) ||
+         base::FeatureList::IsEnabled(chromeos::features::kLacrosPrimary);
+}
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 void EnableSystemWebAppsInLacrosForTesting() {
   g_enable_system_web_apps_in_lacros_for_testing = true;
diff --git a/chrome/browser/web_applications/web_app_utils.h b/chrome/browser/web_applications/web_app_utils.h
index f5f4d31..05ba8070 100644
--- a/chrome/browser/web_applications/web_app_utils.h
+++ b/chrome/browser/web_applications/web_app_utils.h
@@ -131,6 +131,13 @@
                                    bool allowed,
                                    base::OnceClosure update_finished_callback);
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+// The kLacrosPrimary and kWebAppsCrosapi features are each independently
+// sufficient to enable the web apps Crosapi (used for Lacros web app
+// management).
+bool IsWebAppsCrosapiEnabled();
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 // Enables System Web Apps so we can test SWA features in Lacros, even we don't
 // have actual SWAs in Lacros.