File: local_files_migration_manager.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (250 lines) | stat: -rw-r--r-- 9,470 bytes parent folder | download | duplicates (5)
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
// 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_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_
#define CHROME_BROWSER_ASH_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_

#include <memory>
#include <optional>

#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/timer/wall_clock_timer.h"
#include "chrome/browser/ash/policy/skyvault/local_user_files_policy_observer.h"
#include "chrome/browser/ash/policy/skyvault/migration_coordinator.h"
#include "chrome/browser/ash/policy/skyvault/migration_notification_manager.h"
#include "chrome/browser/ash/policy/skyvault/policy_utils.h"
#include "chrome/browser/chromeos/extensions/login_screen/login/cleanup/files_cleanup_handler.h"
#include "chrome/browser/profiles/profile_keyed_service_factory.h"
#include "chromeos/ash/components/dbus/cryptohome/UserDataAuth.pb.h"
#include "components/keyed_service/core/keyed_service.h"

namespace base {
template <typename T>
class NoDestructor;
}  // namespace base

namespace content {
class BrowserContext;
}  // namespace content

namespace policy::local_user_files {

// Manages the migration of local files to the cloud when SkyVault is enabled.
// Handles starting, monitoring, and completing the migration process.
class LocalFilesMigrationManager : public LocalUserFilesPolicyObserver,
                                   public KeyedService {
 public:
  class Observer {
   public:
    // Called when the migration of files to the cloud has completed
    // successfully.
    virtual void OnMigrationSucceeded() = 0;

    // Called when the migration of files to the cloud has been reset.
    virtual void OnMigrationReset() = 0;
  };

  // Creates an instance of LocalFilesMigrationManager with overridden
  // dependencies.
  static LocalFilesMigrationManager* CreateForTesting(
      content::BrowserContext* context,
      MigrationNotificationManager* notification_manager,
      std::unique_ptr<MigrationCoordinator> coordinator);

  // Creates an instance of LocalFilesMigrationManager.
  explicit LocalFilesMigrationManager(content::BrowserContext* context);
  LocalFilesMigrationManager(const LocalFilesMigrationManager&) = delete;
  LocalFilesMigrationManager& operator=(const LocalFilesMigrationManager&) =
      delete;
  ~LocalFilesMigrationManager() override;

  // Initializes this instance.
  void Initialize();

  // KeyedService overrides:
  void Shutdown() override;

  // Adds an observer to receive notifications about migration events.
  void AddObserver(Observer* observer);

  // Removes an observer.
  void RemoveObserver(Observer* observer);

  // Injects a mock MigrationNotificationManager for tests.
  void SetNotificationManagerForTesting(
      MigrationNotificationManager* notification_manager);

  // Injects a mock MigrationCoordinator for tests.
  void SetCoordinatorForTesting(
      std::unique_ptr<MigrationCoordinator> coordinator);

  // Injects a mock FilesCleanupHandler for tests.
  void SetCleanupHandlerForTesting(
      base::WeakPtr<chromeos::FilesCleanupHandler> cleanup_handler);

 private:
  // Called after the preferences have been loaded.
  void OnPrefsInitialized(bool success);

  // Initializes this instance, after the preferences have been loaded.
  void InitializeFromPrefs();

  // policy::local_user_files::Observer overrides:
  void OnLocalUserFilesPolicyChanged() override;

  // Called after migration is stopped and can be started again.
  void OnMigrationStopped(bool log_file_deleted);

  // Called after contents of MyFiles are checked. If empty, removes the volume
  // and restricts write access, otherwise initiates the migration based on the
  // current state.
  void OnMyFilesChecked(bool is_empty);

  // Informs the user about the upcoming migration. Schedules another dialog to
  // appear closer to the start. From the dialog, the user can also choose to
  // start the migration immediately.
  void InformUser();

  // After initial delay, informs the user again and schedules the migration to
  // start automatically. From the dialog, the user can also choose to start the
  // migration immediately.
  void ScheduleMigrationAndInformUser(const base::Time scheduled_start_time);

  // Bypasses the migration delay and initiates the upload process immediately.
  // Called when the user clicks the "Upload now" button in the info dialog.
  void SkipMigrationDelay();

  // Called after the full migration timeout elapses. Closes the dialog if
  // opened, and starts migration.
  void OnTimeoutExpired();

  // Gathers all file paths that need to be uploaded.
  void GetPathsToUpload();

  // Starts the migration process by uploading `files` to `cloud_provider_`.
  void StartMigration(std::vector<base::FilePath> files);

  // Handles the completion of the migration process (success or failure).
  // If the migration was successful, starts the cleanup process, and handles
  // the errors otherwise.
  void OnMigrationDone(std::map<base::FilePath, MigrationUploadError> errors,
                       base::FilePath upload_root_path,
                       base::FilePath error_log_path);

  // Completes the migration process, taking into account any errors that
  // occurred during the migration.
  void ProcessErrors(std::map<base::FilePath, MigrationUploadError> errors,
                     base::FilePath error_log_path);

  // Cleans up any remaining files from the device after a successful migration.
  void CleanupLocalFiles();

  // Handles the completion of the local files cleanup process.
  void OnCleanupDone(
      std::unique_ptr<chromeos::FilesCleanupHandler> cleanup_handler,
      const std::optional<std::string>& error_message);

  // Sends a D-Bus call to enable or disable write access to MyFiles.
  void SetLocalUserFilesWriteEnabled(bool enabled);

  // Handles the response of the SetUserDataStorageWriteEnabled D-Bus call.
  void OnFilesWriteRestricted(
      std::optional<user_data_auth::SetUserDataStorageWriteEnabledReply> reply);

  // Stops the migration if currently ongoing.
  void MaybeStopMigration(MigrationDestination previous_destination,
                          bool close_dialog = true,
                          MigrationStoppedCallback = base::DoNothing());

  // Sets and stores the state on the device.
  void SetState(State new_state);

  // Resets all stored prefs, like the state and start time, in case migration
  // is stopped.
  void ResetMigrationPrefs();

  // Notifies the observers that migration succeeded.
  void NotifySuccess();

  // Notifies the observers that migration was reset.
  void NotifyReset();

  // Observers for migration events.
  base::ObserverList<Observer>::Unchecked observers_;

  // Indicates the migration state.
  State state_ = State::kUninitialized;

  // Indicates if local files cleanup is currently running.
  bool cleanup_in_progress_ = false;

  // Whether local user files are allowed by policy.
  bool local_user_files_allowed_ = true;

  // Indicates how local files should be handled (upload to the cloud or
  // delete). If not specified, no migration happens.
  MigrationDestination migration_destination_ =
      MigrationDestination::kNotSpecified;

  // The name of the device-unique upload root folder on Drive
  std::string upload_root_;

  // Context for which this instance is created.
  raw_ptr<content::BrowserContext> context_;

  // Shows and manages migration notifications and dialogs.
  raw_ptr<MigrationNotificationManager> notification_manager_;

  // Manages the upload of local files to the cloud.
  std::unique_ptr<MigrationCoordinator> coordinator_;

  // Timer for delaying the start of migration and showing dialogs.
  std::unique_ptr<base::WallClockTimer> scheduling_timer_;

  // Number of times the entire upload failed and was retried.
  int current_retry_count_;

  base::WeakPtr<chromeos::FilesCleanupHandler> cleanup_handler_for_testing_ =
      nullptr;

  base::WeakPtrFactory<LocalFilesMigrationManager> weak_factory_{this};
};

// Manages all LocalFilesMigrationManager instances and associates them with
// Profiles.
class LocalFilesMigrationManagerFactory : public ProfileKeyedServiceFactory {
 public:
  LocalFilesMigrationManagerFactory(const LocalFilesMigrationManagerFactory&) =
      delete;
  LocalFilesMigrationManagerFactory& operator=(
      const LocalFilesMigrationManagerFactory&) = delete;

  // Gets the singleton instance of the factory.
  static LocalFilesMigrationManagerFactory* GetInstance();

  // Gets the LocalFilesMigrationManager instance associated with the given
  // BrowserContext. If `create` is true, an instance is created if it doesn't
  // exist.
  static LocalFilesMigrationManager* GetForBrowserContext(
      content::BrowserContext* context,
      bool create = true);

 private:
  friend base::NoDestructor<LocalFilesMigrationManagerFactory>;

  LocalFilesMigrationManagerFactory();
  ~LocalFilesMigrationManagerFactory() override;

  // BrowserContextKeyedServiceFactory overrides:
  bool ServiceIsNULLWhileTesting() const override;
  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
      content::BrowserContext* context) const override;
};

}  // namespace policy::local_user_files

#endif  // CHROME_BROWSER_ASH_POLICY_SKYVAULT_LOCAL_FILES_MIGRATION_MANAGER_H_