File: os_integration_manager.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (238 lines) | stat: -rw-r--r-- 10,081 bytes parent folder | download | duplicates (2)
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
// Copyright 2020 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_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_

#include <bitset>
#include <memory>
#include <optional>
#include <string_view>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/types/pass_key.h"
#include "chrome/browser/web_applications/os_integration/os_integration_sub_manager.h"
#include "chrome/browser/web_applications/os_integration/web_app_file_handler_manager.h"
#include "chrome/browser/web_applications/os_integration/web_app_protocol_handler_manager.h"
#include "chrome/browser/web_applications/os_integration/web_app_run_on_os_login.h"
#include "chrome/browser/web_applications/os_integration/web_app_shortcut.h"
#include "chrome/browser/web_applications/proto/web_app_os_integration_state.pb.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "components/custom_handlers/protocol_handler.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/services/app_service/public/cpp/file_handler.h"
#include "components/webapps/common/web_app_id.h"

class Profile;
class ScopedProfileKeepAlive;

namespace web_app {

class FakeOsIntegrationManager;
class WebAppProvider;
class WebAppProfileDeletionManager;

using ShortcutLocationCallback =
    base::OnceCallback<void(ShortcutLocations shortcut_locations)>;

// Returns the ShortcutInfo for an app.
using GetShortcutInfoCallback =
    base::OnceCallback<void(std::unique_ptr<ShortcutInfo>)>;

// OsIntegrationManager is responsible of creating/updating/deleting
// all OS hooks during Web App lifecycle.
// It contains individual OS integration managers and takes
// care of inter-dependencies among them.
class OsIntegrationManager {
 public:
  using UpdateShortcutsForAllAppsCallback =
      base::RepeatingCallback<void(Profile*, base::OnceClosure)>;

  // Used to suppress OS hooks during this object's lifetime.
  class ScopedSuppressForTesting {
   public:
    ScopedSuppressForTesting();
    ~ScopedSuppressForTesting();
  };
  static bool AreOsHooksSuppressedForTesting();

  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Sets a callback to be called when this class determines that all shortcuts
  // for a particular profile need to be rebuild, for example because the app
  // shortcut version has changed since the last time these were created.
  // This is used by the legacy extensions based app code in
  // chrome/browser/web_applications/extensions to ensure those app shortcuts
  // also get updated. Calling out to that code directly would violate
  // dependency layering.
  static void SetUpdateShortcutsForAllAppsCallback(
      UpdateShortcutsForAllAppsCallback callback);

  static base::OnceClosure& OnSetCurrentAppShortcutsVersionCallbackForTesting();

  OsIntegrationManager(
      Profile* profile,
      std::unique_ptr<WebAppFileHandlerManager> file_handler_manager,
      std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager);
  virtual ~OsIntegrationManager();

  // Sets internal WebAppProvider reference and threads it through to all sub
  // managers.
  virtual void SetProvider(base::PassKey<WebAppProvider>,
                           WebAppProvider& provider);

  virtual void Start();

  // Start OS Integration synchronization from external callsites. This should
  // be the only point of call into OsIntegrationManager from external places
  // after the OS integration sub managers have been implemented.
  virtual void Synchronize(
      const webapps::AppId& app_id,
      base::OnceClosure callback,
      std::optional<SynchronizeOsOptions> options = std::nullopt);

  // Asynchronously gathers existing shortcut locations according to
  // `shortcut_info`, the results of which will be passed into `callback`.
  // Virtual for testing.
  virtual void GetAppExistingShortCutLocation(
      ShortcutLocationCallback callback,
      std::unique_ptr<ShortcutInfo> shortcut_info);

  // Asynchronously gets the information required to create a shortcut for
  // `app_id` from the WebAppRegistrar along with the icon bitmaps. Do note that
  // this information is obtained from fields other than the web app's
  // `current_os_integration_state_` field, so there is still a slight chance
  // that the information returned from the registrar might not match the web
  // app's current OS integration state (for example if this API is triggered in
  // between the registrar being updated and OS integration being completed).
  //
  // If ShortcutInfo creation requires using the current OS integration state of
  // the web_app, prefer calling `web_app::BuildShortcutInfoWithoutFavicon()`
  // instead.
  virtual void GetShortcutInfoForAppFromRegistrar(
      const webapps::AppId& app_id,
      GetShortcutInfoCallback callback);

  // Proxy calls for WebAppFileHandlerManager.
  bool IsFileHandlingAPIAvailable(const webapps::AppId& app_id);
  const apps::FileHandlers* GetEnabledFileHandlers(
      const webapps::AppId& app_id) const;

  // Proxy calls for WebAppProtocolHandlerManager.
  virtual std::optional<GURL> TranslateProtocolUrl(const webapps::AppId& app_id,
                                                   const GURL& protocol_url);
  virtual std::vector<custom_handlers::ProtocolHandler> GetAppProtocolHandlers(
      const webapps::AppId& app_id);
  virtual std::vector<custom_handlers::ProtocolHandler>
  GetAllowedHandlersForProtocol(const std::string& protocol);
  virtual std::vector<custom_handlers::ProtocolHandler>
  GetDisallowedHandlersForProtocol(const std::string& protocol);

  WebAppFileHandlerManager& file_handler_manager() {
    return *file_handler_manager_;
  }

  WebAppProtocolHandlerManager& protocol_handler_manager_for_testing();

  virtual FakeOsIntegrationManager* AsTestOsIntegrationManager();

  void SetForceUnregisterCalledForTesting(
      base::RepeatingCallback<void(const webapps::AppId&)> on_force_unregister);

  // If a profile is marked for deletion, remove all OS integration for an app
  // installed for that profile.
  void UnregisterOsIntegrationOnProfileMarkedForDeletion(
      base::PassKey<WebAppProfileDeletionManager>,
      const webapps::AppId& app_id);

 protected:
  WebAppProtocolHandlerManager* protocol_handler_manager() {
    return protocol_handler_manager_.get();
  }
  bool has_file_handler_manager() { return !!file_handler_manager_; }
  void set_file_handler_manager(
      std::unique_ptr<WebAppFileHandlerManager> file_handler_manager) {
    file_handler_manager_ = std::move(file_handler_manager);
  }
  void set_protocol_handler_manager(
      std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager) {
    protocol_handler_manager_ = std::move(protocol_handler_manager);
  }

 private:
  // Synchronize:
  void StartSubManagerExecutionIfRequired(
      const webapps::AppId& app_id,
      std::optional<SynchronizeOsOptions> options,
      std::unique_ptr<proto::os_state::WebAppOsIntegration> desired_states,
      base::OnceClosure on_all_execution_done);

  // Use to call Execute() on each sub manager recursively through callbacks
  // so as to ensure that execution happens serially in the order the sub
  // managers are stored inside the sub_managers_ vector, and that consecutive
  // sub managers execute only if the one before it has finished executing.
  void ExecuteNextSubmanager(
      const webapps::AppId& app_id,
      std::optional<SynchronizeOsOptions> options,
      proto::os_state::WebAppOsIntegration* desired_state,
      const proto::os_state::WebAppOsIntegration current_state,
      size_t index,
      base::OnceClosure on_all_execution_done_db_write);

  void WriteStateToDB(
      const webapps::AppId& app_id,
      std::unique_ptr<proto::os_state::WebAppOsIntegration> desired_states,
      base::OnceClosure callback);

  // Called when ForceUnregisterOsIntegrationSubManager has finished
  // unregistering sub managers. `keep_alive` is reset to allow the
  // profile to be deleted.
  void SubManagersUnregistered(
      const webapps::AppId& app_id,
      std::unique_ptr<ScopedProfileKeepAlive> keep_alive);

  // Used to call ForceUnregister() on all sub managers to remove
  // any OS integrations from the OS. This runs synchronously in the order that
  // the sub managers are stored inside the sub_managers_ vector.
  void ForceUnregisterOsIntegrationOnSubManager(
      const webapps::AppId& app_id,
      size_t index,
      base::OnceClosure final_callback);

  // Schedules a call to UpdateShortcutsForAllAppsNow() if kAppShortcutsVersion
  // in prefs is less than kCurrentAppShortcutsVersion.
  void UpdateShortcutsForAllAppsIfNeeded();
  void UpdateShortcutsForAllAppsNow();
  void SetCurrentAppShortcutsVersion();

  void OnIconsRead(const webapps::AppId& app_id,
                   GetShortcutInfoCallback callback,
                   std::map<SquareSizePx, SkBitmap> icon_bitmaps);

  std::unique_ptr<ShortcutInfo> BuildShortcutInfoForWebApp(const WebApp* app);

  const raw_ptr<Profile> profile_;
  raw_ptr<WebAppProvider> provider_ = nullptr;

  std::unique_ptr<WebAppFileHandlerManager> file_handler_manager_;
  std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager_;

  std::vector<std::unique_ptr<OsIntegrationSubManager>> sub_managers_;
  bool set_provider_called_ = false;
  bool first_synchronize_called_ = false;

  base::RepeatingCallback<void(const webapps::AppId&)>
      force_unregister_callback_for_testing_ = base::DoNothing();

  base::WeakPtrFactory<OsIntegrationManager> weak_ptr_factory_{this};
};

}  // namespace web_app

#endif  // CHROME_BROWSER_WEB_APPLICATIONS_OS_INTEGRATION_OS_INTEGRATION_MANAGER_H_