Commit ac4c0f7c authored by Daniel Murphy's avatar Daniel Murphy Committed by Commit Bot

[BMO] Migrating AppLauncherHandler's app list, launch, setLaunch to BMO

This change starts the migration of the chrome://apps UI to support BMO.
1. Updates the 'population' logic to create items for WebApps fetched
   through the AppRegistrar for display in chrome://apps
2. Updates the 'launch' logic to correctly launch webapps populated
   through BMO.
3. Update the 'setLaunchType' event logic to set the display mode in the
   BMO system.
4. NOTIMPLEMENTED() calls on all methods where BMO is not supported (and
   it is turned on).

One nuance with this change is that the icons for the BMO web apps do
not display correctly in chrome://apps. This is because the icon is
pointing to the remote source of the icon, which violates the cross
origin policy of the chrome://apps page. It is currently unclear what
should be done here, so leaving that as broken for now.

A nuance on that nuance is that when BMO is not turned on, it still
serves the extensions-backed web apps through its abstraction layers.
This is good for us for testing, and allows most of the code in this
patch to be used & tested when chrome://apps is used. However, it also
means that icons for all webapps would no longer show up, given the
nuance above. So to prevent this breakage, this is special-cased (where
BMO is turned off but we are serving a web app) and the old extentions-
backed icon url is used. This allows the icon to still work when BMO is
off.

Doc:
https://docs.google.com/document/d/1BcDJHd0gEt5oImBsNbgRg7Fz9T3I-YO7KkUuSLHQSYg/edit

Bug: 1009302
Change-Id: Ib2f05e6be0b856fbe1d68adc8d1dc6ef0db6f11d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2090492Reviewed-by: default avatarcalamity <calamity@chromium.org>
Reviewed-by: default avatarAlexey Baskakov <loyso@chromium.org>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756717}
parent 78ea531d
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
#include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h" #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h"
#include "chrome/browser/ui/webui/theme_handler.h" #include "chrome/browser/ui/webui/theme_handler.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h" #include "chrome/grit/theme_resources.h"
...@@ -42,9 +43,13 @@ AppLauncherPageUI::AppLauncherPageUI(content::WebUI* web_ui) ...@@ -42,9 +43,13 @@ AppLauncherPageUI::AppLauncherPageUI(content::WebUI* web_ui)
if (!GetProfile()->IsOffTheRecord()) { if (!GetProfile()->IsOffTheRecord()) {
extensions::ExtensionService* service = extensions::ExtensionService* service =
extensions::ExtensionSystem::Get(GetProfile())->extension_service(); extensions::ExtensionSystem::Get(GetProfile())->extension_service();
// We should not be launched without an ExtensionService. web_app::WebAppProvider* web_app_provider =
web_app::WebAppProvider::Get(GetProfile());
DCHECK(web_app_provider);
DCHECK(service); DCHECK(service);
web_ui->AddMessageHandler(std::make_unique<AppLauncherHandler>(service)); // We should not be launched without an ExtensionService or WebAppProvider.
web_ui->AddMessageHandler(
std::make_unique<AppLauncherHandler>(service, web_app_provider));
web_ui->AddMessageHandler(std::make_unique<CoreAppLauncherHandler>()); web_ui->AddMessageHandler(std::make_unique<CoreAppLauncherHandler>());
web_ui->AddMessageHandler(std::make_unique<AppIconWebUIHandler>()); web_ui->AddMessageHandler(std::make_unique<AppIconWebUIHandler>());
web_ui->AddMessageHandler(std::make_unique<MetricsHandler>()); web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
...@@ -146,4 +151,4 @@ std::string AppLauncherPageUI::HTMLSource::GetContentSecurityPolicyImgSrc() { ...@@ -146,4 +151,4 @@ std::string AppLauncherPageUI::HTMLSource::GetContentSecurityPolicyImgSrc() {
"data:;"; "data:;";
} }
AppLauncherPageUI::HTMLSource::~HTMLSource() {} AppLauncherPageUI::HTMLSource::~HTMLSource() = default;
...@@ -80,12 +80,17 @@ GURL ExtensionIconSource::GetIconURL(const Extension* extension, ...@@ -80,12 +80,17 @@ GURL ExtensionIconSource::GetIconURL(const Extension* extension,
int icon_size, int icon_size,
ExtensionIconSet::MatchType match, ExtensionIconSet::MatchType match,
bool grayscale) { bool grayscale) {
GURL icon_url(base::StringPrintf("%s%s/%d/%d%s", return GetIconURL(extension->id(), icon_size, match, grayscale);
chrome::kChromeUIExtensionIconURL, }
extension->id().c_str(),
icon_size, // static
match, GURL ExtensionIconSource::GetIconURL(const std::string& extension_id,
grayscale ? "?grayscale=true" : "")); int icon_size,
ExtensionIconSet::MatchType match,
bool grayscale) {
GURL icon_url(base::StringPrintf(
"%s%s/%d/%d%s", chrome::kChromeUIExtensionIconURL, extension_id.c_str(),
icon_size, match, grayscale ? "?grayscale=true" : ""));
CHECK(icon_url.is_valid()); CHECK(icon_url.is_valid());
return icon_url; return icon_url;
} }
......
...@@ -62,6 +62,10 @@ class ExtensionIconSource : public content::URLDataSource, ...@@ -62,6 +62,10 @@ class ExtensionIconSource : public content::URLDataSource,
int icon_size, int icon_size,
ExtensionIconSet::MatchType match, ExtensionIconSet::MatchType match,
bool grayscale); bool grayscale);
static GURL GetIconURL(const std::string& extension_id,
int icon_size,
ExtensionIconSet::MatchType match,
bool grayscale);
// A public utility function for accessing the bitmap of the image specified // A public utility function for accessing the bitmap of the image specified
// by |resource_id|. // by |resource_id|.
......
...@@ -14,9 +14,12 @@ ...@@ -14,9 +14,12 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
...@@ -45,11 +48,16 @@ ...@@ -45,11 +48,16 @@
#include "chrome/browser/ui/webui/extensions/extension_basic_info.h" #include "chrome/browser/ui/webui/extensions/extension_basic_info.h"
#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
#include "chrome/browser/ui/webui/ntp/new_tab_ui.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
#include "chrome/browser/web_applications/components/app_registry_controller.h"
#include "chrome/browser/web_applications/components/file_handler_manager.h" #include "chrome/browser/web_applications/components/file_handler_manager.h"
#include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_finalizer_utils.h" #include "chrome/browser/web_applications/extensions/bookmark_app_finalizer_utils.h"
#include "chrome/browser/web_applications/extensions/bookmark_app_util.h" #include "chrome/browser/web_applications/extensions/bookmark_app_util.h"
#include "chrome/browser/web_applications/web_app_icon_manager.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/buildflags.h" #include "chrome/common/buildflags.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_metrics.h" #include "chrome/common/extensions/extension_metrics.h"
...@@ -102,15 +110,56 @@ enum { ...@@ -102,15 +110,56 @@ enum {
APPS_PAGE_ID = 2 << kPageIdOffset, APPS_PAGE_ID = 2 << kPageIdOffset,
}; };
// Keys in the dictionary returned by GetExtensionBasicInfo().
const char kDescriptionKey[] = "description";
const char kEnabledKey[] = "enabled";
const char kInfoIdKey[] = "id";
const char kInfoNameKey[] = "name";
const char kKioskEnabledKey[] = "kioskEnabled";
const char kKioskOnlyKey[] = "kioskOnly";
const char kOfflineEnabledKey[] = "offlineEnabled";
const char kPackagedAppKey[] = "packagedApp";
const int kWebAppIconLargeNonDefault = 128;
const int kWebAppIconSmallNonDefault = 16;
void GetWebAppBasicInfo(const web_app::AppId& app_id,
const web_app::AppRegistrar& app_registrar,
base::DictionaryValue* info) {
info->SetString(kInfoIdKey, app_id);
info->SetString(kInfoNameKey, app_registrar.GetAppShortName(app_id));
info->SetBoolean(kEnabledKey, true);
info->SetBoolean(kKioskEnabledKey, false);
info->SetBoolean(kKioskOnlyKey, false);
info->SetBoolean(kOfflineEnabledKey, true);
info->SetString(kDescriptionKey, app_registrar.GetAppDescription(app_id));
info->SetBoolean(kPackagedAppKey, false);
}
bool DesktopPWAsWithoutExtensions() {
return base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions);
}
bool HasMatchingOrGreaterThanIcon(
const std::vector<WebApplicationIconInfo>& icon_infos,
int pixels) {
for (const auto& icon : icon_infos) {
if (icon.square_size_px >= pixels)
return true;
}
return false;
}
} // namespace } // namespace
AppLauncherHandler::AppInstallInfo::AppInstallInfo() {} AppLauncherHandler::AppInstallInfo::AppInstallInfo() {}
AppLauncherHandler::AppInstallInfo::~AppInstallInfo() {} AppLauncherHandler::AppInstallInfo::~AppInstallInfo() {}
AppLauncherHandler::AppLauncherHandler( AppLauncherHandler::AppLauncherHandler(
extensions::ExtensionService* extension_service) extensions::ExtensionService* extension_service,
web_app::WebAppProvider* web_app_provider)
: extension_service_(extension_service), : extension_service_(extension_service),
web_app_provider_(web_app_provider),
ignore_changes_(false), ignore_changes_(false),
attempted_bookmark_app_install_(false), attempted_bookmark_app_install_(false),
has_loaded_apps_(false) {} has_loaded_apps_(false) {}
...@@ -119,9 +168,103 @@ AppLauncherHandler::~AppLauncherHandler() { ...@@ -119,9 +168,103 @@ AppLauncherHandler::~AppLauncherHandler() {
ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this); ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this);
} }
void AppLauncherHandler::CreateAppInfo(const Extension* extension, void AppLauncherHandler::CreateWebAppInfo(const web_app::AppId& app_id,
extensions::ExtensionService* service, base::DictionaryValue* value) {
base::DictionaryValue* value) { // The items which are to be written into |value| are also described in
// chrome/browser/resources/ntp4/page_list_view.js in @typedef for AppInfo.
// Please update it whenever you add or remove any keys here.
value->Clear();
// Communicate the kiosk flag so the apps page can disable showing the
// context menu in kiosk mode.
value->SetBoolean(
"kioskMode",
base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode));
auto& registrar = web_app_provider_->registrar();
base::string16 name = base::UTF8ToUTF16(registrar.GetAppShortName(app_id));
NewTabUI::SetUrlTitleAndDirection(value, name,
registrar.GetAppLaunchURL(app_id));
NewTabUI::SetFullNameAndDirection(name, value);
GetWebAppBasicInfo(app_id, registrar, value);
bool is_locally_installed = registrar.IsLocallyInstalled(app_id);
value->SetBoolean("mayChangeLaunchType", is_locally_installed);
// Any locally installed app can have shortcuts created.
value->SetBoolean("mayCreateShortcuts", is_locally_installed);
value->SetBoolean("isLocallyInstalled", is_locally_installed);
base::Optional<std::string> icon_big;
base::Optional<std::string> icon_small;
// TODO(https://crbug.com/1062081): Figure out how to serve icons for web apps
// when BMO is enabled.
if (!DesktopPWAsWithoutExtensions()) {
// This is a hack to allow extensions-backed webapps to continue to have an
// icon.
if (HasMatchingOrGreaterThanIcon(registrar.GetAppIconInfos(app_id),
kWebAppIconLargeNonDefault)) {
icon_big = extensions::ExtensionIconSource::GetIconURL(
app_id, kWebAppIconLargeNonDefault,
ExtensionIconSet::MATCH_BIGGER, false)
.spec();
}
if (HasMatchingOrGreaterThanIcon(registrar.GetAppIconInfos(app_id),
kWebAppIconSmallNonDefault)) {
icon_small = extensions::ExtensionIconSource::GetIconURL(
app_id, kWebAppIconSmallNonDefault,
ExtensionIconSet::MATCH_BIGGER, false)
.spec();
}
}
value->SetBoolean("icon_big_exists", icon_big.has_value());
value->SetString("icon_big", icon_big.value_or(GURL().spec()));
// TODO(https://crbug.com/1062081): Figure out how to serve icons.
value->SetBoolean("icon_small_exists", icon_small.has_value());
value->SetString("icon_small", icon_small.value_or(GURL().spec()));
extensions::LaunchContainerAndType result =
extensions::GetLaunchContainerAndTypeFromDisplayMode(
registrar.GetAppUserDisplayMode(app_id));
value->SetInteger("launch_container",
static_cast<int>(result.launch_container));
value->SetInteger("launch_type", result.launch_type);
value->SetBoolean("is_component", false);
value->SetBoolean("is_webstore", false);
// TODO(https://crbug.com/1061586): Figure out a way to keep the AppSorting
// system compatible with web apps.
DCHECK_NE(app_id, extensions::kWebStoreAppId);
AppSorting* sorting =
ExtensionSystem::Get(Profile::FromWebUI(web_ui()))->app_sorting();
syncer::StringOrdinal page_ordinal = sorting->GetPageOrdinal(app_id);
if (!page_ordinal.IsValid()) {
// Make sure every app has a page ordinal (some predate the page ordinal).
page_ordinal = sorting->GetNaturalAppPageOrdinal();
sorting->SetPageOrdinal(app_id, page_ordinal);
}
value->SetInteger("page_index",
sorting->PageStringOrdinalAsInteger(page_ordinal));
syncer::StringOrdinal app_launch_ordinal =
sorting->GetAppLaunchOrdinal(app_id);
if (!app_launch_ordinal.IsValid()) {
// Make sure every app has a launch ordinal (some predate the launch
// ordinal).
app_launch_ordinal = sorting->CreateNextAppLaunchOrdinal(page_ordinal);
sorting->SetAppLaunchOrdinal(app_id, app_launch_ordinal);
}
value->SetString("app_launch_ordinal", app_launch_ordinal.ToInternalValue());
}
void AppLauncherHandler::CreateExtensionInfo(const Extension* extension,
base::DictionaryValue* value) {
DCHECK(!extension->from_bookmark());
// The items which are to be written into |value| are also described in // The items which are to be written into |value| are also described in
// chrome/browser/resources/ntp4/page_list_view.js in @typedef for AppInfo. // chrome/browser/resources/ntp4/page_list_view.js in @typedef for AppInfo.
// Please update it whenever you add or remove any keys here. // Please update it whenever you add or remove any keys here.
...@@ -146,21 +289,22 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension, ...@@ -146,21 +289,22 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension,
base::i18n::UnadjustStringForLocaleDirection(&name); base::i18n::UnadjustStringForLocaleDirection(&name);
NewTabUI::SetFullNameAndDirection(name, value); NewTabUI::SetFullNameAndDirection(name, value);
bool enabled = bool enabled = extension_service_->IsExtensionEnabled(extension->id()) &&
service->IsExtensionEnabled(extension->id()) && !extensions::ExtensionRegistry::Get(
!extensions::ExtensionRegistry::Get(service->GetBrowserContext()) extension_service_->GetBrowserContext())
->terminated_extensions() ->terminated_extensions()
.GetByID(extension->id()); .GetByID(extension->id());
extensions::GetExtensionBasicInfo(extension, enabled, value); extensions::GetExtensionBasicInfo(extension, enabled, value);
value->SetBoolean("mayDisable", value->SetBoolean(
extensions::ExtensionSystem::Get(service->profile()) "mayDisable",
->management_policy() extensions::ExtensionSystem::Get(extension_service_->profile())
->UserMayModifySettings(extension, nullptr)); ->management_policy()
->UserMayModifySettings(extension, nullptr));
bool is_locally_installed = bool is_locally_installed =
!extension->is_hosted_app() || !extension->is_hosted_app() ||
BookmarkAppIsLocallyInstalled(service->profile(), extension); BookmarkAppIsLocallyInstalled(extension_service_->profile(), extension);
value->SetBoolean("mayChangeLaunchType", value->SetBoolean("mayChangeLaunchType",
!extension->is_platform_app() && is_locally_installed); !extension->is_platform_app() && is_locally_installed);
...@@ -191,14 +335,15 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension, ...@@ -191,14 +335,15 @@ void AppLauncherHandler::CreateAppInfo(const Extension* extension,
"launch_container", "launch_container",
static_cast<int>( static_cast<int>(
extensions::AppLaunchInfo::GetLaunchContainer(extension))); extensions::AppLaunchInfo::GetLaunchContainer(extension)));
ExtensionPrefs* prefs = ExtensionPrefs::Get(service->profile()); ExtensionPrefs* prefs = ExtensionPrefs::Get(extension_service_->profile());
value->SetInteger("launch_type", extensions::GetLaunchType(prefs, extension)); value->SetInteger("launch_type", extensions::GetLaunchType(prefs, extension));
value->SetBoolean("is_component", value->SetBoolean("is_component",
extension->location() == extensions::Manifest::COMPONENT); extension->location() == extensions::Manifest::COMPONENT);
value->SetBoolean("is_webstore", value->SetBoolean("is_webstore",
extension->id() == extensions::kWebStoreAppId); extension->id() == extensions::kWebStoreAppId);
AppSorting* sorting = ExtensionSystem::Get(service->profile())->app_sorting(); AppSorting* sorting =
ExtensionSystem::Get(extension_service_->profile())->app_sorting();
syncer::StringOrdinal page_ordinal = sorting->GetPageOrdinal(extension->id()); syncer::StringOrdinal page_ordinal = sorting->GetPageOrdinal(extension->id());
if (!page_ordinal.IsValid()) { if (!page_ordinal.IsValid()) {
// Make sure every app has a page ordinal (some predate the page ordinal). // Make sure every app has a page ordinal (some predate the page ordinal).
...@@ -307,18 +452,20 @@ void AppLauncherHandler::Observe(int type, ...@@ -307,18 +452,20 @@ void AppLauncherHandler::Observe(int type,
const std::string* id = const std::string* id =
content::Details<const std::string>(details).ptr(); content::Details<const std::string>(details).ptr();
if (id) { if (id) {
const Extension* extension =
ExtensionRegistry::Get(extension_service_->profile())
->GetInstalledExtension(*id);
if (!extension) {
// Extension could still be downloading or installing.
return;
}
base::DictionaryValue app_info; base::DictionaryValue app_info;
CreateAppInfo(extension, if (web_app_provider_->registrar().IsInstalled(*id)) {
extension_service_, CreateWebAppInfo(*id, &app_info);
&app_info); } else {
const Extension* extension =
ExtensionRegistry::Get(extension_service_->profile())
->GetInstalledExtension(*id);
if (!extension) {
// Extension could still be downloading or installing.
return;
}
CreateExtensionInfo(extension, &app_info);
}
web_ui()->CallJavascriptFunctionUnsafe("ntp.appMoved", app_info); web_ui()->CallJavascriptFunctionUnsafe("ntp.appMoved", app_info);
} else { } else {
HandleGetApps(nullptr); HandleGetApps(nullptr);
...@@ -348,7 +495,10 @@ void AppLauncherHandler::OnExtensionLoaded( ...@@ -348,7 +495,10 @@ void AppLauncherHandler::OnExtensionLoaded(
if (!ShouldShow(extension)) if (!ShouldShow(extension))
return; return;
std::unique_ptr<base::DictionaryValue> app_info(GetAppInfo(extension)); if (extension->from_bookmark())
return;
std::unique_ptr<base::DictionaryValue> app_info(GetExtensionInfo(extension));
if (!app_info.get()) if (!app_info.get())
return; return;
...@@ -364,31 +514,75 @@ void AppLauncherHandler::OnExtensionUnloaded( ...@@ -364,31 +514,75 @@ void AppLauncherHandler::OnExtensionUnloaded(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension, const Extension* extension,
extensions::UnloadedExtensionReason reason) { extensions::UnloadedExtensionReason reason) {
AppRemoved(extension, false); // Exclude events from bookmarks apps if BMO is turned on.
if (extension->from_bookmark())
return;
ExtensionRemoved(extension, /*is_uninstall=*/false);
} }
void AppLauncherHandler::OnExtensionUninstalled( void AppLauncherHandler::OnExtensionUninstalled(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const Extension* extension, const Extension* extension,
extensions::UninstallReason reason) { extensions::UninstallReason reason) {
AppRemoved(extension, true); // Exclude events from bookmarks apps if BMO is turned on.
if (extension->from_bookmark())
return;
ExtensionRemoved(extension, /*is_uninstall=*/true);
}
void AppLauncherHandler::OnWebAppInstalled(const web_app::AppId& app_id) {
std::unique_ptr<base::DictionaryValue> app_info(
GetWebAppInfo(app_id, web_app_provider_->registrar()));
if (!app_info.get())
return;
visible_apps_.insert(app_id);
base::Value highlight(attempted_bookmark_app_install_);
attempted_bookmark_app_install_ = false;
web_ui()->CallJavascriptFunctionUnsafe("ntp.appAdded", *app_info, highlight);
}
void AppLauncherHandler::OnWebAppWillBeUninstalled(
const web_app::AppId& app_id) {
std::unique_ptr<base::DictionaryValue> app_info =
std::make_unique<base::DictionaryValue>();
app_info->SetString(kInfoIdKey, app_id);
// Since |isUninstaLL| is true below, the only item needed in the app_info
// dictionary is the id.
web_ui()->CallJavascriptFunctionUnsafe(
"ntp.appRemoved", *app_info, /*isUninstall=*/base::Value(true),
base::Value(!extension_id_prompting_.empty()));
}
void AppLauncherHandler::OnAppRegistrarDestroyed() {
web_apps_observer_.RemoveAll();
} }
void AppLauncherHandler::FillAppDictionary(base::DictionaryValue* dictionary) { void AppLauncherHandler::FillAppDictionary(base::DictionaryValue* dictionary) {
// CreateAppInfo and ClearOrdinals can change the extension prefs. // CreateExtensionInfo and ClearOrdinals can change the extension prefs.
base::AutoReset<bool> auto_reset(&ignore_changes_, true); base::AutoReset<bool> auto_reset(&ignore_changes_, true);
auto installed_extensions = std::make_unique<base::ListValue>(); auto installed_extensions = std::make_unique<base::ListValue>();
Profile* profile = Profile::FromWebUI(web_ui()); Profile* profile = Profile::FromWebUI(web_ui());
PrefService* prefs = profile->GetPrefs(); PrefService* prefs = profile->GetPrefs();
std::set<web_app::AppId> web_app_ids;
web_app::AppRegistrar& registrar = web_app_provider_->registrar();
for (const web_app::AppId& web_app_id : registrar.GetAppIds()) {
installed_extensions->Append(GetWebAppInfo(web_app_id, registrar));
web_app_ids.insert(web_app_id);
}
ExtensionRegistry* registry = ExtensionRegistry* registry =
ExtensionRegistry::Get(extension_service_->profile()); ExtensionRegistry::Get(extension_service_->profile());
for (auto it = visible_apps_.begin(); it != visible_apps_.end(); ++it) { for (auto it = visible_apps_.begin(); it != visible_apps_.end(); ++it) {
if (base::Contains(web_app_ids, *it))
continue;
const Extension* extension = registry->GetInstalledExtension(*it); const Extension* extension = registry->GetInstalledExtension(*it);
if (extension && extensions::ui_util::ShouldDisplayInNewTabPage( if (extension &&
extension, profile)) { extensions::ui_util::ShouldDisplayInNewTabPage(extension, profile)) {
installed_extensions->Append(GetAppInfo(extension)); DCHECK(!extension->from_bookmark());
installed_extensions->Append(GetExtensionInfo(extension));
} }
} }
...@@ -407,12 +601,20 @@ void AppLauncherHandler::FillAppDictionary(base::DictionaryValue* dictionary) { ...@@ -407,12 +601,20 @@ void AppLauncherHandler::FillAppDictionary(base::DictionaryValue* dictionary) {
} }
} }
std::unique_ptr<base::DictionaryValue> AppLauncherHandler::GetAppInfo( std::unique_ptr<base::DictionaryValue> AppLauncherHandler::GetExtensionInfo(
const Extension* extension) { const Extension* extension) {
std::unique_ptr<base::DictionaryValue> app_info(new base::DictionaryValue()); std::unique_ptr<base::DictionaryValue> app_info(new base::DictionaryValue());
// CreateAppInfo can change the extension prefs. // CreateExtensionInfo can change the extension prefs.
base::AutoReset<bool> auto_reset(&ignore_changes_, true); base::AutoReset<bool> auto_reset(&ignore_changes_, true);
CreateAppInfo(extension, extension_service_, app_info.get()); CreateExtensionInfo(extension, app_info.get());
return app_info;
}
std::unique_ptr<base::DictionaryValue> AppLauncherHandler::GetWebAppInfo(
const web_app::AppId& app_id,
const web_app::AppRegistrar& app_registrar) {
std::unique_ptr<base::DictionaryValue> app_info(new base::DictionaryValue());
CreateWebAppInfo(app_id, app_info.get());
return app_info; return app_info;
} }
...@@ -436,18 +638,24 @@ void AppLauncherHandler::HandleGetApps(const base::ListValue* args) { ...@@ -436,18 +638,24 @@ void AppLauncherHandler::HandleGetApps(const base::ListValue* args) {
const ExtensionSet& enabled_set = registry->enabled_extensions(); const ExtensionSet& enabled_set = registry->enabled_extensions();
for (extensions::ExtensionSet::const_iterator it = enabled_set.begin(); for (extensions::ExtensionSet::const_iterator it = enabled_set.begin();
it != enabled_set.end(); ++it) { it != enabled_set.end(); ++it) {
if ((*it)->from_bookmark())
continue;
visible_apps_.insert((*it)->id()); visible_apps_.insert((*it)->id());
} }
const ExtensionSet& disabled_set = registry->disabled_extensions(); const ExtensionSet& disabled_set = registry->disabled_extensions();
for (ExtensionSet::const_iterator it = disabled_set.begin(); for (ExtensionSet::const_iterator it = disabled_set.begin();
it != disabled_set.end(); ++it) { it != disabled_set.end(); ++it) {
if ((*it)->from_bookmark())
continue;
visible_apps_.insert((*it)->id()); visible_apps_.insert((*it)->id());
} }
const ExtensionSet& terminated_set = registry->terminated_extensions(); const ExtensionSet& terminated_set = registry->terminated_extensions();
for (ExtensionSet::const_iterator it = terminated_set.begin(); for (ExtensionSet::const_iterator it = terminated_set.begin();
it != terminated_set.end(); ++it) { it != terminated_set.end(); ++it) {
if ((*it)->from_bookmark())
continue;
visible_apps_.insert((*it)->id()); visible_apps_.insert((*it)->id());
} }
} }
...@@ -477,6 +685,7 @@ void AppLauncherHandler::HandleGetApps(const base::ListValue* args) { ...@@ -477,6 +685,7 @@ void AppLauncherHandler::HandleGetApps(const base::ListValue* args) {
registrar_.Add(this, registrar_.Add(this,
extensions::NOTIFICATION_EXTENSION_LOAD_ERROR, extensions::NOTIFICATION_EXTENSION_LOAD_ERROR,
content::Source<Profile>(profile)); content::Source<Profile>(profile));
web_apps_observer_.Add(&web_app_provider_->registrar());
} }
has_loaded_apps_ = true; has_loaded_apps_ = true;
...@@ -497,14 +706,31 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { ...@@ -497,14 +706,31 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) {
Profile* profile = extension_service_->profile(); Profile* profile = extension_service_->profile();
const Extension* extension = extensions::Manifest::Type type;
extensions::ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( GURL full_launch_url;
extension_id); apps::mojom::LaunchContainer launch_container;
// Prompt the user to re-enable the application if disabled. web_app::AppRegistrar& registrar = web_app_provider_->registrar();
if (!extension) { if (registrar.IsInstalled(extension_id)) {
PromptToEnableApp(extension_id); type = extensions::Manifest::Type::TYPE_HOSTED_APP;
return; full_launch_url = registrar.GetAppLaunchURL(extension_id);
launch_container = web_app::ConvertDisplayModeToAppLaunchContainer(
registrar.GetAppEffectiveDisplayMode(extension_id));
} else {
const Extension* extension = extensions::ExtensionRegistry::Get(profile)
->enabled_extensions()
.GetByID(extension_id);
// Prompt the user to re-enable the application if disabled.
if (!extension) {
PromptToEnableApp(extension_id);
return;
}
DCHECK(!extension->from_bookmark());
type = extension->GetType();
full_launch_url = extensions::AppLaunchInfo::GetFullLaunchURL(extension);
launch_container =
extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension);
} }
WindowOpenDisposition disposition = WindowOpenDisposition disposition =
...@@ -512,7 +738,7 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { ...@@ -512,7 +738,7 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) {
: WindowOpenDisposition::CURRENT_TAB; : WindowOpenDisposition::CURRENT_TAB;
if (extension_id != extensions::kWebStoreAppId) { if (extension_id != extensions::kWebStoreAppId) {
CHECK_NE(launch_bucket, extension_misc::APP_LAUNCH_BUCKET_INVALID); CHECK_NE(launch_bucket, extension_misc::APP_LAUNCH_BUCKET_INVALID);
extensions::RecordAppLaunchType(launch_bucket, extension->GetType()); extensions::RecordAppLaunchType(launch_bucket, type);
} else { } else {
extensions::RecordWebStoreLaunch(); extensions::RecordWebStoreLaunch();
...@@ -521,8 +747,8 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { ...@@ -521,8 +747,8 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) {
CHECK(args->GetString(2, &source_value)); CHECK(args->GetString(2, &source_value));
if (!source_value.empty()) { if (!source_value.empty()) {
override_url = net::AppendQueryParameter( override_url = net::AppendQueryParameter(
extensions::AppLaunchInfo::GetFullLaunchURL(extension), full_launch_url, extension_urls::kWebstoreSourceField,
extension_urls::kWebstoreSourceField, source_value); source_value);
} }
} }
} }
...@@ -550,8 +776,8 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { ...@@ -550,8 +776,8 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) {
if (browser) if (browser)
old_contents = browser->tab_strip_model()->GetActiveWebContents(); old_contents = browser->tab_strip_model()->GetActiveWebContents();
apps::AppLaunchParams params = CreateAppLaunchParamsUserContainer( apps::AppLaunchParams params(
profile, extension, extension_id, launch_container,
old_contents ? WindowOpenDisposition::CURRENT_TAB old_contents ? WindowOpenDisposition::CURRENT_TAB
: WindowOpenDisposition::NEW_FOREGROUND_TAB, : WindowOpenDisposition::NEW_FOREGROUND_TAB,
extensions::AppLaunchSource::kSourceNewTabPage); extensions::AppLaunchSource::kSourceNewTabPage);
...@@ -570,32 +796,64 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { ...@@ -570,32 +796,64 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) {
} }
void AppLauncherHandler::HandleSetLaunchType(const base::ListValue* args) { void AppLauncherHandler::HandleSetLaunchType(const base::ListValue* args) {
std::string extension_id; std::string app_id;
double launch_type; double launch_type_double;
CHECK(args->GetString(0, &extension_id)); CHECK(args->GetString(0, &app_id));
CHECK(args->GetDouble(1, &launch_type)); CHECK(args->GetDouble(1, &launch_type_double));
extensions::LaunchType launch_type =
static_cast<extensions::LaunchType>(static_cast<int>(launch_type_double));
if (web_app_provider_->registrar().IsInstalled(app_id)) {
// Don't update the page; it already knows about the launch type change.
base::AutoReset<bool> auto_reset(&ignore_changes_, true);
web_app::DisplayMode display_mode = web_app::DisplayMode::kBrowser;
switch (launch_type) {
case extensions::LAUNCH_TYPE_FULLSCREEN:
display_mode = web_app::DisplayMode::kFullscreen;
break;
case extensions::LAUNCH_TYPE_WINDOW:
display_mode = web_app::DisplayMode::kStandalone;
break;
case extensions::LAUNCH_TYPE_PINNED:
case extensions::LAUNCH_TYPE_REGULAR:
display_mode = web_app::DisplayMode::kBrowser;
break;
case extensions::LAUNCH_TYPE_INVALID:
case extensions::NUM_LAUNCH_TYPES:
NOTREACHED();
break;
}
web_app_provider_->registry_controller().SetAppUserDisplayMode(
app_id, display_mode);
return;
}
const Extension* extension = const Extension* extension =
extensions::ExtensionRegistry::Get(extension_service_->profile()) extensions::ExtensionRegistry::Get(extension_service_->profile())
->GetExtensionById(extension_id, ->GetExtensionById(app_id,
extensions::ExtensionRegistry::ENABLED | extensions::ExtensionRegistry::ENABLED |
extensions::ExtensionRegistry::DISABLED | extensions::ExtensionRegistry::DISABLED |
extensions::ExtensionRegistry::TERMINATED); extensions::ExtensionRegistry::TERMINATED);
if (!extension) if (!extension)
return; return;
DCHECK(!extension->from_bookmark());
// Don't update the page; it already knows about the launch type change. // Don't update the page; it already knows about the launch type change.
base::AutoReset<bool> auto_reset(&ignore_changes_, true); base::AutoReset<bool> auto_reset(&ignore_changes_, true);
extensions::SetLaunchType(Profile::FromWebUI(web_ui()), app_id, launch_type);
extensions::SetLaunchType(
Profile::FromWebUI(web_ui()), extension_id,
static_cast<extensions::LaunchType>(static_cast<int>(launch_type)));
} }
void AppLauncherHandler::HandleUninstallApp(const base::ListValue* args) { void AppLauncherHandler::HandleUninstallApp(const base::ListValue* args) {
std::string extension_id; std::string extension_id;
CHECK(args->GetString(0, &extension_id)); CHECK(args->GetString(0, &extension_id));
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id)) {
NOTIMPLEMENTED();
return;
}
const Extension* extension = const Extension* extension =
ExtensionRegistry::Get(extension_service_->profile()) ExtensionRegistry::Get(extension_service_->profile())
->GetInstalledExtension(extension_id); ->GetInstalledExtension(extension_id);
...@@ -633,6 +891,12 @@ void AppLauncherHandler::HandleCreateAppShortcut(const base::ListValue* args) { ...@@ -633,6 +891,12 @@ void AppLauncherHandler::HandleCreateAppShortcut(const base::ListValue* args) {
std::string extension_id; std::string extension_id;
CHECK(args->GetString(0, &extension_id)); CHECK(args->GetString(0, &extension_id));
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id)) {
NOTIMPLEMENTED();
return;
}
const Extension* extension = const Extension* extension =
extensions::ExtensionRegistry::Get(extension_service_->profile()) extensions::ExtensionRegistry::Get(extension_service_->profile())
->GetExtensionById(extension_id, ->GetExtensionById(extension_id,
...@@ -653,6 +917,12 @@ void AppLauncherHandler::HandleInstallAppLocally(const base::ListValue* args) { ...@@ -653,6 +917,12 @@ void AppLauncherHandler::HandleInstallAppLocally(const base::ListValue* args) {
std::string extension_id; std::string extension_id;
CHECK(args->GetString(0, &extension_id)); CHECK(args->GetString(0, &extension_id));
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id)) {
NOTIMPLEMENTED();
return;
}
const Extension* extension = const Extension* extension =
extensions::ExtensionRegistry::Get(extension_service_->profile()) extensions::ExtensionRegistry::Get(extension_service_->profile())
->GetExtensionById(extension_id, ->GetExtensionById(extension_id,
...@@ -674,7 +944,7 @@ void AppLauncherHandler::HandleInstallAppLocally(const base::ListValue* args) { ...@@ -674,7 +944,7 @@ void AppLauncherHandler::HandleInstallAppLocally(const base::ListValue* args) {
} }
// Use the appAdded to update the app icon's color to no longer be greyscale. // Use the appAdded to update the app icon's color to no longer be greyscale.
std::unique_ptr<base::DictionaryValue> app_info(GetAppInfo(extension)); std::unique_ptr<base::DictionaryValue> app_info(GetExtensionInfo(extension));
if (app_info) if (app_info)
web_ui()->CallJavascriptFunctionUnsafe("ntp.appAdded", *app_info); web_ui()->CallJavascriptFunctionUnsafe("ntp.appAdded", *app_info);
} }
...@@ -683,6 +953,12 @@ void AppLauncherHandler::HandleShowAppInfo(const base::ListValue* args) { ...@@ -683,6 +953,12 @@ void AppLauncherHandler::HandleShowAppInfo(const base::ListValue* args) {
std::string extension_id; std::string extension_id;
CHECK(args->GetString(0, &extension_id)); CHECK(args->GetString(0, &extension_id));
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id)) {
NOTIMPLEMENTED();
return;
}
const Extension* extension = const Extension* extension =
extensions::ExtensionRegistry::Get(extension_service_->profile()) extensions::ExtensionRegistry::Get(extension_service_->profile())
->GetExtensionById(extension_id, ->GetExtensionById(extension_id,
...@@ -858,6 +1134,12 @@ void AppLauncherHandler::PromptToEnableApp(const std::string& extension_id) { ...@@ -858,6 +1134,12 @@ void AppLauncherHandler::PromptToEnableApp(const std::string& extension_id) {
if (!extension_id_prompting_.empty()) if (!extension_id_prompting_.empty())
return; // Only one prompt at a time. return; // Only one prompt at a time.
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id_prompting_)) {
NOTIMPLEMENTED();
return;
}
extension_id_prompting_ = extension_id; extension_id_prompting_ = extension_id;
extension_enable_flow_ = std::make_unique<ExtensionEnableFlow>( extension_enable_flow_ = std::make_unique<ExtensionEnableFlow>(
Profile::FromWebUI(web_ui()), extension_id, this); Profile::FromWebUI(web_ui()), extension_id, this);
...@@ -896,6 +1178,12 @@ void AppLauncherHandler::ExtensionEnableFlowFinished() { ...@@ -896,6 +1178,12 @@ void AppLauncherHandler::ExtensionEnableFlowFinished() {
void AppLauncherHandler::ExtensionEnableFlowAborted(bool user_initiated) { void AppLauncherHandler::ExtensionEnableFlowAborted(bool user_initiated) {
DCHECK_EQ(extension_id_prompting_, extension_enable_flow_->extension_id()); DCHECK_EQ(extension_id_prompting_, extension_enable_flow_->extension_id());
if (DesktopPWAsWithoutExtensions() &&
web_app_provider_->registrar().IsInstalled(extension_id_prompting_)) {
NOTIMPLEMENTED();
return;
}
// We record the histograms here because ExtensionUninstallCanceled is also // We record the histograms here because ExtensionUninstallCanceled is also
// called when the extension uninstall dialog is canceled. // called when the extension uninstall dialog is canceled.
const Extension* extension = const Extension* extension =
...@@ -923,12 +1211,13 @@ AppLauncherHandler::CreateExtensionUninstallDialog() { ...@@ -923,12 +1211,13 @@ AppLauncherHandler::CreateExtensionUninstallDialog() {
return extension_uninstall_dialog_.get(); return extension_uninstall_dialog_.get();
} }
void AppLauncherHandler::AppRemoved(const Extension* extension, void AppLauncherHandler::ExtensionRemoved(const Extension* extension,
bool is_uninstall) { bool is_uninstall) {
DCHECK(!extension->from_bookmark());
if (!ShouldShow(extension)) if (!ShouldShow(extension))
return; return;
std::unique_ptr<base::DictionaryValue> app_info(GetAppInfo(extension)); std::unique_ptr<base::DictionaryValue> app_info(GetExtensionInfo(extension));
if (!app_info.get()) if (!app_info.get())
return; return;
......
...@@ -10,9 +10,13 @@ ...@@ -10,9 +10,13 @@
#include <string> #include <string>
#include "base/macros.h" #include "base/macros.h"
#include "base/scoped_observer.h"
#include "base/task/cancelable_task_tracker.h" #include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h"
#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h" #include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
#include "chrome/browser/web_applications/components/app_registrar.h"
#include "chrome/browser/web_applications/components/app_registrar_observer.h"
#include "chrome/browser/web_applications/components/web_app_id.h"
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "components/favicon/core/favicon_service.h" #include "components/favicon/core/favicon_service.h"
#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_change_registrar.h"
...@@ -29,7 +33,7 @@ class Profile; ...@@ -29,7 +33,7 @@ class Profile;
namespace extensions { namespace extensions {
class ExtensionService; class ExtensionService;
} } // namespace extensions
namespace favicon_base { namespace favicon_base {
struct FaviconImageResult; struct FaviconImageResult;
...@@ -39,25 +43,32 @@ namespace user_prefs { ...@@ -39,25 +43,32 @@ namespace user_prefs {
class PrefRegistrySyncable; class PrefRegistrySyncable;
} }
namespace web_app {
class WebAppProvider;
} // namespace web_app
// The handler for Javascript messages related to the "apps" view. // The handler for Javascript messages related to the "apps" view.
class AppLauncherHandler class AppLauncherHandler
: public content::WebUIMessageHandler, : public content::WebUIMessageHandler,
public extensions::ExtensionUninstallDialog::Delegate, public extensions::ExtensionUninstallDialog::Delegate,
public ExtensionEnableFlowDelegate, public ExtensionEnableFlowDelegate,
public content::NotificationObserver, public content::NotificationObserver,
public web_app::AppRegistrarObserver,
public extensions::ExtensionRegistryObserver { public extensions::ExtensionRegistryObserver {
public: public:
explicit AppLauncherHandler(extensions::ExtensionService* extension_service); AppLauncherHandler(extensions::ExtensionService* extension_service,
web_app::WebAppProvider* web_app_provider);
~AppLauncherHandler() override; ~AppLauncherHandler() override;
// Populate a dictionary with the information from an extension. void CreateWebAppInfo(const web_app::AppId& app_id,
static void CreateAppInfo(const extensions::Extension* extension, base::DictionaryValue* value);
extensions::ExtensionService* service,
base::DictionaryValue* value); void CreateExtensionInfo(const extensions::Extension* extension,
base::DictionaryValue* value);
// Registers values (strings etc.) for the page. // Registers values (strings etc.) for the page.
static void GetLocalizedValues(Profile* profile, static void GetLocalizedValues(Profile* profile,
base::DictionaryValue* values); base::DictionaryValue* values);
// Register per-profile preferences. // Register per-profile preferences.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
...@@ -80,14 +91,23 @@ class AppLauncherHandler ...@@ -80,14 +91,23 @@ class AppLauncherHandler
const extensions::Extension* extension, const extensions::Extension* extension,
extensions::UninstallReason reason) override; extensions::UninstallReason reason) override;
// web_app::AppRegistrarObserver:
void OnWebAppInstalled(const web_app::AppId& app_id) override;
void OnWebAppWillBeUninstalled(const web_app::AppId& app_id) override;
void OnAppRegistrarDestroyed() override;
// Populate the given dictionary with all installed app info. // Populate the given dictionary with all installed app info.
void FillAppDictionary(base::DictionaryValue* value); void FillAppDictionary(base::DictionaryValue* value);
// Create a dictionary value for the given extension. May return null, e.g. if // Create a dictionary value for the given extension.
// the given extension is not an app. std::unique_ptr<base::DictionaryValue> GetExtensionInfo(
std::unique_ptr<base::DictionaryValue> GetAppInfo(
const extensions::Extension* extension); const extensions::Extension* extension);
// Create a dictionary value for the given web app.
std::unique_ptr<base::DictionaryValue> GetWebAppInfo(
const web_app::AppId& app_id,
const web_app::AppRegistrar& app_registrar);
// Populate the given dictionary with the web store promo content. // Populate the given dictionary with the web store promo content.
void FillPromoDictionary(base::DictionaryValue* value); void FillPromoDictionary(base::DictionaryValue* value);
...@@ -181,8 +201,10 @@ class AppLauncherHandler ...@@ -181,8 +201,10 @@ class AppLauncherHandler
void OnExtensionPreferenceChanged(); void OnExtensionPreferenceChanged();
// Called when an app is removed (unloaded or uninstalled). Updates the UI. // Called when an extension is removed (unloaded or uninstalled). Updates the
void AppRemoved(const extensions::Extension* extension, bool is_uninstall); // UI.
void ExtensionRemoved(const extensions::Extension* extension,
bool is_uninstall);
// True if the extension should be displayed. // True if the extension should be displayed.
bool ShouldShow(const extensions::Extension* extension) const; bool ShouldShow(const extensions::Extension* extension) const;
...@@ -191,6 +213,14 @@ class AppLauncherHandler ...@@ -191,6 +213,14 @@ class AppLauncherHandler
// outlives us since it's owned by our containing profile. // outlives us since it's owned by our containing profile.
extensions::ExtensionService* const extension_service_; extensions::ExtensionService* const extension_service_;
// The apps are represented in the web apps model, which outlives us since
// it's owned by our containing profile. Populated iff
// features::kDesktopPWAsWithoutExtensions is enabled.
web_app::WebAppProvider* const web_app_provider_;
ScopedObserver<web_app::AppRegistrar, web_app::AppRegistrarObserver>
web_apps_observer_{this};
// We monitor changes to the extension system so that we can reload the apps // We monitor changes to the extension system so that we can reload the apps
// when necessary. // when necessary.
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "components/services/app_service/public/mojom/types.mojom.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry.h"
...@@ -101,4 +102,27 @@ std::vector<SquareSizePx> GetBookmarkAppDownloadedIconSizes( ...@@ -101,4 +102,27 @@ std::vector<SquareSizePx> GetBookmarkAppDownloadedIconSizes(
return icon_sizes_in_px; return icon_sizes_in_px;
} }
LaunchContainerAndType GetLaunchContainerAndTypeFromDisplayMode(
web_app::DisplayMode display_mode) {
apps::mojom::LaunchContainer apps_launch_container =
web_app::ConvertDisplayModeToAppLaunchContainer(display_mode);
switch (apps_launch_container) {
case apps::mojom::LaunchContainer::kLaunchContainerNone:
return {extensions::LaunchContainer::kLaunchContainerNone,
extensions::LaunchType::LAUNCH_TYPE_DEFAULT};
case apps::mojom::LaunchContainer::kLaunchContainerPanelDeprecated:
return {extensions::LaunchContainer::kLaunchContainerPanelDeprecated,
extensions::LaunchType::LAUNCH_TYPE_REGULAR};
case apps::mojom::LaunchContainer::kLaunchContainerTab:
return {extensions::LaunchContainer::kLaunchContainerTab,
extensions::LaunchType::LAUNCH_TYPE_REGULAR};
case apps::mojom::LaunchContainer::kLaunchContainerWindow:
return {extensions::LaunchContainer::kLaunchContainerTab,
display_mode == web_app::DisplayMode::kFullscreen
? extensions::LaunchType::LAUNCH_TYPE_FULLSCREEN
: extensions::LaunchType::LAUNCH_TYPE_WINDOW};
}
NOTREACHED();
}
} // namespace extensions } // namespace extensions
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include <vector> #include <vector>
#include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "extensions/common/constants.h"
namespace content { namespace content {
class BrowserContext; class BrowserContext;
...@@ -49,6 +51,14 @@ int CountUserInstalledBookmarkApps(content::BrowserContext* browser_context); ...@@ -49,6 +51,14 @@ int CountUserInstalledBookmarkApps(content::BrowserContext* browser_context);
std::vector<SquareSizePx> GetBookmarkAppDownloadedIconSizes( std::vector<SquareSizePx> GetBookmarkAppDownloadedIconSizes(
const Extension* extension); const Extension* extension);
struct LaunchContainerAndType {
extensions::LaunchContainer launch_container;
extensions::LaunchType launch_type;
};
LaunchContainerAndType GetLaunchContainerAndTypeFromDisplayMode(
web_app::DisplayMode display_mode);
} // namespace extensions } // namespace extensions
#endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_UTIL_H_ #endif // CHROME_BROWSER_WEB_APPLICATIONS_EXTENSIONS_BOOKMARK_APP_UTIL_H_
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