Home | History | Annotate | Download | only in drive
      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