Commit ef474148 authored by Eric Willigers's avatar Eric Willigers Committed by Commit Bot

desktop-pwas: LaunchService

LaunchService is a keyed service that handles launching of both BMO
web applications and extension-based applications.

Note that the Launch Service is intended to merge later into
the App Service.
See `//chrome/services/app_service/README.md`

Bug: 966288
Change-Id: I68e66ff5996cdae00fa01b57d73e76f39a58b5da
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1695421Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarAlexey Baskakov <loyso@chromium.org>
Reviewed-by: default avatarAlan Cutter <alancutter@chromium.org>
Commit-Queue: Eric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#678580}
parent d2623711
......@@ -2887,6 +2887,14 @@ jumbo_split_static_library("browser") {
"apps/intent_helper/intent_picker_auto_display_service_factory.h",
"apps/intent_helper/page_transition_util.cc",
"apps/intent_helper/page_transition_util.h",
"apps/launch_service/extension_app_launch_manager.cc",
"apps/launch_service/extension_app_launch_manager.h",
"apps/launch_service/launch_manager.cc",
"apps/launch_service/launch_manager.h",
"apps/launch_service/launch_service.cc",
"apps/launch_service/launch_service.h",
"apps/launch_service/launch_service_factory.cc",
"apps/launch_service/launch_service_factory.h",
"background/background_contents.cc",
"background/background_contents.h",
"background/background_contents_service_observer.h",
......
......@@ -8,20 +8,6 @@
namespace apps {
bool OpenApplicationWindow(Profile* profile,
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) {
// TODO(loyso): Redirect to web_app::WebAppProvider for BMO apps (PWAs).
return OpenExtensionApplicationWindow(profile, app_id, command_line,
current_directory);
}
bool OpenApplicationTab(Profile* profile, const std::string& app_id) {
// TODO(loyso): Redirect to web_app::WebAppProvider for BMO apps (Shortcuts).
return OpenExtensionApplicationTab(profile, app_id);
}
bool OpenApplicationWithReenablePrompt(
Profile* profile,
const std::string& app_id,
......
......@@ -17,16 +17,7 @@ class FilePath;
namespace apps {
// Returns true if |app_id| was successfully opened in a window, and false
// otherwise.
bool OpenApplicationWindow(Profile* profile,
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory);
// Returns true if |app_id| was successfully opened in a tab, and false
// otherwise.
bool OpenApplicationTab(Profile* profile, const std::string& app_id);
// TODO(crbug.com/966288): Move these methods into LaunchService.
// Tries to open |app_id|, and prompts the user if the app is disabled. Returns
// true if the app was successfully opened and false otherwise.
......
ericwilligers@chromium.org
loyso@chromium.org
The Launch Service provides browser-specific functions for launching
application.
For example, Chrome Apps (platform apps and legacy packaged apps),
and BMO-based Desktop PWAs can be launched using this service.
The intent is to merge LaunchService into the AppService,
specifically AppServiceProxyImpl.
See `//chrome/services/app_service/README.md` for a description of the
App Service.
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/launch_service/extension_app_launch_manager.h"
#include "base/feature_list.h"
#include "chrome/browser/apps/platform_apps/platform_app_launch.h"
#include "chrome/common/chrome_features.h"
namespace apps {
ExtensionAppLaunchManager::ExtensionAppLaunchManager(Profile* profile)
: LaunchManager(profile) {}
ExtensionAppLaunchManager::~ExtensionAppLaunchManager() = default;
bool ExtensionAppLaunchManager::OpenApplicationWindow(
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) {
return OpenExtensionApplicationWindow(profile(), app_id, command_line,
current_directory);
}
bool ExtensionAppLaunchManager::OpenApplicationTab(const std::string& app_id) {
return OpenExtensionApplicationTab(profile(), app_id);
}
} // namespace apps
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_LAUNCH_SERVICE_EXTENSION_APP_LAUNCH_MANAGER_H_
#define CHROME_BROWSER_APPS_LAUNCH_SERVICE_EXTENSION_APP_LAUNCH_MANAGER_H_
#include "base/macros.h"
#include "chrome/browser/apps/launch_service/launch_manager.h"
#include "chrome/services/app_service/public/mojom/types.mojom.h"
namespace apps {
// Handles launch requests for extension-backed apps,
// including Chrome Apps (platform apps and legacy packaged apps) and hosted
// apps (including desktop PWAs until BMO is ready).
class ExtensionAppLaunchManager final : public LaunchManager {
public:
explicit ExtensionAppLaunchManager(Profile* profile);
~ExtensionAppLaunchManager() override;
// apps::LaunchManager:
bool OpenApplicationWindow(const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) override;
bool OpenApplicationTab(const std::string& app_id) override;
private:
DISALLOW_COPY_AND_ASSIGN(ExtensionAppLaunchManager);
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_LAUNCH_SERVICE_EXTENSION_APP_LAUNCH_MANAGER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/launch_service/launch_manager.h"
namespace apps {
LaunchManager::LaunchManager(Profile* profile) : profile_(profile) {}
LaunchManager::~LaunchManager() = default;
} // namespace apps
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_MANAGER_H_
#define CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_MANAGER_H_
#include <string>
#include "base/macros.h"
class Profile;
namespace base {
class CommandLine;
class FilePath;
} // namespace base
namespace apps {
// A LaunchManager handles launch requests for a given type of apps.
class LaunchManager {
public:
virtual ~LaunchManager();
// Attempt to open |app_id| in a new window.
virtual bool OpenApplicationWindow(
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) = 0;
// Attempt to open |app_id| in a new tab.
virtual bool OpenApplicationTab(const std::string& app_id) = 0;
protected:
explicit LaunchManager(Profile*);
Profile* profile() { return profile_; }
private:
Profile* const profile_;
DISALLOW_COPY_AND_ASSIGN(LaunchManager);
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_MANAGER_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/launch_service/launch_service.h"
#include "base/feature_list.h"
#include "chrome/browser/apps/launch_service/extension_app_launch_manager.h"
#include "chrome/browser/apps/launch_service/launch_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/web_applications/web_app_launch_manager.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/chrome_features.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
namespace apps {
// static
LaunchService* LaunchService::Get(Profile* profile) {
return LaunchServiceFactory::GetForProfile(profile);
}
LaunchService::LaunchService(Profile* profile) : profile_(profile) {
DCHECK(profile_);
// LaunchService must have only one instance in original profile.
// Exclude secondary off-the-record profiles.
DCHECK(!profile_->IsOffTheRecord());
extension_app_launch_manager_ =
std::make_unique<ExtensionAppLaunchManager>(profile);
if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions) ||
base::FeatureList::IsEnabled(features::kDesktopPWAsUnifiedLaunch)) {
web_app_launch_manager_ =
std::make_unique<web_app::WebAppLaunchManager>(profile);
} else {
web_app_launch_manager_ =
std::make_unique<ExtensionAppLaunchManager>(profile);
}
}
LaunchService::~LaunchService() {}
LaunchManager& LaunchService::GetLaunchManagerForApp(
const std::string& app_id) {
const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension(
app_id);
return (!extension || extension->from_bookmark())
? *web_app_launch_manager_
: *extension_app_launch_manager_;
}
bool LaunchService::OpenApplicationWindow(
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) {
return GetLaunchManagerForApp(app_id).OpenApplicationWindow(
app_id, command_line, current_directory);
}
bool LaunchService::OpenApplicationTab(const std::string& app_id) {
return GetLaunchManagerForApp(app_id).OpenApplicationTab(app_id);
}
} // namespace apps
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_H_
#define CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "components/keyed_service/core/keyed_service.h"
class Profile;
namespace base {
class CommandLine;
class FilePath;
} // namespace base
namespace apps {
class LaunchManager;
// This KeyedService receives app launch requests and forwards them
// to the appropriate LaunchManager, based on the type of app.
//
// It is expected to merge into the App Service (Proxy) when that service
// stabilizes. Launch requests will be forwarded through App publishers to App
// providers, and the LaunchManager classes will be retired. See
// chrome/services/app_service/README.md
class LaunchService : public KeyedService {
public:
static LaunchService* Get(Profile* profile);
explicit LaunchService(Profile* profile);
~LaunchService() override;
// Attempt to open |app_id| in a new window.
bool OpenApplicationWindow(const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory);
// Attempt to open |app_id| in a new tab.
bool OpenApplicationTab(const std::string& app_id);
private:
LaunchManager& GetLaunchManagerForApp(const std::string& app_id);
Profile* const profile_;
std::unique_ptr<LaunchManager> extension_app_launch_manager_;
std::unique_ptr<LaunchManager> web_app_launch_manager_;
DISALLOW_COPY_AND_ASSIGN(LaunchService);
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/launch_service/launch_service_factory.h"
#include "chrome/browser/apps/launch_service/launch_service.h"
#include "chrome/browser/extensions/extension_system_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
namespace apps {
// static
LaunchService* LaunchServiceFactory::GetForProfile(Profile* profile) {
return static_cast<LaunchService*>(
LaunchServiceFactory::GetInstance()->GetServiceForBrowserContext(
profile, true /* create */));
}
// static
LaunchServiceFactory* LaunchServiceFactory::GetInstance() {
return base::Singleton<LaunchServiceFactory>::get();
}
LaunchServiceFactory::LaunchServiceFactory()
: BrowserContextKeyedServiceFactory(
"LaunchService",
BrowserContextDependencyManager::GetInstance()) {
DependsOn(extensions::ExtensionSystemFactory::GetInstance());
}
LaunchServiceFactory::~LaunchServiceFactory() = default;
KeyedService* LaunchServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new LaunchService(Profile::FromBrowserContext(context));
}
bool LaunchServiceFactory::ServiceIsCreatedWithBrowserContext() const {
return true;
}
content::BrowserContext* LaunchServiceFactory::GetBrowserContextToUse(
content::BrowserContext* context) const {
// Do not create secondary instance for incognito WebContents with
// off-the-record profiles. Always redirect to the instance from the original
// profile part.
return Profile::FromBrowserContext(context)->GetOriginalProfile();
}
} // namespace apps
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_FACTORY_H_
#define CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_FACTORY_H_
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace content {
class BrowserContext;
}
class Profile;
namespace apps {
class LaunchService;
// A factory which associates LaunchService instance with its profile instance.
class LaunchServiceFactory : public BrowserContextKeyedServiceFactory {
public:
static LaunchService* GetForProfile(Profile* profile);
static LaunchServiceFactory* GetInstance();
private:
friend struct base::DefaultSingletonTraits<LaunchServiceFactory>;
LaunchServiceFactory();
~LaunchServiceFactory() override;
// BrowserContextKeyedServiceFactory
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
bool ServiceIsCreatedWithBrowserContext() const override;
content::BrowserContext* GetBrowserContextToUse(
content::BrowserContext* context) const override;
DISALLOW_COPY_AND_ASSIGN(LaunchServiceFactory);
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_LAUNCH_SERVICE_LAUNCH_SERVICE_FACTORY_H_
......@@ -3684,6 +3684,8 @@ jumbo_split_static_library("ui") {
"web_applications/web_app_dialog_manager.h",
"web_applications/web_app_dialog_utils.cc",
"web_applications/web_app_dialog_utils.h",
"web_applications/web_app_launch_manager.cc",
"web_applications/web_app_launch_manager.h",
"web_applications/web_app_metrics.cc",
"web_applications/web_app_metrics.h",
"web_applications/web_app_metrics_factory.cc",
......
# App-y stuff
benwells@chromium.org
per-file bookmark_app_*=alancutter@chromium.org
per-file bookmark_app_*=harrisjay@chromium.org
per-file bookmark_app_*=mgiuca@chromium.org
per-file bookmark_app_*=ortuno@chromium.org
per-file hosted_app_*=alancutter@chromium.org
per-file hosted_app_*=harrisjay@chromium.org
per-file hosted_app_*=mgiuca@chromium.org
per-file hosted_app_*=ortuno@chromium.org
per-file pwa_*=alancutter@chromium.org
per-file pwa_*=harrisjay@chromium.org
per-file pwa_*=mgiuca@chromium.org
per-file pwa_*=ortuno@chromium.org
per-file bookmark_app_*=file://chrome/browser/web_applications/UI_OWNERS
per-file hosted_app_*=file://chrome/browser/web_applications/UI_OWNERS
per-file pwa_*=file://chrome/browser/web_applications/UI_OWNERS
# Extension-y stuff
finnur@chromium.org
......
......@@ -24,6 +24,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/apps/apps_launch.h"
#include "chrome/browser/apps/launch_service/launch_service.h"
#include "chrome/browser/apps/platform_apps/install_chrome_app.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
......@@ -552,8 +553,8 @@ bool StartupBrowserCreatorImpl::OpenApplicationWindow(Profile* profile) {
// TODO(skerner): Do something reasonable here. Pop up a warning panel?
// Open an URL to the gallery page of the extension id?
if (!app_id.empty()) {
return apps::OpenApplicationWindow(profile, app_id, command_line_,
cur_dir_);
return apps::LaunchService::Get(profile)->OpenApplicationWindow(
app_id, command_line_, cur_dir_);
}
if (url_string.empty())
......@@ -585,7 +586,7 @@ bool StartupBrowserCreatorImpl::OpenApplicationTab(Profile* profile) {
if (!IsAppLaunch(nullptr, &app_id) || app_id.empty())
return false;
return apps::OpenApplicationTab(profile, app_id);
return apps::LaunchService::Get(profile)->OpenApplicationTab(app_id);
}
void StartupBrowserCreatorImpl::DetermineURLsAndLaunch(
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/web_applications/web_app_launch_manager.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/components/web_app_tab_helper_base.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "content/public/browser/render_view_host.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
namespace web_app {
namespace {
ui::WindowShowState DetermineWindowShowState() {
if (chrome::IsRunningInForcedAppMode())
return ui::SHOW_STATE_FULLSCREEN;
return ui::SHOW_STATE_DEFAULT;
}
Browser* CreateWebApplicationWindow(Profile* profile,
const std::string& app_id) {
std::string app_name = GenerateApplicationNameFromAppId(app_id);
gfx::Rect initial_bounds;
auto browser_params = Browser::CreateParams::CreateForApp(
app_name, /*trusted_source=*/true, initial_bounds, profile,
/*user_gesture=*/true);
browser_params.initial_show_state = DetermineWindowShowState();
return new Browser(browser_params);
}
void SetWebAppPrefsForWebContents(content::WebContents* web_contents) {
web_contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
web_contents->GetRenderViewHost()->SyncRendererPrefs();
web_contents->NotifyPreferencesChanged();
}
content::WebContents* ShowWebApplicationWindow(
const ::AppLaunchParams& params,
const std::string& app_id,
const GURL& launch_url,
Browser* browser,
WindowOpenDisposition disposition) {
NavigateParams nav_params(browser, launch_url,
ui::PAGE_TRANSITION_AUTO_BOOKMARK);
nav_params.disposition = disposition;
nav_params.opener = params.opener;
Navigate(&nav_params);
content::WebContents* web_contents =
nav_params.navigated_or_inserted_contents;
SetWebAppPrefsForWebContents(web_contents);
web_app::WebAppTabHelperBase* tab_helper =
web_app::WebAppTabHelperBase::FromWebContents(web_contents);
DCHECK(tab_helper);
tab_helper->SetAppId(app_id);
browser->window()->Show();
web_contents->SetInitialFocus();
return web_contents;
}
} // namespace
WebAppLaunchManager::WebAppLaunchManager(Profile* profile)
: apps::LaunchManager(profile),
provider_(web_app::WebAppProvider::Get(profile)) {}
WebAppLaunchManager::~WebAppLaunchManager() = default;
bool WebAppLaunchManager::OpenApplicationWindow(
const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) {
if (!provider_)
return false;
::AppLaunchParams params(profile(), app_id,
apps::mojom::LaunchContainer::kLaunchContainerWindow,
WindowOpenDisposition::NEW_WINDOW,
apps::mojom::AppLaunchSource::kSourceCommandLine);
params.command_line = command_line;
params.current_directory = current_directory;
provider_->on_registry_ready().Post(
FROM_HERE, base::BindOnce(&WebAppLaunchManager::OpenWebApplication,
weak_ptr_factory_.GetWeakPtr(), params));
return true;
}
bool WebAppLaunchManager::OpenApplicationTab(const std::string& app_id) {
if (!provider_)
return false;
::AppLaunchParams params(profile(), app_id,
apps::mojom::LaunchContainer::kLaunchContainerTab,
WindowOpenDisposition::NEW_FOREGROUND_TAB,
apps::mojom::AppLaunchSource::kSourceCommandLine);
// Wait for the web applications database to load.
// If the profile and WebAppLaunchManager are destroyed,
// on_registry_ready will not fire.
provider_->on_registry_ready().Post(
FROM_HERE, base::BindOnce(&WebAppLaunchManager::OpenWebApplication,
weak_ptr_factory_.GetWeakPtr(), params));
return true;
}
void WebAppLaunchManager::OpenWebApplication(const ::AppLaunchParams& params) {
if (!provider_->registrar().IsInstalled(params.app_id))
return;
Browser* browser = CreateWebApplicationWindow(params.profile, params.app_id);
ShowWebApplicationWindow(
params, params.app_id,
provider_->registrar().GetAppLaunchURL(params.app_id), browser,
WindowOpenDisposition::NEW_FOREGROUND_TAB);
}
} // namespace web_app
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_MANAGER_H_
#define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_MANAGER_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/apps/launch_service/launch_manager.h"
struct AppLaunchParams;
namespace web_app {
class WebAppProvider;
// Handles launch requests for Desktop PWAs and bookmark apps.
// Web applications have type AppType::kWeb in the app registry.
class WebAppLaunchManager : public apps::LaunchManager {
public:
explicit WebAppLaunchManager(Profile* profile);
~WebAppLaunchManager() override;
// apps::LaunchManager:
bool OpenApplicationWindow(const std::string& app_id,
const base::CommandLine& command_line,
const base::FilePath& current_directory) override;
bool OpenApplicationTab(const std::string& app_id) override;
private:
void OpenWebApplication(const AppLaunchParams& params);
WebAppProvider* const provider_;
base::WeakPtrFactory<WebAppLaunchManager> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebAppLaunchManager);
};
} // namespace web_app
#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_MANAGER_H_
alancutter@chromium.org
ericwilligers@chromium.org
harrisjay@chromium.org
loyso@chromium.org
mgiuca@chromium.org
ortuno@chromium.org
......@@ -246,6 +246,12 @@ const base::Feature kDesktopPWAsLocalUpdating{"DesktopPWAsLocalUpdating",
const base::Feature kDesktopPWAsUnifiedInstall{
"DesktopPWAsUnifiedInstall", base::FEATURE_ENABLED_BY_DEFAULT};
// Enables or disables unconditional use of new Desktop PWAs launch manager
// for all bookmark apps (including extensions-based bookmark apps).
// Only relevant if kDesktopPWAsWithoutExtensions is disabled.
const base::Feature kDesktopPWAsUnifiedLaunch{
"DesktopPWAsUnifiedLaunch", base::FEATURE_DISABLED_BY_DEFAULT};
// Enables or disables new Desktop PWAs Unified Sync and Storage (USS)
// implementation that does not use extensions. Requires
// kDesktopPWAsWithoutExtensions to be enabled.
......
......@@ -145,6 +145,9 @@ extern const base::Feature kDesktopPWAsLocalUpdating;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDesktopPWAsUnifiedInstall;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDesktopPWAsUnifiedLaunch;
COMPONENT_EXPORT(CHROME_FEATURES)
extern const base::Feature kDesktopPWAsUSS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment