• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/drive_backend_util.h"
6 
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "chrome/browser/drive/drive_api_util.h"
13 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
14 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
15 #include "google_apis/drive/drive_api_parser.h"
16 #include "google_apis/drive/gdata_wapi_parser.h"
17 #include "net/base/mime_util.h"
18 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
19 
20 namespace sync_file_system {
21 namespace drive_backend {
22 
23 namespace {
24 
25 const char kMimeTypeOctetStream[] = "application/octet-stream";
26 
27 }  // namespace
28 
PutServiceMetadataToBatch(const ServiceMetadata & service_metadata,leveldb::WriteBatch * batch)29 void PutServiceMetadataToBatch(const ServiceMetadata& service_metadata,
30                                leveldb::WriteBatch* batch) {
31   std::string value;
32   bool success = service_metadata.SerializeToString(&value);
33   DCHECK(success);
34   batch->Put(kServiceMetadataKey, value);
35 }
36 
PutFileToBatch(const FileMetadata & file,leveldb::WriteBatch * batch)37 void PutFileToBatch(const FileMetadata& file, leveldb::WriteBatch* batch) {
38   std::string value;
39   bool success = file.SerializeToString(&value);
40   DCHECK(success);
41   batch->Put(kFileMetadataKeyPrefix + file.file_id(), value);
42 }
43 
PutTrackerToBatch(const FileTracker & tracker,leveldb::WriteBatch * batch)44 void PutTrackerToBatch(const FileTracker& tracker, leveldb::WriteBatch* batch) {
45   std::string value;
46   bool success = tracker.SerializeToString(&value);
47   DCHECK(success);
48   batch->Put(kFileTrackerKeyPrefix + base::Int64ToString(tracker.tracker_id()),
49              value);
50 }
51 
PopulateFileDetailsByFileResource(const google_apis::FileResource & file_resource,FileDetails * details)52 void PopulateFileDetailsByFileResource(
53     const google_apis::FileResource& file_resource,
54     FileDetails* details) {
55   details->clear_parent_folder_ids();
56   for (ScopedVector<google_apis::ParentReference>::const_iterator itr =
57            file_resource.parents().begin();
58        itr != file_resource.parents().end();
59        ++itr) {
60     details->add_parent_folder_ids((*itr)->file_id());
61   }
62   details->set_title(file_resource.title());
63 
64   google_apis::DriveEntryKind kind = drive::util::GetKind(file_resource);
65   if (kind == google_apis::ENTRY_KIND_FILE)
66     details->set_file_kind(FILE_KIND_FILE);
67   else if (kind == google_apis::ENTRY_KIND_FOLDER)
68     details->set_file_kind(FILE_KIND_FOLDER);
69   else
70     details->set_file_kind(FILE_KIND_UNSUPPORTED);
71 
72   details->set_md5(file_resource.md5_checksum());
73   details->set_etag(file_resource.etag());
74   details->set_creation_time(file_resource.created_date().ToInternalValue());
75   details->set_modification_time(
76       file_resource.modified_date().ToInternalValue());
77   details->set_missing(false);
78 }
79 
CreateFileMetadataFromFileResource(int64 change_id,const google_apis::FileResource & resource)80 scoped_ptr<FileMetadata> CreateFileMetadataFromFileResource(
81     int64 change_id,
82     const google_apis::FileResource& resource) {
83   scoped_ptr<FileMetadata> file(new FileMetadata);
84   file->set_file_id(resource.file_id());
85 
86   FileDetails* details = file->mutable_details();
87   details->set_change_id(change_id);
88 
89   if (resource.labels().is_trashed()) {
90     details->set_missing(true);
91     return file.Pass();
92   }
93 
94   PopulateFileDetailsByFileResource(resource, details);
95   return file.Pass();
96 }
97 
CreateFileMetadataFromChangeResource(const google_apis::ChangeResource & change)98 scoped_ptr<FileMetadata> CreateFileMetadataFromChangeResource(
99     const google_apis::ChangeResource& change) {
100   scoped_ptr<FileMetadata> file(new FileMetadata);
101   file->set_file_id(change.file_id());
102 
103   FileDetails* details = file->mutable_details();
104   details->set_change_id(change.change_id());
105 
106   if (change.is_deleted()) {
107     details->set_missing(true);
108     return file.Pass();
109   }
110 
111   PopulateFileDetailsByFileResource(*change.file(), details);
112   return file.Pass();
113 }
114 
CreateDeletedFileMetadata(int64 change_id,const std::string & file_id)115 scoped_ptr<FileMetadata> CreateDeletedFileMetadata(
116     int64 change_id,
117     const std::string& file_id) {
118   scoped_ptr<FileMetadata> file(new FileMetadata);
119   file->set_file_id(file_id);
120 
121   FileDetails* details = file->mutable_details();
122   details->set_change_id(change_id);
123   details->set_missing(true);
124   return file.Pass();
125 }
126 
CreateTemporaryFile(base::TaskRunner * file_task_runner)127 webkit_blob::ScopedFile CreateTemporaryFile(
128     base::TaskRunner* file_task_runner) {
129   base::FilePath temp_file_path;
130   if (!base::CreateTemporaryFile(&temp_file_path))
131     return webkit_blob::ScopedFile();
132 
133   return webkit_blob::ScopedFile(
134       temp_file_path,
135       webkit_blob::ScopedFile::DELETE_ON_SCOPE_OUT,
136       file_task_runner);
137 }
138 
FileKindToString(FileKind file_kind)139 std::string FileKindToString(FileKind file_kind) {
140   switch (file_kind) {
141     case FILE_KIND_UNSUPPORTED:
142       return "unsupported";
143     case FILE_KIND_FILE:
144       return "file";
145     case FILE_KIND_FOLDER:
146       return "folder";
147   }
148 
149   NOTREACHED();
150   return "unknown";
151 }
152 
HasFileAsParent(const FileDetails & details,const std::string & file_id)153 bool HasFileAsParent(const FileDetails& details, const std::string& file_id) {
154   for (int i = 0; i < details.parent_folder_ids_size(); ++i) {
155     if (details.parent_folder_ids(i) == file_id)
156       return true;
157   }
158   return false;
159 }
160 
GetMimeTypeFromTitle(const base::FilePath & title)161 std::string GetMimeTypeFromTitle(const base::FilePath& title) {
162   base::FilePath::StringType extension = title.Extension();
163   std::string mime_type;
164   if (extension.empty() ||
165       !net::GetWellKnownMimeTypeFromExtension(extension.substr(1), &mime_type))
166     return kMimeTypeOctetStream;
167   return mime_type;
168 }
169 
GetOldestCreatedFolderResource(ScopedVector<google_apis::ResourceEntry> candidates)170 scoped_ptr<google_apis::ResourceEntry> GetOldestCreatedFolderResource(
171     ScopedVector<google_apis::ResourceEntry> candidates) {
172   scoped_ptr<google_apis::ResourceEntry> oldest;
173   for (size_t i = 0; i < candidates.size(); ++i) {
174     google_apis::ResourceEntry* entry = candidates[i];
175     if (!entry->is_folder() || entry->deleted())
176       continue;
177 
178     if (!oldest || oldest->published_time() > entry->published_time()) {
179       oldest.reset(entry);
180       candidates[i] = NULL;
181     }
182   }
183 
184   return oldest.Pass();
185 }
186 
187 }  // namespace drive_backend
188 }  // namespace sync_file_system
189