Home | History | Annotate | Download | only in drive_backend_v1
      1 // Copyright 2013 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 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_api_util.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/bind.h"
     10 #include "base/location.h"
     11 #include "base/message_loop/message_loop_proxy.h"
     12 #include "google_apis/drive/drive_entry_kinds.h"
     13 #include "webkit/common/blob/scoped_file.h"
     14 
     15 namespace sync_file_system {
     16 namespace drive_backend {
     17 
     18 bool FakeAPIUtil::RemoteResourceComparator::operator()(
     19     const RemoteResource& left,
     20     const RemoteResource& right) {
     21   if (left.parent_resource_id != right.parent_resource_id)
     22     return left.parent_resource_id < right.parent_resource_id;
     23   if (left.parent_title != right.parent_title)
     24     return left.parent_title < right.parent_title;
     25   if (left.title != right.title)
     26     return left.title < right.title;
     27   if (left.resource_id != right.resource_id)
     28     return left.resource_id < right.resource_id;
     29   if (left.md5_checksum != right.md5_checksum)
     30     return left.md5_checksum < right.md5_checksum;
     31   if (left.deleted != right.deleted)
     32     return left.deleted < right.deleted;
     33   return left.changestamp < right.changestamp;
     34 }
     35 
     36 struct FakeAPIUtil::ChangeStampComparator {
     37   bool operator()(const google_apis::ResourceEntry* left,
     38                   const google_apis::ResourceEntry* right) {
     39     return left->changestamp() < right->changestamp();
     40   }
     41 };
     42 
     43 FakeAPIUtil::RemoteResource::RemoteResource()
     44     : type(SYNC_FILE_TYPE_UNKNOWN), deleted(false), changestamp(0) {}
     45 
     46 FakeAPIUtil::RemoteResource::RemoteResource(
     47     const std::string& parent_resource_id,
     48     const std::string& parent_title,
     49     const std::string& title,
     50     const std::string& resource_id,
     51     const std::string& md5_checksum,
     52     SyncFileType type,
     53     bool deleted,
     54     int64 changestamp)
     55     : parent_resource_id(parent_resource_id),
     56       parent_title(parent_title),
     57       title(title),
     58       resource_id(resource_id),
     59       md5_checksum(md5_checksum),
     60       type(type),
     61       deleted(deleted),
     62       changestamp(changestamp) {}
     63 
     64 FakeAPIUtil::RemoteResource::~RemoteResource() {}
     65 
     66 FakeAPIUtil::FakeAPIUtil()
     67     : largest_changestamp_(0),
     68       url_generator_(
     69           GURL(google_apis::GDataWapiUrlGenerator::kBaseUrlForProduction),
     70           GURL(google_apis::GDataWapiUrlGenerator::
     71                kBaseDownloadUrlForProduction)) {}
     72 
     73 FakeAPIUtil::~FakeAPIUtil() {}
     74 
     75 void FakeAPIUtil::AddObserver(APIUtilObserver* observer) {}
     76 
     77 void FakeAPIUtil::RemoveObserver(APIUtilObserver* observer) {}
     78 
     79 void FakeAPIUtil::GetDriveDirectoryForSyncRoot(
     80     const ResourceIdCallback& callback) {
     81   base::MessageLoopProxy::current()->PostTask(
     82       FROM_HERE,
     83       base::Bind(callback,
     84                  google_apis::HTTP_SUCCESS,
     85                  "folder: sync_root_resource_id"));
     86 }
     87 
     88 void FakeAPIUtil::GetDriveDirectoryForOrigin(
     89     const std::string& sync_root_resource_id,
     90     const GURL& origin,
     91     const ResourceIdCallback& callback) {
     92   base::MessageLoopProxy::current()->PostTask(
     93       FROM_HERE,
     94       base::Bind(callback,
     95                  google_apis::HTTP_SUCCESS,
     96                  "folder resource_id for " + origin.host()));
     97 }
     98 
     99 void FakeAPIUtil::GetLargestChangeStamp(const ChangeStampCallback& callback) {
    100   base::MessageLoopProxy::current()->PostTask(
    101       FROM_HERE,
    102       base::Bind(callback, google_apis::HTTP_SUCCESS, largest_changestamp_));
    103 }
    104 
    105 void FakeAPIUtil::GetResourceEntry(const std::string& resource_id,
    106                                    const ResourceEntryCallback& callback) {
    107   NOTREACHED();
    108 }
    109 
    110 void FakeAPIUtil::ListFiles(const std::string& directory_resource_id,
    111                             const ResourceListCallback& callback) {
    112   ListChanges(0, callback);
    113 }
    114 
    115 void FakeAPIUtil::ListChanges(int64 start_changestamp,
    116                               const ResourceListCallback& callback) {
    117   scoped_ptr<google_apis::ResourceList> change_feed(
    118       new google_apis::ResourceList());
    119 
    120   ScopedVector<google_apis::ResourceEntry> entries;
    121   typedef RemoteResourceByResourceId::const_iterator iterator;
    122   for (iterator itr = remote_resources_.begin();
    123        itr != remote_resources_.end(); ++itr) {
    124     if (itr->second.changestamp < start_changestamp)
    125       continue;
    126     scoped_ptr<google_apis::ResourceEntry> entry(
    127         CreateResourceEntry(itr->second));
    128     entries.push_back(entry.release());
    129   }
    130 
    131   std::sort(entries.begin(), entries.end(), ChangeStampComparator());
    132 
    133   change_feed->set_entries(entries.Pass());
    134   change_feed->set_largest_changestamp(largest_changestamp_);
    135 
    136   base::MessageLoopProxy::current()->PostTask(
    137       FROM_HERE,
    138       base::Bind(
    139           callback, google_apis::HTTP_SUCCESS, base::Passed(&change_feed)));
    140 }
    141 
    142 void FakeAPIUtil::ContinueListing(const GURL& next_link,
    143                                   const ResourceListCallback& callback) {
    144   NOTREACHED();
    145 }
    146 
    147 void FakeAPIUtil::DownloadFile(const std::string& resource_id,
    148                                const std::string& local_file_md5,
    149                                const DownloadFileCallback& callback) {
    150   RemoteResourceByResourceId::iterator found =
    151       remote_resources_.find(resource_id);
    152   std::string file_md5;
    153   int64 file_size = 0;
    154   base::Time updated_time;
    155   google_apis::GDataErrorCode error = google_apis::HTTP_NOT_FOUND;
    156 
    157   if (found != remote_resources_.end() && !found->second.deleted) {
    158     scoped_ptr<google_apis::ResourceEntry> entry(
    159         CreateResourceEntry(found->second));
    160     file_md5 = entry->file_md5();
    161     file_size = entry->file_size();
    162     updated_time = entry->updated_time();
    163     error = google_apis::HTTP_SUCCESS;
    164   }
    165 
    166   webkit_blob::ScopedFile dummy;
    167   base::MessageLoopProxy::current()->PostTask(
    168       FROM_HERE,
    169       base::Bind(callback, error, file_md5, file_size, updated_time,
    170                  base::Passed(&dummy)));
    171 }
    172 
    173 void FakeAPIUtil::UploadNewFile(const std::string& directory_resource_id,
    174                                 const base::FilePath& local_file_path,
    175                                 const std::string& title,
    176                                 const UploadFileCallback& callback) {
    177   NOTREACHED();
    178 }
    179 
    180 void FakeAPIUtil::UploadExistingFile(const std::string& resource_id,
    181                                      const std::string& remote_file_md5,
    182                                      const base::FilePath& local_file_path,
    183                                      const UploadFileCallback& callback) {
    184   NOTREACHED();
    185 }
    186 
    187 void FakeAPIUtil::CreateDirectory(const std::string& parent_resource_id,
    188                                   const std::string& title,
    189                                   const ResourceIdCallback& callback) {
    190   NOTREACHED();
    191 }
    192 
    193 bool FakeAPIUtil::IsAuthenticated() const { return true; }
    194 
    195 void FakeAPIUtil::DeleteFile(const std::string& resource_id,
    196                              const std::string& remote_file_md5,
    197                              const GDataErrorCallback& callback) {
    198   if (!ContainsKey(remote_resources_, resource_id)) {
    199     base::MessageLoopProxy::current()->PostTask(
    200         FROM_HERE,
    201         base::Bind(callback, google_apis::HTTP_NOT_FOUND));
    202     return;
    203   }
    204 
    205   const RemoteResource& deleted_directory = remote_resources_[resource_id];
    206   PushRemoteChange(deleted_directory.parent_resource_id,
    207                    deleted_directory.parent_title,
    208                    deleted_directory.title,
    209                    deleted_directory.resource_id,
    210                    deleted_directory.md5_checksum,
    211                    SYNC_FILE_TYPE_UNKNOWN,
    212                    true /* deleted */);
    213 
    214   base::MessageLoopProxy::current()->PostTask(
    215       FROM_HERE,
    216       base::Bind(callback, google_apis::HTTP_SUCCESS));
    217 }
    218 
    219 void FakeAPIUtil::EnsureSyncRootIsNotInMyDrive(
    220     const std::string& sync_root_resource_id) {
    221   // Nothing to do.
    222 }
    223 
    224 void FakeAPIUtil::PushRemoteChange(const std::string& parent_resource_id,
    225                                    const std::string& parent_title,
    226                                    const std::string& title,
    227                                    const std::string& resource_id,
    228                                    const std::string& md5,
    229                                    SyncFileType type,
    230                                    bool deleted) {
    231   remote_resources_[resource_id] = RemoteResource(
    232       parent_resource_id, parent_title, title, resource_id,
    233       md5, type, deleted, ++largest_changestamp_);
    234 }
    235 
    236 scoped_ptr<google_apis::ResourceEntry> FakeAPIUtil::CreateResourceEntry(
    237     const RemoteResource& resource) const {
    238   scoped_ptr<google_apis::ResourceEntry> entry(
    239       new google_apis::ResourceEntry());
    240   ScopedVector<google_apis::Link> parent_links;
    241   scoped_ptr<google_apis::Link> link(new google_apis::Link());
    242 
    243   link->set_type(google_apis::Link::LINK_PARENT);
    244   link->set_href(ResourceIdToResourceLink(resource.parent_resource_id));
    245   link->set_title(resource.parent_title);
    246   parent_links.push_back(link.release());
    247 
    248   entry->set_links(parent_links.Pass());
    249   entry->set_title(resource.title);
    250   entry->set_resource_id(resource.resource_id);
    251   entry->set_file_md5(resource.md5_checksum);
    252   entry->set_deleted(resource.deleted);
    253   entry->set_changestamp(resource.changestamp);
    254 
    255   switch (resource.type) {
    256     case SYNC_FILE_TYPE_FILE:
    257       entry->set_kind(google_apis::ENTRY_KIND_FILE);
    258       break;
    259     case SYNC_FILE_TYPE_DIRECTORY:
    260       entry->set_kind(google_apis::ENTRY_KIND_FOLDER);
    261       break;
    262     case SYNC_FILE_TYPE_UNKNOWN:
    263       entry->set_kind(google_apis::ENTRY_KIND_UNKNOWN);
    264       break;
    265   }
    266 
    267   return entry.Pass();
    268 }
    269 
    270 GURL FakeAPIUtil::ResourceIdToResourceLink(
    271     const std::string& resource_id) const {
    272   return url_generator_.GenerateEditUrl(resource_id);
    273 }
    274 
    275 }  // namespace drive_backend
    276 }  // namespace sync_file_system
    277