1 // Copyright 2018 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_WEB_APP_REGISTRAR_H_
6 #define CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_REGISTRAR_H_
7 
8 #include <map>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/check_op.h"
15 #include "base/optional.h"
16 #include "chrome/browser/profiles/profile_manager_observer.h"
17 #include "chrome/browser/web_applications/components/app_registrar.h"
18 #include "chrome/browser/web_applications/components/web_app_constants.h"
19 #include "chrome/browser/web_applications/components/web_app_id.h"
20 #include "chrome/browser/web_applications/components/web_application_info.h"
21 
22 namespace web_app {
23 
24 class WebApp;
25 
26 using Registry = std::map<AppId, std::unique_ptr<WebApp>>;
27 
28 // A registry model. This is a read-only container, which owns WebApp objects.
29 class WebAppRegistrar : public AppRegistrar, public ProfileManagerObserver {
30  public:
31   explicit WebAppRegistrar(Profile* profile);
32   WebAppRegistrar(const WebAppRegistrar&) = delete;
33   WebAppRegistrar& operator=(const WebAppRegistrar&) = delete;
34   ~WebAppRegistrar() override;
35 
is_empty()36   bool is_empty() const { return registry_.empty(); }
37 
38   const WebApp* GetAppById(const AppId& app_id) const;
39 
40   // AppRegistrar:
41   void Start() override;
42   void Shutdown() override;
43   bool IsInstalled(const AppId& app_id) const override;
44   bool IsLocallyInstalled(const AppId& app_id) const override;
45   bool WasInstalledByUser(const AppId& app_id) const override;
46   int CountUserInstalledApps() const override;
47   std::string GetAppShortName(const AppId& app_id) const override;
48   std::string GetAppDescription(const AppId& app_id) const override;
49   base::Optional<SkColor> GetAppThemeColor(const AppId& app_id) const override;
50   base::Optional<SkColor> GetAppBackgroundColor(
51       const AppId& app_id) const override;
52   const GURL& GetAppStartUrl(const AppId& app_id) const override;
53   const std::string* GetAppLaunchQueryParams(
54       const AppId& app_id) const override;
55   const apps::ShareTarget* GetAppShareTarget(
56       const AppId& app_id) const override;
57   base::Optional<GURL> GetAppScopeInternal(const AppId& app_id) const override;
58   DisplayMode GetAppDisplayMode(const AppId& app_id) const override;
59   DisplayMode GetAppUserDisplayMode(const AppId& app_id) const override;
60   std::vector<DisplayMode> GetAppDisplayModeOverride(
61       const AppId& app_id) const override;
62   base::Time GetAppLastLaunchTime(const web_app::AppId& app_id) const override;
63   base::Time GetAppInstallTime(const web_app::AppId& app_id) const override;
64   std::vector<WebApplicationIconInfo> GetAppIconInfos(
65       const AppId& app_id) const override;
66   SortedSizesPx GetAppDownloadedIconSizesAny(
67       const AppId& app_id) const override;
68   std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutsMenuItemInfos(
69       const AppId& app_id) const override;
70   std::vector<std::vector<SquareSizePx>>
71   GetAppDownloadedShortcutsMenuIconsSizes(const AppId& app_id) const override;
72   RunOnOsLoginMode GetAppRunOnOsLoginMode(const AppId& app_id) const override;
73   std::vector<AppId> GetAppIds() const override;
74   WebAppRegistrar* AsWebAppRegistrar() override;
75 
76   // ProfileManagerObserver:
77   void OnProfileMarkedForPermanentDeletion(
78       Profile* profile_to_be_deleted) override;
79 
80   // A filter must return false to skip the |web_app|.
81   using Filter = bool (*)(const WebApp& web_app);
82 
83   // Only range-based |for| loop supported. Don't use AppSet directly.
84   // Doesn't support registration and unregistration of WebApp while iterating.
85   class AppSet {
86    public:
87     // An iterator class that can be used to access the list of apps.
88     template <typename WebAppType>
89     class Iter {
90      public:
91       using InternalIter = Registry::const_iterator;
92 
Iter(InternalIter && internal_iter,InternalIter && internal_end,Filter filter)93       Iter(InternalIter&& internal_iter,
94            InternalIter&& internal_end,
95            Filter filter)
96           : internal_iter_(std::move(internal_iter)),
97             internal_end_(std::move(internal_end)),
98             filter_(filter) {
99         FilterAndSkipApps();
100       }
101       Iter(Iter&&) = default;
102       Iter(const Iter&) = delete;
103       Iter& operator=(const Iter&) = delete;
104       ~Iter() = default;
105 
106       void operator++() {
107         ++internal_iter_;
108         FilterAndSkipApps();
109       }
110       WebAppType& operator*() const { return *internal_iter_->second.get(); }
111       bool operator!=(const Iter& iter) const {
112         return internal_iter_ != iter.internal_iter_;
113       }
114 
115      private:
FilterAndSkipApps()116       void FilterAndSkipApps() {
117         if (!filter_)
118           return;
119 
120         while (internal_iter_ != internal_end_ && !filter_(**this))
121           ++internal_iter_;
122       }
123 
124       InternalIter internal_iter_;
125       InternalIter internal_end_;
126       Filter filter_;
127     };
128 
129     AppSet(const WebAppRegistrar* registrar, Filter filter);
130     AppSet(AppSet&&) = default;
131     AppSet(const AppSet&) = delete;
132     AppSet& operator=(const AppSet&) = delete;
133     ~AppSet();
134 
135     using iterator = Iter<WebApp>;
136     using const_iterator = Iter<const WebApp>;
137 
138     iterator begin();
139     iterator end();
140     const_iterator begin() const;
141     const_iterator end() const;
142 
143    private:
144     const WebAppRegistrar* const registrar_;
145     const Filter filter_;
146 #if DCHECK_IS_ON()
147     const size_t mutations_count_;
148 #endif
149   };
150 
151   // Returns all apps in the registry (a superset) including stubs.
152   const AppSet GetAppsIncludingStubs() const;
153   // Returns all apps excluding stubs for apps in sync install. Apps in sync
154   // install are being installed and should be hidden for most subsystems. This
155   // is a subset of GetAppsIncludingStubs().
156   const AppSet GetApps() const;
157 
158  protected:
registry()159   Registry& registry() { return registry_; }
160   void SetRegistry(Registry&& registry);
161 
162   const AppSet FilterApps(Filter filter) const;
163 
164   void CountMutation();
165 
166  private:
167   Registry registry_;
168   bool registry_profile_being_deleted_ = false;
169 #if DCHECK_IS_ON()
170   size_t mutations_count_ = 0;
171 #endif
172 };
173 
174 // A writable API for the registry model. Mutable WebAppRegistrar must be used
175 // only by WebAppSyncBridge.
176 class WebAppRegistrarMutable : public WebAppRegistrar {
177  public:
178   explicit WebAppRegistrarMutable(Profile* profile);
179   ~WebAppRegistrarMutable() override;
180 
181   void InitRegistry(Registry&& registry);
182 
183   WebApp* GetAppByIdMutable(const AppId& app_id);
184 
185   AppSet FilterAppsMutable(Filter filter);
186 
187   AppSet GetAppsIncludingStubsMutable();
188   AppSet GetAppsMutable();
189 
190   using WebAppRegistrar::CountMutation;
191   using WebAppRegistrar::registry;
192 };
193 
194 // For testing and debug purposes.
195 bool IsRegistryEqual(const Registry& registry, const Registry& registry2);
196 
197 }  // namespace web_app
198 
199 #endif  // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_REGISTRAR_H_
200