1 // Copyright (c) 2012 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_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_ 6 #define CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_vector.h" 15 #include "base/observer_list.h" 16 #include "chrome/browser/chromeos/drive/file_errors.h" 17 #include "google_apis/drive/drive_common_callbacks.h" 18 #include "google_apis/drive/gdata_errorcode.h" 19 20 class GURL; 21 22 namespace base { 23 class ScopedClosureRunner; 24 class SequencedTaskRunner; 25 class Time; 26 } // namespace base 27 28 namespace google_apis { 29 class AboutResource; 30 class ResourceList; 31 } // namespace google_apis 32 33 namespace drive { 34 35 class EventLogger; 36 class JobScheduler; 37 class ResourceEntry; 38 39 namespace internal { 40 41 class ChangeList; 42 class ChangeListLoaderObserver; 43 class ChangeListProcessor; 44 class DirectoryLoader; 45 class ResourceMetadata; 46 47 // Delays execution of tasks as long as more than one lock is alive. 48 // Used to ensure that ChangeListLoader does not cause race condition by adding 49 // new entries created by sync tasks before they do. 50 // All code which may add entries found on the server to the local metadata 51 // should use this class. 52 class LoaderController { 53 public: 54 LoaderController(); 55 ~LoaderController(); 56 57 // Increments the lock count and returns an object which decrements the count 58 // on its destruction. 59 // While the lock count is positive, tasks will be pending. 60 scoped_ptr<base::ScopedClosureRunner> GetLock(); 61 62 // Runs the task if the lock count is 0, otherwise it will be pending. 63 void ScheduleRun(const base::Closure& task); 64 65 private: 66 // Decrements the lock count. 67 void Unlock(); 68 69 int lock_count_; 70 std::vector<base::Closure> pending_tasks_; 71 72 base::WeakPtrFactory<LoaderController> weak_ptr_factory_; 73 DISALLOW_COPY_AND_ASSIGN(LoaderController); 74 }; 75 76 // This class is responsible to load AboutResource from the server and cache it. 77 class AboutResourceLoader { 78 public: 79 explicit AboutResourceLoader(JobScheduler* scheduler); 80 ~AboutResourceLoader(); 81 82 // Returns the cached about resource. 83 // NULL is returned if the cache is not available. 84 const google_apis::AboutResource* cached_about_resource() const { 85 return cached_about_resource_.get(); 86 } 87 88 // Gets the about resource from the cache or the server. If the cache is 89 // availlavle, just runs |callback| with the cached about resource. If not, 90 // calls |UpdateAboutResource| passing |callback|. 91 void GetAboutResource(const google_apis::AboutResourceCallback& callback); 92 93 // Gets the about resource from the server, and caches it if successful. This 94 // function calls JobScheduler::GetAboutResource internally. The cache will be 95 // used in |GetAboutResource|. 96 void UpdateAboutResource( 97 const google_apis::AboutResourceCallback& callback); 98 99 private: 100 // Part of UpdateAboutResource(). 101 // This function should be called when the latest about resource is being 102 // fetched from the server. The retrieved about resoure is cloned, and one is 103 // cached and the other is passed to |callback|. 104 void UpdateAboutResourceAfterGetAbout( 105 const google_apis::AboutResourceCallback& callback, 106 google_apis::GDataErrorCode status, 107 scoped_ptr<google_apis::AboutResource> about_resource); 108 109 JobScheduler* scheduler_; 110 scoped_ptr<google_apis::AboutResource> cached_about_resource_; 111 base::WeakPtrFactory<AboutResourceLoader> weak_ptr_factory_; 112 DISALLOW_COPY_AND_ASSIGN(AboutResourceLoader); 113 }; 114 115 // ChangeListLoader is used to load the change list, the full resource list, 116 // and directory contents, from WAPI (codename for Documents List API) 117 // or Google Drive API. The class also updates the resource metadata with 118 // the change list loaded from the server. 119 // 120 // Note that the difference between "resource list" and "change list" is 121 // subtle hence the two words are often used interchangeably. To be precise, 122 // "resource list" refers to metadata from the server when fetching the full 123 // resource metadata, or fetching directory contents, whereas "change list" 124 // refers to metadata from the server when fetching changes (delta). 125 class ChangeListLoader { 126 public: 127 // Resource feed fetcher from the server. 128 class FeedFetcher; 129 130 ChangeListLoader(EventLogger* logger, 131 base::SequencedTaskRunner* blocking_task_runner, 132 ResourceMetadata* resource_metadata, 133 JobScheduler* scheduler, 134 AboutResourceLoader* about_resource_loader, 135 LoaderController* apply_task_controller); 136 ~ChangeListLoader(); 137 138 // Indicates whether there is a request for full resource list or change 139 // list fetching is in flight (i.e. directory contents fetching does not 140 // count). 141 bool IsRefreshing() const; 142 143 // Adds and removes the observer. 144 void AddObserver(ChangeListLoaderObserver* observer); 145 void RemoveObserver(ChangeListLoaderObserver* observer); 146 147 // Checks for updates on the server. Does nothing if the change list is now 148 // being loaded or refreshed. |callback| must not be null. 149 // Note: |callback| will be called if the check for updates actually 150 // runs, i.e. it may NOT be called if the checking is ignored. 151 void CheckForUpdates(const FileOperationCallback& callback); 152 153 // Starts the change list loading if needed. If the locally stored metadata is 154 // available, runs |callback| immediately and starts checking server for 155 // updates in background. If the locally stored metadata is not available, 156 // starts loading from the server, and runs |callback| to tell the result to 157 // the caller when it is finished. 158 // 159 // |callback| must not be null. 160 void LoadIfNeeded(const FileOperationCallback& callback); 161 162 private: 163 // Starts the resource metadata loading and calls |callback| when it's done. 164 void Load(const FileOperationCallback& callback); 165 void LoadAfterGetLargestChangestamp(bool is_initial_load, 166 const int64* local_changestamp, 167 FileError error); 168 void LoadAfterGetAboutResource( 169 int64 local_changestamp, 170 google_apis::GDataErrorCode status, 171 scoped_ptr<google_apis::AboutResource> about_resource); 172 173 // Part of Load(). 174 // This function should be called when the change list load is complete. 175 // Flushes the callbacks for change list loading and all directory loading. 176 void OnChangeListLoadComplete(FileError error); 177 178 // ================= Implementation for change list loading ================= 179 180 // Part of LoadFromServerIfNeeded(). 181 // Starts loading the change list since |start_changestamp|, or the full 182 // resource list if |start_changestamp| is zero. 183 void LoadChangeListFromServer(int64 start_changestamp); 184 185 // Part of LoadChangeListFromServer(). 186 // Called when the entire change list is loaded. 187 void LoadChangeListFromServerAfterLoadChangeList( 188 scoped_ptr<google_apis::AboutResource> about_resource, 189 bool is_delta_update, 190 FileError error, 191 ScopedVector<ChangeList> change_lists); 192 193 // Part of LoadChangeListFromServer(). 194 // Called when the resource metadata is updated. 195 void LoadChangeListFromServerAfterUpdate( 196 ChangeListProcessor* change_list_processor, 197 bool should_notify_changed_directories, 198 const base::Time& start_time, 199 FileError error); 200 201 EventLogger* logger_; // Not owned. 202 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; 203 ResourceMetadata* resource_metadata_; // Not owned. 204 JobScheduler* scheduler_; // Not owned. 205 AboutResourceLoader* about_resource_loader_; // Not owned. 206 LoaderController* loader_controller_; // Not owned. 207 ObserverList<ChangeListLoaderObserver> observers_; 208 std::vector<FileOperationCallback> pending_load_callback_; 209 FileOperationCallback pending_update_check_callback_; 210 211 // Running feed fetcher. 212 scoped_ptr<FeedFetcher> change_feed_fetcher_; 213 214 // True if the full resource list is loaded (i.e. the resource metadata is 215 // stored locally). 216 bool loaded_; 217 218 // Note: This should remain the last member so it'll be destroyed and 219 // invalidate its weak pointers before any other members are destroyed. 220 base::WeakPtrFactory<ChangeListLoader> weak_ptr_factory_; 221 DISALLOW_COPY_AND_ASSIGN(ChangeListLoader); 222 }; 223 224 } // namespace internal 225 } // namespace drive 226 227 #endif // CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_ 228