kiosk: Implement a base class for web and iwa kiosk launchers
Extracts functionality that is common between PWA and IWA kiosks
(e.g. app service launch, notifying observers, etc.) into a base class.
Bug: 361018151
Change-Id: Ieff5f954e070ee6b597406bff40dc95f3ac1d6ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5938230
Reviewed-by: Polina Bondarenko <pbond@chromium.org>
Commit-Queue: Sergii Bykov <sbykov@google.com>
Cr-Commit-Position: refs/heads/main@{#1371286}
diff --git a/chrome/browser/ash/app_mode/BUILD.gn b/chrome/browser/ash/app_mode/BUILD.gn
index d1d10cd..439503f5 100644
--- a/chrome/browser/ash/app_mode/BUILD.gn
+++ b/chrome/browser/ash/app_mode/BUILD.gn
@@ -56,6 +56,8 @@
"kiosk_profile_load_failed_observer.h",
"kiosk_system_session.cc",
"kiosk_system_session.h",
+ "kiosk_web_app_launcher_base.cc",
+ "kiosk_web_app_launcher_base.h",
"load_profile.cc",
"load_profile.h",
"pref_names.cc",
diff --git a/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.cc b/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.cc
new file mode 100644
index 0000000..4e8319f
--- /dev/null
+++ b/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.cc
@@ -0,0 +1,95 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h"
+
+#include <memory>
+
+#include "base/check.h"
+#include "base/functional/bind.h"
+#include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
+#include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_service_launcher.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/web_applications/web_app_helpers.h"
+#include "components/account_id/account_id.h"
+#include "components/services/app_service/public/cpp/app_types.h"
+
+namespace ash {
+
+KioskWebAppLauncherBase::KioskWebAppLauncherBase(
+ Profile* profile,
+ const AccountId& account_id,
+ KioskAppLauncher::NetworkDelegate* network_delegate)
+ : KioskAppLauncher(network_delegate),
+ profile_(profile),
+ account_id_(account_id) {}
+
+KioskWebAppLauncherBase::~KioskWebAppLauncherBase() = default;
+
+void KioskWebAppLauncherBase::AddObserver(
+ KioskAppLauncher::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void KioskWebAppLauncherBase::RemoveObserver(
+ KioskAppLauncher::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void KioskWebAppLauncherBase::Initialize() {
+ InitAppServiceLauncher();
+}
+
+void KioskWebAppLauncherBase::ContinueWithNetworkReady() {
+ observers().NotifyAppInstalling();
+}
+
+void KioskWebAppLauncherBase::LaunchApp() {
+ app_service_launcher().CheckAndMaybeLaunchApp(
+ GetInstalledWebAppId(),
+ base::BindOnce(&KioskWebAppLauncherBase::OnAppLaunched,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::BindOnce(&KioskWebAppLauncherBase::OnAppBecomesVisible,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void KioskWebAppLauncherBase::NotifyAppPrepared() {
+ observers().NotifyAppPrepared();
+}
+
+void KioskWebAppLauncherBase::NotifyLaunchFailed(
+ KioskAppLaunchError::Error error) {
+ observers().NotifyLaunchFailed(error);
+}
+
+void KioskWebAppLauncherBase::OnAppLaunched(bool success) {
+ if (!success) {
+ observers().NotifyLaunchFailed(KioskAppLaunchError::Error::kUnableToLaunch);
+ return;
+ }
+ observers().NotifyAppLaunched();
+}
+
+void KioskWebAppLauncherBase::OnAppBecomesVisible() {
+ observers().NotifyAppWindowCreated(
+ web_app::GenerateApplicationNameFromAppId(GetInstalledWebAppId()));
+}
+
+void KioskWebAppLauncherBase::InitAppServiceLauncher() {
+ CHECK(!app_service_launcher_);
+ app_service_launcher_ =
+ std::make_unique<chromeos::KioskAppServiceLauncher>(profile_);
+
+ app_service_launcher_->EnsureAppTypeInitialized(
+ apps::AppType::kWeb,
+ base::BindOnce(&KioskWebAppLauncherBase::OnWebAppInitialized,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void KioskWebAppLauncherBase::OnWebAppInitialized() {
+ CheckAppInstallState();
+}
+
+} // namespace ash
diff --git a/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h b/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h
new file mode 100644
index 0000000..58cb77f
--- /dev/null
+++ b/chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h
@@ -0,0 +1,72 @@
+// Copyright 2024 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_ASH_APP_MODE_KIOSK_WEB_APP_LAUNCHER_BASE_H_
+#define CHROME_BROWSER_ASH_APP_MODE_KIOSK_WEB_APP_LAUNCHER_BASE_H_
+
+#include <memory>
+
+#include "base/check_deref.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
+#include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
+#include "chrome/browser/chromeos/app_mode/kiosk_app_service_launcher.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/account_id/account_id.h"
+#include "components/webapps/common/web_app_id.h"
+
+namespace ash {
+
+class KioskWebAppLauncherBase : public KioskAppLauncher {
+ public:
+ KioskWebAppLauncherBase(Profile* profile,
+ const AccountId& account_id,
+ KioskAppLauncher::NetworkDelegate* network_delegate);
+ KioskWebAppLauncherBase(const KioskWebAppLauncherBase&) = delete;
+ KioskWebAppLauncherBase& operator=(const KioskWebAppLauncherBase&) = delete;
+ ~KioskWebAppLauncherBase() override;
+
+ // `KioskAppLauncher`:
+ void AddObserver(KioskAppLauncher::Observer* observer) override;
+ void RemoveObserver(KioskAppLauncher::Observer* observer) override;
+ void Initialize() override;
+ void ContinueWithNetworkReady() override;
+ void LaunchApp() override;
+
+ protected:
+ Profile* profile() const { return profile_; }
+ const AccountId& account_id() const { return account_id_; }
+ chromeos::KioskAppServiceLauncher& app_service_launcher() const {
+ return CHECK_DEREF(app_service_launcher_.get());
+ }
+
+ void NotifyAppPrepared();
+ void NotifyLaunchFailed(KioskAppLaunchError::Error error);
+
+ private:
+ KioskAppLauncher::ObserverList& observers() { return observers_; }
+
+ // `KioskAppServiceLauncher` callbacks.
+ void OnAppLaunched(bool success);
+ void OnAppBecomesVisible();
+
+ void InitAppServiceLauncher();
+ void OnWebAppInitialized();
+
+ virtual void CheckAppInstallState() = 0;
+ virtual const webapps::AppId& GetInstalledWebAppId() = 0;
+
+ KioskAppLauncher::ObserverList observers_;
+ raw_ptr<Profile> profile_;
+ const AccountId account_id_;
+
+ std::unique_ptr<chromeos::KioskAppServiceLauncher> app_service_launcher_;
+
+ base::WeakPtrFactory<KioskWebAppLauncherBase> weak_ptr_factory_{this};
+};
+
+} // namespace ash
+
+#endif // CHROME_BROWSER_ASH_APP_MODE_KIOSK_WEB_APP_LAUNCHER_BASE_H_
diff --git a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.cc b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.cc
index e3bda26..ea30da3d 100644
--- a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.cc
+++ b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.cc
@@ -4,9 +4,7 @@
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.h"
-#include <memory>
#include <optional>
-#include <utility>
#include "base/check.h"
#include "base/check_deref.h"
@@ -14,9 +12,9 @@
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
#include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
+#include "chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
-#include "chrome/browser/ash/crosapi/web_kiosk_service_ash.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_service_launcher.h"
#include "chrome/browser/chromeos/app_mode/kiosk_web_app_install_util.h"
#include "chrome/browser/extensions/extension_special_storage_policy.h"
@@ -25,9 +23,7 @@
#include "chromeos/crosapi/mojom/web_kiosk_service.mojom-shared.h"
#include "chromeos/crosapi/mojom/web_kiosk_service.mojom.h"
#include "components/account_id/account_id.h"
-#include "components/services/app_service/public/cpp/app_types.h"
#include "components/webapps/common/web_app_id.h"
-#include "url/gurl.h"
#include "url/origin.h"
using crosapi::mojom::WebKioskInstaller;
@@ -39,84 +35,39 @@
Profile* profile,
const AccountId& account_id,
KioskAppLauncher::NetworkDelegate* network_delegate)
- : KioskAppLauncher(network_delegate),
- profile_(profile),
- account_id_(account_id) {}
+ : KioskWebAppLauncherBase(profile, account_id, network_delegate) {}
WebKioskAppServiceLauncher::~WebKioskAppServiceLauncher() = default;
const WebKioskAppData* WebKioskAppServiceLauncher::GetCurrentApp() const {
const WebKioskAppData* app =
- WebKioskAppManager::Get()->GetAppByAccountId(account_id_);
+ WebKioskAppManager::Get()->GetAppByAccountId(account_id());
DCHECK(app);
return app;
}
-void WebKioskAppServiceLauncher::AddObserver(
- KioskAppLauncher::Observer* observer) {
- observers_.AddObserver(observer);
-}
-
-void WebKioskAppServiceLauncher::RemoveObserver(
- KioskAppLauncher::Observer* observer) {
- observers_.RemoveObserver(observer);
-}
-
void WebKioskAppServiceLauncher::Initialize() {
- DCHECK(!app_service_launcher_);
-
- app_service_launcher_ =
- std::make_unique<chromeos::KioskAppServiceLauncher>(profile_);
- app_service_launcher_->EnsureAppTypeInitialized(
- apps::AppType::kWeb,
- base::BindOnce(&WebKioskAppServiceLauncher::OnWebAppInitialized,
- weak_ptr_factory_.GetWeakPtr()));
+ KioskWebAppLauncherBase::Initialize();
// By default the app service will try to launch the start_url as defined by
// the web app's manifest. This is generally not what we want, so we need to
// set the complete url as override url.
- app_service_launcher_->SetLaunchUrl(GetCurrentApp()->install_url());
+ app_service_launcher().SetLaunchUrl(GetCurrentApp()->install_url());
- profile_->GetExtensionSpecialStoragePolicy()->AddOriginWithUnlimitedStorage(
+ // TODO(crbug.com/372848158): Move to base class if it works for IWAs.
+ profile()->GetExtensionSpecialStoragePolicy()->AddOriginWithUnlimitedStorage(
url::Origin::Create(GetCurrentApp()->install_url()));
}
-void WebKioskAppServiceLauncher::OnWebAppInitialized() {
- GetInstallState(
- GetCurrentApp()->install_url(),
- base::BindOnce(&WebKioskAppServiceLauncher::CheckWhetherNetworkIsRequired,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void WebKioskAppServiceLauncher::GetInstallState(
- const GURL& install_url,
- WebKioskInstaller::GetWebKioskInstallStateCallback callback) {
- auto [state, app_id] = chromeos::GetKioskWebAppInstallState(
- CHECK_DEREF(profile_.get()), install_url);
- std::move(callback).Run(state, std::move(app_id));
-}
-
-void WebKioskAppServiceLauncher::CheckWhetherNetworkIsRequired(
- WebKioskInstallState state,
- const std::optional<webapps::AppId>& id) {
- if (state != WebKioskInstallState::kInstalled ||
- !profile_->GetPrefs()->GetBoolean(::prefs::kKioskWebAppOfflineEnabled)) {
- delegate_->InitializeNetwork();
- return;
- }
-
- NotifyAppPrepared(id);
-}
-
void WebKioskAppServiceLauncher::ContinueWithNetworkReady() {
- observers_.NotifyAppInstalling();
+ KioskWebAppLauncherBase::ContinueWithNetworkReady();
// Start observing app update as soon a web app system is ready so that app
// updates being applied while launching can be handled.
- WebKioskAppManager::Get()->StartObservingAppUpdate(profile_, account_id_);
+ WebKioskAppManager::Get()->StartObservingAppUpdate(profile(), account_id());
chromeos::InstallKioskWebApp(
- CHECK_DEREF(profile_.get()), GetCurrentApp()->install_url(),
+ CHECK_DEREF(profile()), GetCurrentApp()->install_url(),
base::BindOnce(&WebKioskAppServiceLauncher::OnInstallComplete,
weak_ptr_factory_.GetWeakPtr()));
}
@@ -128,37 +79,32 @@
return;
}
- observers_.NotifyLaunchFailed(KioskAppLaunchError::Error::kUnableToInstall);
+ NotifyLaunchFailed(KioskAppLaunchError::Error::kUnableToInstall);
}
void WebKioskAppServiceLauncher::NotifyAppPrepared(
- const std::optional<webapps::AppId>& id) {
- CHECK(id.has_value());
- app_id_ = id.value();
- observers_.NotifyAppPrepared();
+ const std::optional<webapps::AppId>& app_id) {
+ CHECK(app_id.has_value());
+ installed_app_id_ = app_id;
+ KioskWebAppLauncherBase::NotifyAppPrepared();
}
-void WebKioskAppServiceLauncher::LaunchApp() {
- DCHECK(app_service_launcher_);
- app_service_launcher_->CheckAndMaybeLaunchApp(
- app_id_,
- base::BindOnce(&WebKioskAppServiceLauncher::OnAppLaunched,
- weak_ptr_factory_.GetWeakPtr()),
- base::BindOnce(&WebKioskAppServiceLauncher::OnAppBecomesVisible,
- weak_ptr_factory_.GetWeakPtr()));
-}
+void WebKioskAppServiceLauncher::CheckAppInstallState() {
+ auto [state, app_id] = chromeos::GetKioskWebAppInstallState(
+ CHECK_DEREF(profile()), GetCurrentApp()->install_url());
-void WebKioskAppServiceLauncher::OnAppLaunched(bool success) {
- if (!success) {
- observers_.NotifyLaunchFailed(KioskAppLaunchError::Error::kUnableToLaunch);
+ if (state != WebKioskInstallState::kInstalled ||
+ !profile()->GetPrefs()->GetBoolean(::prefs::kKioskWebAppOfflineEnabled)) {
+ delegate_->InitializeNetwork();
return;
}
- observers_.NotifyAppLaunched();
+
+ NotifyAppPrepared(app_id);
}
-void WebKioskAppServiceLauncher::OnAppBecomesVisible() {
- observers_.NotifyAppWindowCreated(
- web_app::GenerateApplicationNameFromAppId(app_id_));
+const webapps::AppId& WebKioskAppServiceLauncher::GetInstalledWebAppId() {
+ CHECK(installed_app_id_.has_value());
+ return installed_app_id_.value();
}
} // namespace ash
diff --git a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.h b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.h
index 6a325c3..d093116 100644
--- a/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.h
+++ b/chrome/browser/ash/app_mode/web_app/web_kiosk_app_service_launcher.h
@@ -5,19 +5,14 @@
#ifndef CHROME_BROWSER_ASH_APP_MODE_WEB_APP_WEB_KIOSK_APP_SERVICE_LAUNCHER_H_
#define CHROME_BROWSER_ASH_APP_MODE_WEB_APP_WEB_KIOSK_APP_SERVICE_LAUNCHER_H_
-#include <memory>
#include <optional>
-#include <string>
-#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
-#include "chrome/browser/chromeos/app_mode/kiosk_app_service_launcher.h"
+#include "chrome/browser/ash/app_mode/kiosk_web_app_launcher_base.h"
#include "chrome/browser/chromeos/app_mode/kiosk_web_app_install_util.h"
#include "chrome/browser/web_applications/externally_managed_app_manager.h"
-#include "chromeos/crosapi/mojom/web_kiosk_service.mojom-shared.h"
-#include "chromeos/crosapi/mojom/web_kiosk_service.mojom.h"
#include "components/account_id/account_id.h"
#include "components/webapps/common/web_app_id.h"
@@ -29,7 +24,7 @@
// Responsible of installing and launching web kiosk app using App Service. It's
// destroyed upon successful app launch.
-class WebKioskAppServiceLauncher : public KioskAppLauncher {
+class WebKioskAppServiceLauncher : public KioskWebAppLauncherBase {
public:
// Histogram to log the installed web app is a placeholder.
static constexpr char kWebAppIsPlaceholderUMA[] =
@@ -49,36 +44,20 @@
~WebKioskAppServiceLauncher() override;
// `KioskAppLauncher`:
- void AddObserver(KioskAppLauncher::Observer* observer) override;
- void RemoveObserver(KioskAppLauncher::Observer* observer) override;
void Initialize() override;
void ContinueWithNetworkReady() override;
- void LaunchApp() override;
private:
- // `KioskAppServiceLauncher` callbacks.
- void OnWebAppInitialized();
void NotifyAppPrepared(const std::optional<webapps::AppId>& app_id);
- void OnAppLaunched(bool success);
- void OnAppBecomesVisible();
-
- void GetInstallState(
- const GURL& url,
- crosapi::mojom::WebKioskInstaller::GetWebKioskInstallStateCallback
- callback);
- void CheckWhetherNetworkIsRequired(crosapi::mojom::WebKioskInstallState state,
- const std::optional<webapps::AppId>& id);
void OnInstallComplete(const std::optional<webapps::AppId>& app_id);
// Get the current web application to be launched in the session.
const WebKioskAppData* GetCurrentApp() const;
- raw_ptr<Profile> profile_;
- const AccountId account_id_;
- std::string app_id_;
- KioskAppLauncher::ObserverList observers_;
+ void CheckAppInstallState() override;
+ const webapps::AppId& GetInstalledWebAppId() override;
- std::unique_ptr<chromeos::KioskAppServiceLauncher> app_service_launcher_;
+ std::optional<webapps::AppId> installed_app_id_;
base::WeakPtrFactory<WebKioskAppServiceLauncher> weak_ptr_factory_{this};
};