blob: 8f793dedabf481005e3d2a51638384fd8399cf6a [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// 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_BROWSER_CONTROLLER_H_
#define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_BROWSER_CONTROLLER_H_
#include <memory>
#include <optional>
#include <string>
#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/web_applications/ui_manager/update_dialog_types.h"
#include "chrome/browser/web_applications/web_app_icon_manager.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_install_manager_observer.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registrar_observer.h"
#include "components/services/app_service/public/cpp/icon_types.h"
#include "components/webapps/common/web_app_id.h"
#include "third_party/re2/src/re2/set.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/models/image_model.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "components/content_relationship_verification/digital_asset_links_handler.h" // nogncheck
#endif
class Browser;
class SkBitmap;
#if BUILDFLAG(IS_CHROMEOS)
namespace ash {
class SystemWebAppDelegate;
}
#endif // BUILDFLAG(IS_CHROMEOS)
namespace content_relationship_verification {
class DigitalAssetLinksHandler;
}
namespace base {
class TimeTicks;
} // namespace base
namespace web_app {
class WebAppRegistrar;
class WebAppProvider;
// Class to encapsulate logic to control the browser UI for
// web apps.
// App information is obtained from the WebAppRegistrar.
// Icon information is obtained from the WebAppIconManager.
// Note: Much of the functionality in HostedAppBrowserController
// will move to this class.
class WebAppBrowserController : public AppBrowserController,
public WebAppInstallManagerObserver,
public WebAppRegistrarObserver {
public:
WebAppBrowserController(WebAppProvider& provider,
Browser* browser,
webapps::AppId app_id,
#if BUILDFLAG(IS_CHROMEOS)
const ash::SystemWebAppDelegate* system_app,
#endif // BUILDFLAG(IS_CHROMEOS)
bool has_tab_strip);
WebAppBrowserController(const WebAppBrowserController&) = delete;
WebAppBrowserController& operator=(const WebAppBrowserController&) = delete;
~WebAppBrowserController() override;
// AppBrowserController:
using HomeTabCallbackList = base::OnceCallbackList<void()>;
bool HasMinimalUiButtons() const override;
gfx::ImageSkia GetHomeTabIcon() const;
gfx::ImageSkia GetFallbackHomeTabIcon() const;
gfx::ImageSkia GetAppMenuIcon() const;
ui::ImageModel GetWindowAppIcon() const override;
ui::ImageModel GetWindowIcon() const override;
std::optional<SkColor> GetThemeColor() const override;
std::optional<SkColor> GetBackgroundColor() const override;
std::u16string GetTitle() const override;
std::u16string GetAppShortName() const override;
std::u16string GetFormattedUrlOrigin() const override;
const GURL& GetAppStartUrl() const override;
const GURL& GetAppNewTabUrl() const override;
content::WebContents* GetPinnedHomeTab() const override;
bool ShouldHideNewTabButton() const override;
bool IsUrlInHomeTabScope(const GURL& url) const override;
bool ShouldShowAppIconOnTab(int index) const override;
bool IsUrlInAppScope(const GURL& url) const override;
WebAppBrowserController* AsWebAppBrowserController() override;
bool CanUserUninstall() const override;
void Uninstall(
webapps::WebappUninstallSource webapp_uninstall_source) override;
bool IsInstalled() const override;
std::unique_ptr<TabMenuModelFactory> GetTabMenuModelFactory() const override;
bool AppUsesWindowControlsOverlay() const override;
bool AppUsesTabbed() const override;
bool IsWindowControlsOverlayEnabled() const override;
void ToggleWindowControlsOverlayEnabled(
base::OnceClosure on_complete) override;
bool AppUsesBorderlessMode() const override;
bool IsIsolatedWebApp() const override;
void SetIsolatedWebAppTrueForTesting() override;
gfx::Rect GetDefaultBounds() const override;
bool HasReloadButton() const override;
bool HasPendingUpdate() const override;
void CreateMetadataAndTriggerAppUpdateDialog(
base::TimeTicks start_time) const override;
#if BUILDFLAG(IS_CHROMEOS)
const ash::SystemWebAppDelegate* system_app() const override;
bool ShouldShowCustomTabBar() const override;
#else
bool HasProfileMenuButton() const override;
bool IsProfileMenuButtonVisible() const override;
#endif // BUILDFLAG(IS_CHROMEOS)
#if BUILDFLAG(IS_MAC)
bool AlwaysShowToolbarInFullscreen() const override;
void ToggleAlwaysShowToolbarInFullscreen() override;
#endif
// WebAppInstallManagerObserver:
void OnWebAppUninstalled(
const webapps::AppId& app_id,
webapps::WebappUninstallSource uninstall_source) override;
void OnWebAppManifestUpdated(const webapps::AppId& app_id) override;
void OnWebAppInstallManagerDestroyed() override;
// WebAppRegistrarObserver:
void OnWebAppEffectiveScopeChanged(const webapps::AppId& app_id,
const WebAppScope& new_scope) override;
void OnAppRegistrarDestroyed() override;
base::CallbackListSubscription AddHomeTabIconLoadCallbackForTesting(
const base::OnceClosure callback);
static void SetIconLoadCallbackForTesting(base::OnceClosure callback);
static void SetManifestUpdateAppliedCallbackForTesting(
base::OnceClosure callback);
protected:
// AppBrowserController:
void OnTabInserted(content::WebContents* contents) override;
void OnTabRemoved(content::WebContents* contents) override;
private:
mutable HomeTabCallbackList home_tab_callback_list_;
const WebAppRegistrar& registrar() const;
const WebAppInstallManager& install_manager() const;
// Helper function to call AppServiceProxy to load icon.
void LoadAppIcon(bool allow_placeholder_icon) const;
// Invoked when the icon is loaded.
void OnLoadIcon(apps::IconValuePtr icon_value);
void OnReadHomeTabIcon(SkBitmap home_tab_icon_bitmap) const;
void OnReadIcon(IconPurpose purpose, SkBitmap bitmap);
void PerformDigitalAssetLinkVerification(Browser* browser);
void OnMetadataObtainedTriggerUpdateDialog(
base::TimeTicks start_time,
std::optional<WebAppIdentityUpdate> identity_update) const;
#if BUILDFLAG(IS_CHROMEOS)
void CheckDigitalAssetLinkRelationshipForAndroidApp(
const std::string& package_name,
const std::string& fingerprint);
void OnRelationshipCheckComplete(
content_relationship_verification::RelationshipCheckResult result);
#endif // BUILDFLAG(IS_CHROMEOS)
// Helper function to return the resolved background color from the manifest
// given the current state of dark/light mode.
std::optional<SkColor> GetResolvedManifestBackgroundColor() const;
const raw_ref<WebAppProvider> provider_;
// Save the display mode at time of launch. The web app display mode may
// change with manifest updates but the app window should continue using
// whatever it was launched with.
DisplayMode effective_display_mode_ = DisplayMode::kUndefined;
bool is_isolated_web_app_for_testing_ = false;
#if BUILDFLAG(IS_CHROMEOS)
const raw_ptr<const ash::SystemWebAppDelegate> system_app_;
#endif // BUILDFLAG(IS_CHROMEOS)
mutable std::optional<ui::ImageModel> app_icon_;
// Save this at launch time in case it changes with a manifest update while
// the window is open.
const bool has_pinned_home_tab_ = false;
#if BUILDFLAG(IS_CHROMEOS)
// The result of digital asset link verification of the web app.
// Only used for web-only TWAs installed through the Play Store.
std::optional<bool> is_verified_;
std::unique_ptr<content_relationship_verification::DigitalAssetLinksHandler>
asset_link_handler_;
#endif // BUILDFLAG(IS_CHROMEOS)
base::ScopedObservation<WebAppInstallManager, WebAppInstallManagerObserver>
install_manager_observation_{this};
base::ScopedObservation<WebAppRegistrar, WebAppRegistrarObserver>
registrar_observation_{this};
mutable base::WeakPtrFactory<WebAppBrowserController> weak_ptr_factory_{this};
};
} // namespace web_app
#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_BROWSER_CONTROLLER_H_