File: drive_integration_service.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 (595 lines) | stat: -rw-r--r-- 22,215 bytes parent folder | download | duplicates (3)
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
// Copyright 2012 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_DRIVE_DRIVE_INTEGRATION_SERVICE_H_
#define CHROME_BROWSER_ASH_DRIVE_DRIVE_INTEGRATION_SERVICE_H_

#include <memory>
#include <string>
#include <variant>
#include <vector>

#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chromeos/ash/components/drivefs/drivefs_host.h"
#include "chromeos/ash/components/drivefs/drivefs_pinning_manager.h"
#include "chromeos/ash/components/drivefs/mojom/drivefs.mojom.h"
#include "chromeos/ash/components/drivefs/mojom/notifications.mojom.h"
#include "chromeos/ash/components/network/network_state.h"
#include "chromeos/ash/components/network/network_state_handler.h"
#include "chromeos/ash/components/network/network_state_handler_observer.h"
#include "components/drive/event_logger.h"
#include "components/drive/file_errors.h"
#include "components/drive/file_system_core_util.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "google_apis/common/api_error_codes.h"
#include "google_apis/common/auth_service_interface.h"

class PrefService;

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace drivefs {
class DriveFsHost;
class DriveFsSearchQuery;

namespace mojom {
class DriveFs;
}  // namespace mojom
}  // namespace drivefs

namespace user_prefs {
class PrefRegistrySyncable;
}  // namespace user_prefs

namespace drive {

namespace internal {
class ResourceMetadataStorage;
}  // namespace internal

// Mounting status. These values are persisted to logs. Entries should not be
// renumbered and numeric values should never be reused.
enum class DriveMountStatus {
  kSuccess = 0,
  kUnknownFailure = 1,
  kTemporaryUnavailable = 2,
  kInvocationFailure = 3,
  kUnexpectedDisconnect = 4,
  kTimeout = 5,
  kMaxValue = kTimeout,
};

struct QuickAccessItem {
  base::FilePath path;
  double confidence;
};

// Notifications/Errors coming from DriveFs side which we need to persist in
// the Chrome side.
struct PersistedMessage {
  // Where does the message come from in DriveFs.
  enum Source {
    kNotification = 0,
    kError = 1,
  };
  Source source;

  // DriveFs Notification/Error types which require persistence.
  using Type = std::variant<drivefs::mojom::DriveFsNotification::Tag,
                            drivefs::mojom::MirrorSyncError::Type>;
  Type type;

  base::FilePath path;

  int64_t stable_id;
};

// DriveIntegrationService is used to integrate Drive to Chrome. This class
// exposes the file system representation built on top of Drive and some
// other Drive related objects to the file manager, and some other sub
// systems.
//
// The class is essentially a container that manages lifetime of the objects
// that are used to integrate Drive to Chrome. The object of this class is
// created per-profile.
class DriveIntegrationService : public KeyedService,
                                public drivefs::DriveFsHost::MountObserver,
                                drivefs::pinning::PinningManager::Observer,
                                ash::NetworkStateHandler::Observer {
 public:
  using DriveFsMojoListenerFactory = base::RepeatingCallback<
      std::unique_ptr<drivefs::DriveFsBootstrapListener>()>;
  using GetQuickAccessItemsCallback =
      base::OnceCallback<void(FileError, std::vector<QuickAccessItem>)>;
  using SearchDriveByFileNameCallback =
      drivefs::mojom::SearchQuery::GetNextPageCallback;
  using GetThumbnailCallback =
      base::OnceCallback<void(const std::optional<std::vector<uint8_t>>&)>;
  using GetReadOnlyAuthenticationTokenCallback =
      base::OnceCallback<void(google_apis::ApiErrorCode code,
                              const std::string& access_token)>;

  // test_mount_point_name, test_cache_root and
  // test_drivefs_mojo_listener_factory are used by tests to inject customized
  // instances.
  // Pass NULL or the empty value when not interested.
  // `local_state` must be non-null and must outlive `this`.
  DriveIntegrationService(
      PrefService* local_state,
      Profile* profile,
      const std::string& test_mount_point_name,
      const base::FilePath& test_cache_root,
      DriveFsMojoListenerFactory test_drivefs_mojo_listener_factory = {});

  DriveIntegrationService(const DriveIntegrationService&) = delete;
  DriveIntegrationService& operator=(const DriveIntegrationService&) = delete;

  ~DriveIntegrationService() override;

  // KeyedService override.
  void Shutdown() override;

  void SetEnabled(bool enabled);
  bool is_enabled() const { return enabled_; }

  bool IsOnline() const { return is_online_; }

  bool IsMounted() const;

  bool mount_failed() const { return mount_failed_; }

  // Returns the path of the mount point for drive. It is only valid to call if
  // |IsMounted()|.
  base::FilePath GetMountPointPath() const;

  // Returns the path of DriveFS log if enabled or empty path.
  base::FilePath GetDriveFsLogPath() const;

  // Returns the path of the DriveFs content cache.
  base::FilePath GetDriveFsContentCachePath() const;

  // Returns true if |local_path| resides inside |GetMountPointPath()|.
  // In this case |drive_path| will contain 'drive' path of this file, e.g.
  // reparented to the mount point.
  // It is only valid to call if |IsMounted()|.
  bool GetRelativeDrivePath(const base::FilePath& local_path,
                            base::FilePath* drive_path) const;

  bool IsSharedDrive(const base::FilePath& local_path) const;

  // Base class for classes that need to observe events from
  // DriveIntegrationService. All events are notified on the UI thread.
  class Observer : public base::CheckedObserver {
   public:
    ~Observer() override;

    // Triggered when the `DriveIntegrationService` is being destroyed.
    virtual void OnDriveIntegrationServiceDestroyed() {}

    // Triggered when the file system is mounted.
    virtual void OnFileSystemMounted() {}

    // Triggered when the file system is being unmounted.
    virtual void OnFileSystemBeingUnmounted() {}

    // Triggered when mounting the filesystem has failed in a fashion that will
    // not be automatically retried.
    virtual void OnFileSystemMountFailed() {}

    // Triggered when the mirroring functionality is enabled.
    virtual void OnMirroringEnabled() {}

    // Triggered when the mirroring functionality is disabled.
    virtual void OnMirroringDisabled() {}

    // Triggered when the bulk pinning manager reports progress.
    virtual void OnBulkPinProgress(const drivefs::pinning::Progress& progress) {
    }

    // Triggered when the bulk-pinning manager is fully initialized.
    virtual void OnBulkPinInitialized() {}

    // Triggered when the network connection to Drive could have changed.
    virtual void OnDriveConnectionStatusChanged(util::ConnectionStatus status) {
    }

    // Starts observing the given service.
    void Observe(DriveIntegrationService* service);

    // Stops observing the service.
    void Reset();

    // Gets a pointer to the service being observed.
    DriveIntegrationService* GetService() const { return service_; }

   private:
    // The service being observed.
    raw_ptr<DriveIntegrationService> service_ = nullptr;
  };

  // MountObserver implementation.
  void OnMounted(const base::FilePath& mount_path) override;
  void OnUnmounted(std::optional<base::TimeDelta> remount_delay) override;
  void OnMountFailed(MountFailure failure,
                     std::optional<base::TimeDelta> remount_delay) override;

  // PinningManager::Observer implementation
  using Progress = drivefs::pinning::Progress;
  void OnProgress(const Progress& progress) override;

  EventLogger* GetLogger() { return &logger_; }

  // Clears all the local cache folder and remounts the file system. |callback|
  // is called with true when this operation is done successfully. Otherwise,
  // |callback| is called with false. |callback| must not be null.
  void ClearCacheAndRemountFileSystem(base::OnceCallback<void(bool)> callback);

  // Returns the DriveFsHost if it is enabled.
  drivefs::DriveFsHost* GetDriveFsHost() const;

  // Returns the PinningManager if DriveFS is mounted and bulk-pinning is
  // enabled.
  using PinningManager = drivefs::pinning::PinningManager;
  PinningManager* GetPinningManager() const;

  // Returns the mojo interface to the DriveFs daemon if it is enabled and
  // connected.
  drivefs::mojom::DriveFs* GetDriveFsInterface() const;

  void GetQuickAccessItems(int max_number,
                           GetQuickAccessItemsCallback callback);

  void SearchDriveByFileName(
      std::string query,
      int max_results,
      drivefs::mojom::QueryParameters::SortField sort_field,
      drivefs::mojom::QueryParameters::SortDirection sort_direction,
      drivefs::mojom::QueryParameters::QuerySource query_source,
      SearchDriveByFileNameCallback callback) const;
  // Returns nullptr if DriveFS is not mounted.
  std::unique_ptr<drivefs::DriveFsSearchQuery> CreateSearchQueryByFileName(
      std::string query,
      int max_results,
      drivefs::mojom::QueryParameters::SortField sort_field,
      drivefs::mojom::QueryParameters::SortDirection sort_direction,
      drivefs::mojom::QueryParameters::QuerySource query_source) const;

  // Returns the metadata for Drive file at |local_path|.
  void GetMetadata(const base::FilePath& local_path,
                   drivefs::mojom::DriveFs::GetMetadataCallback callback);

  // Locates files or dirs by their server-side ID. Paths are relative to the
  // mount point.
  void LocateFilesByItemIds(
      const std::vector<std::string>& item_ids,
      drivefs::mojom::DriveFs::LocateFilesByItemIdsCallback callback);

  // Returns the total and free space available in the user's Drive.
  void GetQuotaUsage(drivefs::mojom::DriveFs::GetQuotaUsageCallback callback);

  // Returns the total and free space available in the user's Drive.
  // Additionally, if the user belongs to an organization, whether the
  // organization quota is full or not, and the name of the organization.
  void GetPooledQuotaUsage(
      drivefs::mojom::DriveFs::GetPooledQuotaUsageCallback callback);

  void RestartDrive();

  // Sets the arguments to be parsed by DriveFS on startup. Should only be
  // called in developer mode.
  void SetStartupArguments(std::string arguments,
                           base::OnceCallback<void(bool)> callback);

  // Gets the currently set arguments parsed by DriveFS on startup. Should only
  // be called in developer mode.
  void GetStartupArguments(
      base::OnceCallback<void(const std::string&)> callback);

  // Enables or disables performance tracing, which logs to
  // |data_dir_path|/Logs/drive_fs_trace.
  void SetTracingEnabled(bool enabled);

  // Enables or disables networking for testing. Should only be called in
  // developer mode.
  void SetNetworkingEnabled(bool enabled);

  // Overrides syncing to be paused if enabled. Should only be called in
  // developer mode.
  void ForcePauseSyncing(bool enabled);

  // Dumps account settings (including feature flags) to
  // |data_dir_path/account_settings. Should only be called in developer mode.
  void DumpAccountSettings();

  // Loads account settings (including feature flags) from
  // |data_dir_path/account_settings. Should only be called in developer mode.
  void LoadAccountSettings();

  // Returns a PNG containing a thumbnail for |path|. If |crop_to_square|, a
  // 360x360 thumbnail, cropped to fit a square is returned; otherwise a
  // thumbnail up to 500x500, maintaining aspect ration, is returned. If |path|
  // does not exist or does not have a thumbnail, |thumbnail| will be null.
  void GetThumbnail(const base::FilePath& path,
                    bool crop_to_square,
                    GetThumbnailCallback callback);

  // Toggle mirroring on or off defined by |enabled|.
  void ToggleMirroring(
      bool enabled,
      drivefs::mojom::DriveFs::ToggleMirroringCallback callback);

  // Toggle syncing for a specific path. Should only be called once mirroring
  // has been enabled via |ToggleMirroring|.
  void ToggleSyncForPath(
      const base::FilePath& path,
      drivefs::mojom::MirrorPathStatus status,
      drivefs::mojom::DriveFs::ToggleSyncForPathCallback callback);

  // Retrieves a list of paths being synced.
  void GetSyncingPaths(
      drivefs::mojom::DriveFs::GetSyncingPathsCallback callback);

  // Tells DriveFS to update its cached pin states of hosted files (once).
  void PollHostedFilePinStates();

  // Returns whether mirroring is enabled.
  bool IsMirroringEnabled();

  // Requests Drive to resync the office file at |local_path| from the cloud.
  void ForceReSyncFile(const base::FilePath& local_path,
                       base::OnceClosure callback);

  // Gets a read-only OAuth token that allows downloading files from the user's
  // Drive. If an error occurs or the user does not have access to download
  // files from Drive, `access_token` will be an empty string.
  void GetReadOnlyAuthenticationToken(
      GetReadOnlyAuthenticationTokenCallback callback);

  // Returns via callback the amount of storage taken by all currently pinned
  // files.
  void GetTotalPinnedSize(base::OnceCallback<void(int64_t)> callback);

  void ClearOfflineFiles(base::OnceCallback<void(FileError)> callback);

  // Tells Drive to immediately start uploading the file at |path|, which is a
  // relative path in Drive. This avoids queuing delays for newly created files,
  // when we are sure that there are no more subsequent operations on the file
  // that we should wait for.
  void ImmediatelyUpload(
      const base::FilePath& path,
      drivefs::mojom::DriveFs::ImmediatelyUploadCallback callback);

  // Gets counts of files in docs offline extension.
  void GetDocsOfflineStats(
      drivefs::mojom::DriveFs::GetDocsOfflineStatsCallback callback);

  // Gets the mirror sync status for a specific file.
  void GetMirrorSyncStatusForFile(
      const base::FilePath& path,
      drivefs::mojom::DriveFs::GetMirrorSyncStatusForFileCallback callback);

  // Gets the mirror sync status for a specific directory.
  void GetMirrorSyncStatusForDirectory(
      const base::FilePath& path,
      drivefs::mojom::DriveFs::GetMirrorSyncStatusForDirectoryCallback
          callback);

  void OnNetworkChanged();

  // Register the drive related profile prefs.
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* prefs);

 private:
  enum class State {
    kNone,
    kInitializing,
    kInitialized,
    kRemounting,
  };

  class DriveFsHolder;

  PrefService* GetPrefs() const { return profile_->GetPrefs(); }

  // Returns true if Drive is enabled.
  // Must be called on UI thread.
  bool IsDriveEnabled();

  enum class DirResult { kError, kExisting, kCreated };
  static DirResult EnsureDirectoryExists(const base::FilePath& data_dir);

  // Registers remote file system for drive mount point. If DriveFS is enabled,
  // but not yet mounted, this will start it mounting and wait for it to
  // complete before adding the mount point.
  void AddDriveMountPoint();

  // Mounts Drive if the directory exists.
  void MaybeMountDrive(const base::FilePath& data_dir,
                       DirResult data_dir_result);

  // Registers remote file system for drive mount point.
  bool AddDriveMountPointAfterMounted();

  // Unregisters drive mount point from File API.
  void RemoveDriveMountPoint();

  // Adds back the drive mount point.
  // Used to implement ClearCacheAndRemountFileSystem().
  void AddBackDriveMountPoint(base::OnceCallback<void(bool)> callback,
                              FileError error);

  // Unregisters drive mount point, and if |remount_delay| is specified
  // then tries to add it back after that delay. If |remount_delay| isn't
  // specified, |failed_to_mount| is true and the user is offline, schedules a
  // retry when the user is online.
  void MaybeRemountFileSystem(std::optional<base::TimeDelta> remount_delay,
                              bool failed_to_mount);

  // Helper function for ClearCacheAndRemountFileSystem() that deletes the cache
  // folder.
  void ClearCacheAndRemountFileSystemAfterDelay(
      base::OnceCallback<void(bool)> callback);

  // Helper function for ClearCacheAndRemountFileSystem() that remounts Drive if
  // necessary.
  void MaybeRemountFileSystemAfterClearCache(
      base::OnceCallback<void(bool)> callback,
      bool success);

  // Initializes the object. This function should be called before any
  // other functions.
  void Initialize();

  // Called when metadata initialization is done. Continues initialization if
  // the metadata initialization is successful.
  void InitializeAfterMetadataInitialized(FileError error);

  // Change the download directory to the local "Downloads" if the download
  // destination is set under Drive. This must be called when disabling Drive.
  void AvoidDriveAsDownloadDirectoryPreference();

  bool DownloadDirectoryPreferenceIsInDrive();

  // Migrate pinned files from the old Drive integration to DriveFS.
  void MigratePinnedFiles();

  // Pin all the files in |files_to_pin| with DriveFS.
  void PinFiles(const std::vector<base::FilePath>& files_to_pin);

  // Called when the "drivefs.bulk_pinning_enabled" pref changes value.
  // Starts or stops DriveFS bulk pinning accordingly.
  // Does nothing if there is no bulk-pinning manager.
  void StartOrStopBulkPinning();

  // Called when the "drivefs.bulk_pinning.visible" pref changes value.
  // Creates or deletes the DriveFS bulk-pinning manager accordingly.
  void CreateOrDeleteBulkPinningManager();

  // Regularly samples the bulk-pinning preference and stores the result in a
  // UMA histogram.
  void SampleBulkPinningPref();

  void OnGetOfflineItemsPage(
      int64_t total_size,
      mojo::Remote<drivefs::mojom::SearchQuery> search_query,
      base::OnceCallback<void(int64_t)> callback,
      FileError error,
      std::optional<std::vector<drivefs::mojom::QueryItemPtr>> results);

  void OnGetQuickAccessItems(
      GetQuickAccessItemsCallback callback,
      FileError error,
      std::optional<std::vector<drivefs::mojom::QueryItemPtr>> items);

  void OnSearchDriveByFileName(
      SearchDriveByFileNameCallback callback,
      FileError error,
      std::optional<std::vector<drivefs::mojom::QueryItemPtr>> items);

  void OnEnableMirroringStatusUpdate(drivefs::mojom::MirrorSyncStatus status);
  void OnMyFilesSyncPathAdded(drive::FileError status);

  void OnDisableMirroringStatusUpdate(drivefs::mojom::MirrorSyncStatus status);

  // Before adding a new root, get all existing roots first to see if it exists
  // or not. If it exists, do nothing.
  void OnGetSyncPathsForAddingPath(
      const base::FilePath& path_to_add,
      drivefs::mojom::DriveFs::ToggleSyncForPathCallback callback,
      drive::FileError status,
      const std::vector<base::FilePath>& paths);

  // Toggle syncing for |path| if the the directory exists.
  void ToggleSyncForPathIfDirectoryExists(
      const base::FilePath& path,
      drivefs::mojom::DriveFs::ToggleSyncForPathCallback callback,
      bool exists);

  void OnUpdateFromPairedDocComplete(const base::FilePath& drive_path,
                                     base::OnceClosure callback,
                                     FileError error);

  void OnGetOfflineFilesSpaceUsage(base::OnceCallback<void(int64_t)> callback,
                                   FileError error,
                                   int64_t total_size);

  void RegisterPrefs();
  void OnDrivePrefChanged();
  void OnMirroringPrefChanged();

  // NetworkStateHandler::Observer implementation.
  void PortalStateChanged(const ash::NetworkState*,
                          ash::NetworkState::PortalState portal_state) override;
  void DefaultNetworkChanged(const ash::NetworkState*) override;
  void OnShuttingDown() override;

  friend class DriveIntegrationServiceFactory;

  const raw_ptr<Profile> profile_;

  State state_ = State::kNone;
  bool enabled_ = false;
  bool mount_failed_ = false;
  bool in_clear_cache_ = false;

  // Is the bulk-pinning preference sampling task currently scheduled?
  bool bulk_pinning_pref_sampling_ = false;
  bool mirroring_enabled_ = false;
  bool is_online_ = true;
  bool remount_when_online_ = false;

  // Custom mount point name that can be injected for testing in constructor.
  std::string mount_point_name_;
  base::FilePath cache_root_directory_;
  EventLogger logger_;
  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
  std::unique_ptr<internal::ResourceMetadataStorage, util::DestroyHelper>
      metadata_storage_;

  base::ObserverList<Observer, true> observers_;

  std::unique_ptr<DriveFsHolder> drivefs_holder_;

  std::unique_ptr<PinningManager> pinning_manager_;

  int drivefs_total_failures_count_ = 0;
  int drivefs_consecutive_failures_count_ = 0;

  // Used to fetch authentication and refresh tokens from Drive.
  std::unique_ptr<google_apis::AuthServiceInterface> auth_service_;

  base::TimeTicks mount_start_;

  base::Time last_offline_storage_size_time_;
  int64_t last_offline_storage_size_result_;

  PrefChangeRegistrar registrar_;

  base::ScopedObservation<ash::NetworkStateHandler,
                          ash::NetworkStateHandler::Observer>
      network_state_handler_{this};

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<DriveIntegrationService> weak_ptr_factory_{this};

  FRIEND_TEST_ALL_PREFIXES(DriveIntegrationServiceTest, EnsureDirectoryExists);
};

}  // namespace drive

#endif  // CHROME_BROWSER_ASH_DRIVE_DRIVE_INTEGRATION_SERVICE_H_