1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
|
// Copyright 2018 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_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_
#define CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "ash/webui/system_apps/public/system_web_app_type.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/one_shot_event.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ash/system_web_apps/system_web_app_background_task.h"
#include "chrome/browser/ash/system_web_apps/system_web_app_icon_checker.h"
#include "chrome/browser/web_applications/externally_managed_app_manager.h"
#include "chrome/browser/web_applications/web_app_ui_manager.h"
#include "chromeos/ash/experiences/system_web_apps/types/system_web_app_delegate.h"
#include "chromeos/ash/experiences/system_web_apps/types/system_web_app_delegate_map.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/webapps/common/web_app_id.h"
#include "url/gurl.h"
namespace base {
class Version;
}
namespace content {
class NavigationHandle;
}
namespace web_app {
class WebAppProvider;
} // namespace web_app
class PrefService;
class Profile;
namespace ash {
// Installs, uninstalls, and updates System Web Apps.
// System Web Apps are built-in, highly-privileged Web Apps for Chrome OS. They
// have access to more APIs and are part of the Chrome OS image. All clients
// should await `on_apps_synchronized()` event to start working with SWAs.
class SystemWebAppManager : public KeyedService,
public web_app::WebAppUiManagerObserver {
public:
// Policy for when the SystemWebAppManager will update apps/install new apps.
enum class UpdatePolicy {
// Update every system start.
kAlwaysUpdate,
// Update when the Chrome version number changes.
kOnVersionChange,
};
// Number of attempts to install a given version & locale of the SWAs before
// bailing out.
static constexpr int kInstallFailureAttempts = 3;
static constexpr char kSystemWebAppSessionHasBrokenIconsPrefName[] =
"web_apps.system_web_app_has_broken_icons_in_session";
static constexpr char kFreshInstallDurationHistogramName[] =
"Webapp.SystemApps.FreshInstallDuration";
static constexpr char kIconsFixedOnReinstallHistogramName[] =
"Webapp.SystemApps.IconsFixedOnReinstall";
static constexpr char kIconsAreHealthyInSessionHistorgramName[] =
"Webapp.SystemApps.IconsAreHealthyInSession";
static constexpr char kInstallResultHistogramName[] =
"Webapp.InstallResult.System";
// Returns whether the given app type is enabled.
bool IsAppEnabled(SystemWebAppType type) const;
explicit SystemWebAppManager(Profile* profile);
SystemWebAppManager(const SystemWebAppManager&) = delete;
SystemWebAppManager& operator=(const SystemWebAppManager&) = delete;
~SystemWebAppManager() override;
// Return the SystemWebAppManager that hosts system web apps in profile.
// Returns nullptr if the profile doesn't support system web apps (e.g. Kiosk,
// lock-screen, system profile).
static SystemWebAppManager* Get(Profile* profile);
// Gets the associated WebAppProvider for system web apps. `WebAppProvider` is
// always present in the `profile` if the `Get` above returns non-nullptr.
static web_app::WebAppProvider* GetWebAppProvider(Profile* profile);
// Returns the SystemWebAppManager for tests. Blocks if the web app registry
// is not yet ready.
static SystemWebAppManager* GetForTest(Profile* profile);
// Calls `Start` when `WebAppProvider` is ready.
void ScheduleStart();
// Initialize the SystemWebAppManager.
void Start();
// KeyedService:
void Shutdown() override;
// By default, we don't install system web apps in browser tests to avoid
// running installation tasks (inefficient because most browser tests don't
// need SWAs).
//
// Call this to install default enabled system apps if the test needs them.
// (e.g. test opening OS Settings from an Ash views button).
//
// This can be called multiple times to simulate reinstallation from system
// restart.
void InstallSystemAppsForTesting();
// Returns the app id for the given System App |type|.
std::optional<webapps::AppId> GetAppIdForSystemApp(
SystemWebAppType type) const;
// Returns the System App Type for the given |app_id|.
std::optional<SystemWebAppType> GetSystemAppTypeForAppId(
const webapps::AppId& app_id) const;
// Returns the System App Delegate for the given App |type|.
const SystemWebAppDelegate* GetSystemApp(SystemWebAppType type) const;
// Returns the App Ids for all installed System Web Apps.
std::vector<webapps::AppId> GetAppIds() const;
// Returns whether |app_id| points to an installed System App.
bool IsSystemWebApp(const webapps::AppId& app_id) const;
// Returns the SystemWebAppType that should handle |url|.
//
// Under the hood, it returns the system web app whose `start_url` shares
// the same origin with the given |url|. It does not take
// `SystemWebAppDelegate::IsURLInSystemAppScope` into account.
std::optional<SystemWebAppType> GetSystemAppForURL(const GURL& url) const;
// Returns the SystemWebAppType that should capture the navigation to |url|.
std::optional<SystemWebAppType> GetCapturingSystemAppForURL(
const GURL& url) const;
const base::OneShotEvent& on_apps_synchronized() const {
return *on_apps_synchronized_;
}
// Return the OneShotEvent that is fired after all of the background tasks
// have started and their timers become active.
const base::OneShotEvent& on_tasks_started() const {
return *on_tasks_started_;
}
// Returns the OneShotEvent that is fired after icon checks are complete.
const base::OneShotEvent& on_icon_check_completed() const {
return *on_icon_check_completed_;
}
// Returns a map of registered system app types and infos, these apps will be
// installed on the system.
const SystemWebAppDelegateMap& system_app_delegates() const {
return system_app_delegates_;
}
// This call will override default System Apps configuration. You should call
// Start() after this call to install |system_apps|.
void SetSystemAppsForTesting(SystemWebAppDelegateMap system_apps);
// Overrides the update policy. If AlwaysReinstallSystemWebApps feature is
// enabled, this method does nothing, and system apps will be reinstalled.
void SetUpdatePolicyForTesting(UpdatePolicy policy);
void ResetForTesting();
// Get the timers. Only use this for testing.
const std::vector<std::unique_ptr<SystemWebAppBackgroundTask>>&
GetBackgroundTasksForTesting();
void StopBackgroundTasksForTesting();
const Profile* profile() const { return profile_; }
protected:
virtual const base::Version& CurrentVersion() const;
virtual const std::string& CurrentLocale() const;
virtual bool PreviousSessionHadBrokenIcons() const;
void StopBackgroundTasks();
private:
// Returns the list of origin trials to enable for |url| loaded in System
// App |type|. Returns an empty vector if the App does not specify origin
// trials for |url|.
const std::vector<std::string>* GetEnabledOriginTrials(
const SystemWebAppDelegate* system_app,
const GURL& url) const;
void OnAppsSynchronized(
bool did_force_install_apps,
const base::TimeTicks& install_start_time,
std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult>
install_results,
std::map<GURL, webapps::UninstallResultCode> uninstall_results);
bool ShouldForceInstallApps() const;
void UpdateLastAttemptedInfo();
// Returns if we have exceeded the number of retry attempts allowed for this
// version.
bool CheckAndIncrementRetryAttempts();
void RecordSystemWebAppInstallResults(
const std::map<GURL, web_app::ExternallyManagedAppManager::InstallResult>&
install_results) const;
void RecordSystemWebAppInstallDuration(
const base::TimeDelta& time_duration) const;
void StartBackgroundTasks() const;
void OnIconCheckResult(SystemWebAppIconChecker::IconState result);
// web_app::WebAppUiManagerObserver:
void OnReadyToCommitNavigation(
const webapps::AppId& app_id,
content::NavigationHandle* navigation_handle) override;
void OnWebAppUiManagerDestroyed() override;
void ConnectProviderToSystemWebAppDelegateMap(
const SystemWebAppDelegateMap* system_web_apps_delegate_map) const;
raw_ptr<Profile> profile_;
// SystemWebAppManager KeyedService depends on WebAppProvider KeyedService,
// therefore this pointer is always valid.
raw_ptr<web_app::WebAppProvider> provider_ = nullptr;
std::unique_ptr<base::OneShotEvent> on_apps_synchronized_;
std::unique_ptr<base::OneShotEvent> on_tasks_started_;
std::unique_ptr<base::OneShotEvent> on_icon_check_completed_;
bool shutting_down_ = false;
bool previous_session_had_broken_icons_ = false;
std::string install_result_per_profile_histogram_name_;
UpdatePolicy update_policy_;
// We skip app installation in tests by default. Tests can trigger
// installation by calling `InstallSystemAppsForTesting()` or
// `SetSystemAppsForTesting()`.
bool skip_app_installation_in_test_ = true;
SystemWebAppDelegateMap system_app_delegates_;
const raw_ptr<PrefService> pref_service_;
std::vector<std::unique_ptr<SystemWebAppBackgroundTask>> tasks_;
base::ScopedObservation<web_app::WebAppUiManager,
web_app::WebAppUiManagerObserver>
ui_manager_observation_{this};
// Always a valid pointer, has the same lifecycle as `this` in production.
// Might be reset in tests.
std::unique_ptr<SystemWebAppIconChecker> icon_checker_;
base::WeakPtrFactory<SystemWebAppManager> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_SYSTEM_WEB_APPS_SYSTEM_WEB_APP_MANAGER_H_
|