1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_WEB_APPLICATIONS_MANIFEST_UPDATE_MANAGER_H_
6 #define CHROME_BROWSER_WEB_APPLICATIONS_MANIFEST_UPDATE_MANAGER_H_
7 
8 #include <memory>
9 
10 #include "base/callback.h"
11 #include "base/containers/flat_map.h"
12 #include "base/optional.h"
13 #include "base/scoped_observer.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/web_applications/components/app_registrar.h"
16 #include "chrome/browser/web_applications/components/app_registrar_observer.h"
17 #include "chrome/browser/web_applications/components/web_app_id.h"
18 #include "chrome/browser/web_applications/manifest_update_task.h"
19 
20 namespace content {
21 class WebContents;
22 }
23 
24 namespace web_app {
25 
26 class WebAppUiManager;
27 class InstallManager;
28 class SystemWebAppManager;
29 
30 // Checks for updates to a web app's manifest and triggers a reinstall if the
31 // current installation is out of date.
32 //
33 // Update checks are throttled per app (see MaybeConsumeUpdateCheck()) to avoid
34 // excessive updating on pathological sites.
35 //
36 // Each update check is performed by a |ManifestUpdateTask|, see that class for
37 // details about what happens during a check.
38 //
39 // TODO(crbug.com/926083): Replace MaybeUpdate() with a background check instead
40 // of being triggered by page loads.
41 class ManifestUpdateManager final : public AppRegistrarObserver {
42  public:
43   ManifestUpdateManager();
44   ~ManifestUpdateManager() override;
45 
46   void SetSubsystems(AppRegistrar* registrar,
47                      AppIconManager* icon_manager,
48                      WebAppUiManager* ui_manager,
49                      InstallManager* install_manager,
50                      SystemWebAppManager* system_web_app_manager);
51   void Start();
52   void Shutdown();
53 
54   void MaybeUpdate(const GURL& url,
55                    const AppId& app_id,
56                    content::WebContents* web_contents);
57 
58   // AppRegistrarObserver:
59   void OnWebAppUninstalled(const AppId& app_id) override;
60 
61   // |app_id| will be nullptr when |result| is kNoAppInScope.
62   using ResultCallback =
63       base::OnceCallback<void(const GURL& url, ManifestUpdateResult result)>;
64   void SetResultCallbackForTesting(ResultCallback callback);
set_time_override_for_testing(base::Time time_override)65   void set_time_override_for_testing(base::Time time_override) {
66     time_override_for_testing_ = time_override;
67   }
68 
hang_update_checks_for_testing()69   void hang_update_checks_for_testing() {
70     hang_update_checks_for_testing_ = true;
71   }
72 
73  private:
74   bool MaybeConsumeUpdateCheck(const GURL& origin, const AppId& app_id);
75   base::Optional<base::Time> GetLastUpdateCheckTime(const GURL& origin,
76                                                     const AppId& app_id) const;
77   void SetLastUpdateCheckTime(const GURL& origin,
78                               const AppId& app_id,
79                               base::Time time);
80   void OnUpdateStopped(const ManifestUpdateTask& task,
81                        ManifestUpdateResult result);
82   void NotifyResult(const GURL& url, ManifestUpdateResult result);
83 
84   AppRegistrar* registrar_ = nullptr;
85   AppIconManager* icon_manager_ = nullptr;
86   WebAppUiManager* ui_manager_ = nullptr;
87   InstallManager* install_manager_ = nullptr;
88   SystemWebAppManager* system_web_app_manager_ = nullptr;
89 
90   ScopedObserver<AppRegistrar, AppRegistrarObserver> registrar_observer_{this};
91 
92   base::flat_map<AppId, std::unique_ptr<ManifestUpdateTask>> tasks_;
93 
94   base::flat_map<AppId, base::Time> last_update_check_;
95 
96   base::Optional<base::Time> time_override_for_testing_;
97   ResultCallback result_callback_for_testing_;
98 
99   bool started_ = false;
100   bool hang_update_checks_for_testing_ = false;
101 };
102 
103 }  // namespace web_app
104 
105 #endif  // CHROME_BROWSER_WEB_APPLICATIONS_MANIFEST_UPDATE_MANAGER_H_
106