summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/drive/drive_sync_client.h
blob: 77dc8d3af72344fc93dbed6ca7734b95607e4e9c (plain)
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
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_SYNC_CLIENT_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_SYNC_CLIENT_H_

#include <deque>
#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "chrome/browser/chromeos/drive/drive_cache.h"
#include "chrome/browser/chromeos/drive/drive_cache_observer.h"
#include "chrome/browser/chromeos/drive/drive_file_system_observer.h"
#include "chrome/browser/chromeos/drive/drive_resource_metadata.h"
#include "net/base/network_change_notifier.h"

class Profile;
class PrefChangeRegistrar;

namespace drive {

class DriveEntryProto;
class DriveFileSystemInterface;
class DrivePrefetcher;
class DriveSyncClientObserver;

// The DriveSyncClient is used to synchronize pinned files on Drive and the
// cache on the local drive. The sync client works as follows.
//
// When the user pins files on Drive, this client is notified about the files
// that get pinned, and queues tasks and starts fetching these files in the
// background.
//
// When the user unpins files on Drive, this client is notified about the
// files that get unpinned, cancels tasks if these are still in the queue.
//
// If the user logs out before fetching of the pinned files is complete, this
// client resumes fetching operations next time the user logs in, based on
// the states left in the cache.
class DriveSyncClient
    : public DriveFileSystemObserver,
      public DriveCacheObserver {
 public:
  // Types of sync tasks.
  enum SyncType {
    FETCH,  // Fetch a file from the Drive server.
    UPLOAD,  // Upload a file to the Drive server.
  };

  // |profile| is used to access user preferences.
  // |file_system| is used access the
  // cache (ex. store a file to the cache when the file is downloaded).
  DriveSyncClient(Profile* profile,
                  DriveFileSystemInterface* file_system,
                  DriveCache* cache);
  virtual ~DriveSyncClient();

  // Initializes the DriveSyncClient.
  void Initialize();

  // DriveFileSystemInterface::Observer overrides.
  virtual void OnInitialLoadFinished(DriveFileError error) OVERRIDE;
  virtual void OnFeedFromServerLoaded() OVERRIDE;

  // DriveCache::Observer overrides.
  virtual void OnCachePinned(const std::string& resource_id,
                             const std::string& md5) OVERRIDE;
  virtual void OnCacheUnpinned(const std::string& resource_id,
                               const std::string& md5) OVERRIDE;
  virtual void OnCacheCommitted(const std::string& resource_id) OVERRIDE;

  // Adds/Removes an observer.
  void AddObserver(DriveSyncClientObserver* observer);
  void RemoveObserver(DriveSyncClientObserver* observer);

  // Starts processing the backlog (i.e. pinned-but-not-filed files and
  // dirty-but-not-uploaded files). Kicks off retrieval of the resource
  // IDs of these files, and then starts the sync loop.
  void StartProcessingBacklog();

  // Starts checking the existing pinned files to see if these are
  // up-to-date. If stale files are detected, the resource IDs of these files
  // are added to the queue and the sync loop is started.
  void StartCheckingExistingPinnedFiles();

  // Returns the resource IDs in |queue_| for the given sync type. Used only
  // for testing.
  std::vector<std::string> GetResourceIdsForTesting(SyncType sync_type) const;

  // Adds the resource ID to the queue. Used only for testing.
  void AddResourceIdForTesting(SyncType sync_type,
                               const std::string& resource_id) {
    AddTaskToQueue(sync_type, resource_id);
  }

  // Sets a delay for testing.
  void set_delay_for_testing(const base::TimeDelta& delay) {
    delay_ = delay;
  }

  // Starts the sync loop if it's not running.
  void StartSyncLoop();

 private:
  friend class DriveSyncClientTest;

  // Adds the given task to the queue. If the same task is queued, remove the
  // existing one, and adds a new one to the end of the queue.
  void AddTaskToQueue(SyncType type, const std::string& resource_id);

  // Called when a task is ready to be added to the queue.
  void StartTask(SyncType type, const std::string& resource_id);

  // Called when the resource IDs of files in the backlog are obtained.
  void OnGetResourceIdsOfBacklog(const std::vector<std::string>* to_fetch,
                                 const std::vector<std::string>* to_upload);

  // Called when the resource ID of a pinned file is obtained.
  void OnGetResourceIdOfExistingPinnedFile(const std::string& resource_id,
                                           const DriveCacheEntry& cache_entry);

  // Called when a file entry is obtained.
  void OnGetEntryInfoByResourceId(const std::string& resource_id,
                                  const DriveCacheEntry& cache_entry,
                                  DriveFileError error,
                                  const base::FilePath& file_path,
                                  scoped_ptr<DriveEntryProto> entry_proto);

  // Called when a cache entry is obtained.
  void OnGetCacheEntry(const std::string& resource_id,
                       const std::string& latest_md5,
                       bool success,
                       const DriveCacheEntry& cache_entry);

  // Called when an existing cache entry and the local files are removed.
  void OnRemove(const std::string& resource_id, DriveFileError error);

  // Called when a file is pinned.
  void OnPinned(const std::string& resource_id, DriveFileError error);

  // Called when the file for |resource_id| is fetched.
  // Calls DoSyncLoop() to go back to the sync loop.
  void OnFetchFileComplete(const std::string& resource_id,
                           DriveFileError error,
                           const base::FilePath& local_path,
                           const std::string& ununsed_mime_type,
                           DriveFileType file_type);

  // Called when the file for |resource_id| is uploaded.
  // Calls DoSyncLoop() to go back to the sync loop.
  void OnUploadFileComplete(const std::string& resource_id,
                            DriveFileError error);

  Profile* profile_;
  DriveFileSystemInterface* file_system_;  // Owned by DriveSystemService.
  DriveCache* cache_;  // Owned by DriveSystemService.
  ObserverList<DriveSyncClientObserver> observers_;

  // List of the resource ids of resources which have a fetch task created.
  std::set<std::string> fetch_list_;

  // List of the resource ids of resources which have a upload task created.
  std::set<std::string> upload_list_;

  // Fetch tasks which have been created, but not started yet.  If they are
  // removed before starting, they will be cancelled.
  std::set<std::string> pending_fetch_list_;

  // The delay is used for delaying processing SyncTasks in DoSyncLoop().
  base::TimeDelta delay_;

  // 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<DriveSyncClient> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(DriveSyncClient);
};

}  // namespace drive

#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_SYNC_CLIENT_H_