blob: 53f974c44dc7253e6803e4ce891c82a6786213fa [file] [log] [blame]
// Copyright (c) 2013 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/webui/app_launcher_page_ui.h"
#include <memory>
#include <string>
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/apps/app_info_dialog.h"
#include "chrome/browser/ui/webui/app_launcher_login_handler.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
#include "chrome/browser/ui/webui/ntp/app_icon_webui_handler.h"
#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
#include "chrome/browser/ui/webui/ntp/app_resource_cache_factory.h"
#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
#include "chrome/browser/ui/webui/theme_handler.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/apps_resources.h"
#include "chrome/grit/apps_resources_map.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/theme_resources.h"
#include "components/bookmarks/common/bookmark_pref_names.h"
#include "components/google/core/common/google_util.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension_urls.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/gfx/animation/animation.h"
#if defined(OS_MAC)
#include "chrome/browser/platform_util.h"
#endif
///////////////////////////////////////////////////////////////////////////////
// AppLauncherPageUI
AppLauncherPageUI::AppLauncherPageUI(content::WebUI* web_ui)
: content::WebUIController(web_ui) {
web_ui->OverrideTitle(l10n_util::GetStringUTF16(IDS_APP_LAUNCHER_TAB_TITLE));
if (!GetProfile()->IsOffTheRecord()) {
extensions::ExtensionService* service =
extensions::ExtensionSystem::Get(GetProfile())->extension_service();
web_app::WebAppProvider* web_app_provider =
web_app::WebAppProvider::Get(GetProfile());
DCHECK(web_app_provider);
DCHECK(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<AppIconWebUIHandler>());
web_ui->AddMessageHandler(std::make_unique<MetricsHandler>());
}
// The theme handler can require some CPU, so do it after hooking up the most
// visited handler. This allows the DB query for the new tab thumbs to happen
// earlier.
web_ui->AddMessageHandler(std::make_unique<ThemeHandler>());
/*content::URLDataSource::Add(
GetProfile(),
std::make_unique<HTMLSource>(GetProfile()->GetOriginalProfile()));*/
content::WebUIDataSource* source =
content::WebUIDataSource::Create(chrome::kChromeUIAppLauncherPageHost);
content::WebUIDataSource::Add(GetProfile(), source);
source->AddResourcePaths(base::make_span(kAppsResources, kAppsResourcesSize));
source->SetDefaultResource(IDR_APPS_NEW_TAB_HTML);
source->UseStringsJs();
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"title", IDS_NEW_TAB_TITLE},
{"webStoreTitle", IDS_EXTENSION_WEB_STORE_TITLE},
{"webStoreTitleShort", IDS_EXTENSION_WEB_STORE_TITLE_SHORT},
{"attributionintro", IDS_NEW_TAB_ATTRIBUTION_INTRO},
{"appuninstall", IDS_EXTENSIONS_UNINSTALL},
{"appoptions", IDS_NEW_TAB_APP_OPTIONS},
{"appdetails", IDS_NEW_TAB_APP_DETAILS},
{"appinfodialog", IDS_APP_CONTEXT_MENU_SHOW_INFO},
{"appcreateshortcut", IDS_NEW_TAB_APP_CREATE_SHORTCUT},
{"appinstalllocally", IDS_NEW_TAB_APP_INSTALL_LOCALLY},
{"appDefaultPageName", IDS_APP_DEFAULT_PAGE_NAME},
{"applaunchtypepinned", IDS_APP_CONTEXT_MENU_OPEN_PINNED},
{"applaunchtyperegular", IDS_APP_CONTEXT_MENU_OPEN_REGULAR},
{"applaunchtypewindow", IDS_APP_CONTEXT_MENU_OPEN_WINDOW},
{"applaunchtypefullscreen", IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN},
{"syncpromotext", IDS_SYNC_START_SYNC_BUTTON_LABEL},
{"syncLinkText", IDS_SYNC_ADVANCED_OPTIONS},
{"learnMore", IDS_LEARN_MORE},
{"appInstallHintText", IDS_NEW_TAB_APP_INSTALL_HINT_LABEL},
{"learn_more", IDS_LEARN_MORE},
{"tile_grid_screenreader_accessible_description",
IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION},
{"page_switcher_change_title", IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE},
{"page_switcher_same_title", IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE},
{"runonoslogin", IDS_APP_CONTEXT_MENU_RUN_ON_OS_LOGIN},
};
source->AddLocalizedStrings(kLocalizedStrings);
PrefService* prefs = GetProfile()->GetPrefs();
source->AddString(
"bookmarkbarattached",
prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar) ? "true" : "false");
source->AddBoolean("shouldShowSyncLogin",
AppLauncherLoginHandler::ShouldShow(GetProfile()));
const std::string& app_locale = g_browser_process->GetApplicationLocale();
source->AddString("webStoreLink",
google_util::AppendGoogleLocaleParam(
extension_urls::GetWebstoreLaunchURL(), app_locale)
.spec());
bool is_swipe_tracking_from_scroll_events_enabled = false;
#if defined(OS_MAC)
// On Mac OS X 10.7+, horizontal scrolling can be treated as a back or
// forward gesture. Pass through a flag that indicates whether or not that
// feature is enabled.
is_swipe_tracking_from_scroll_events_enabled =
platform_util::IsSwipeTrackingFromScrollEventsEnabled();
#endif
source->AddBoolean("isSwipeTrackingFromScrollEventsEnabled",
is_swipe_tracking_from_scroll_events_enabled);
source->AddBoolean("showWebStoreIcon",
!prefs->GetBoolean(prefs::kHideWebStoreIcon));
pref_change_registrar_.Init(prefs);
pref_change_registrar_.Add(
prefs::kHideWebStoreIcon,
base::BindRepeating(&AppLauncherPageUI::OnHideWebStoreIconChanged,
base::Unretained(this)));
source->AddBoolean("canShowAppInfoDialog", CanPlatformShowAppInfoDialog());
AppLauncherHandler::RegisterLoadTimeData(GetProfile(), source);
// Control fade and resize animations.
source->AddBoolean("anim", gfx::Animation::ShouldRenderRichAnimation());
source->AddBoolean("isUserSignedIn",
IdentityManagerFactory::GetForProfile(GetProfile())
->HasPrimaryAccount(signin::ConsentLevel::kSync));
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::ScriptSrc,
"script-src chrome://resources 'self' 'unsafe-eval' "
"'unsafe-inline';");
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::StyleSrc,
"style-src 'self' chrome://resources chrome://theme "
"'unsafe-inline';");
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::ImgSrc,
"img-src 'self' chrome://extension-icon chrome://app-icon chrome://theme "
"chrome://resources data:;");
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::TrustedTypes,
"trusted-types apps-page-js cr-ui-bubble-js-static "
"parse-html-subset;");
}
AppLauncherPageUI::~AppLauncherPageUI() {
}
void AppLauncherPageUI::OnHideWebStoreIconChanged() {
std::unique_ptr<base::DictionaryValue> update(new base::DictionaryValue);
PrefService* prefs = GetProfile()->GetPrefs();
update->SetBoolean("showWebStoreIcon",
!prefs->GetBoolean(prefs::kHideWebStoreIcon));
content::WebUIDataSource::Update(
GetProfile(), chrome::kChromeUIAppLauncherPageHost, std::move(update));
}
// static
base::RefCountedMemory* AppLauncherPageUI::GetFaviconResourceBytes(
ui::ScaleFactor scale_factor) {
return ui::ResourceBundle::GetSharedInstance().
LoadDataResourceBytesForScale(IDR_BOOKMARK_BAR_APPS_SHORTCUT,
scale_factor);
}
bool AppLauncherPageUI::OverrideHandleWebUIMessage(
const GURL& source_url,
const std::string& message,
const base::ListValue& args) {
if (message == "getApps" &&
AppLauncherLoginHandler::ShouldShow(GetProfile())) {
web_ui()->AddMessageHandler(std::make_unique<AppLauncherLoginHandler>());
}
return false;
}
Profile* AppLauncherPageUI::GetProfile() const {
return Profile::FromWebUI(web_ui());
}