| OLD | NEW |
| (Empty) |
| 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_GDATA_GDATA_DIRECTORY_SERVICE_H_ | |
| 6 #define CHROME_BROWSER_CHROMEOS_GDATA_GDATA_DIRECTORY_SERVICE_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <string> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/callback.h" | |
| 13 #include "base/file_path.h" | |
| 14 #include "base/memory/scoped_ptr.h" | |
| 15 #include "base/memory/weak_ptr.h" | |
| 16 #include "base/time.h" | |
| 17 #include "chrome/browser/chromeos/gdata/gdata_errorcode.h" | |
| 18 | |
| 19 namespace base { | |
| 20 class SequencedTaskRunner; | |
| 21 } | |
| 22 | |
| 23 namespace gdata { | |
| 24 | |
| 25 struct CreateDBParams; | |
| 26 class DocumentEntry; | |
| 27 class DriveDirectory; | |
| 28 class DriveEntry; | |
| 29 class DriveEntryProto; | |
| 30 class DriveFile; | |
| 31 class ResourceMetadataDB; | |
| 32 | |
| 33 typedef std::vector<DriveEntryProto> DriveEntryProtoVector; | |
| 34 | |
| 35 // File type on the gdata file system can be either a regular file or | |
| 36 // a hosted document. | |
| 37 enum DriveFileType { | |
| 38 REGULAR_FILE, | |
| 39 HOSTED_DOCUMENT, | |
| 40 }; | |
| 41 | |
| 42 // The root directory content origin. | |
| 43 enum ContentOrigin { | |
| 44 UNINITIALIZED, | |
| 45 // Content is currently loading from somewhere. Needs to wait. | |
| 46 INITIALIZING, | |
| 47 // Content is initialized, but during refreshing. | |
| 48 REFRESHING, | |
| 49 // Content is initialized from disk cache. | |
| 50 FROM_CACHE, | |
| 51 // Content is initialized from the direct server response. | |
| 52 FROM_SERVER, | |
| 53 }; | |
| 54 | |
| 55 // The root directory name used for the Google Drive file system tree. The | |
| 56 // name is used in URLs for the file manager, hence user-visible. | |
| 57 const FilePath::CharType kGDataRootDirectory[] = FILE_PATH_LITERAL("drive"); | |
| 58 | |
| 59 // The resource ID for the root directory is defined in the spec: | |
| 60 // https://developers.google.com/google-apps/documents-list/ | |
| 61 const char kGDataRootDirectoryResourceId[] = "folder:root"; | |
| 62 | |
| 63 // This should be incremented when incompatibility change is made in | |
| 64 // drive.proto. | |
| 65 const int32 kProtoVersion = 2; | |
| 66 | |
| 67 // Callback type used to get result of file search. | |
| 68 // If |error| is not PLATFORM_FILE_OK, |entry| is set to NULL. | |
| 69 typedef base::Callback<void(GDataFileError error, DriveEntry* entry)> | |
| 70 FindEntryCallback; | |
| 71 | |
| 72 // Used for file operations like removing files. | |
| 73 typedef base::Callback<void(GDataFileError error)> | |
| 74 FileOperationCallback; | |
| 75 | |
| 76 // Callback similar to FileOperationCallback but with a given |file_path|. | |
| 77 // Used for operations that change a file path like moving files. | |
| 78 typedef base::Callback<void(GDataFileError error, | |
| 79 const FilePath& file_path)> | |
| 80 FileMoveCallback; | |
| 81 | |
| 82 // Used to get entry info from the file system. | |
| 83 // If |error| is not GDATA_FILE_OK, |entry_info| is set to NULL. | |
| 84 typedef base::Callback<void(GDataFileError error, | |
| 85 scoped_ptr<DriveEntryProto> entry_proto)> | |
| 86 GetEntryInfoCallback; | |
| 87 | |
| 88 typedef base::Callback<void(GDataFileError error, | |
| 89 scoped_ptr<DriveEntryProtoVector> entries)> | |
| 90 ReadDirectoryCallback; | |
| 91 | |
| 92 // Used to get entry info from the file system, with the Drive file path. | |
| 93 // If |error| is not GDATA_FILE_OK, |entry_proto| is set to NULL. | |
| 94 // | |
| 95 // |drive_file_path| parameter is provided as DriveEntryProto does not contain | |
| 96 // the Drive file path (i.e. only contains the base name without parent | |
| 97 // directory names). | |
| 98 typedef base::Callback<void(GDataFileError error, | |
| 99 const FilePath& drive_file_path, | |
| 100 scoped_ptr<DriveEntryProto> entry_proto)> | |
| 101 GetEntryInfoWithFilePathCallback; | |
| 102 | |
| 103 // This is a part of EntryInfoPairResult. | |
| 104 struct EntryInfoResult { | |
| 105 EntryInfoResult(); | |
| 106 ~EntryInfoResult(); | |
| 107 | |
| 108 FilePath path; | |
| 109 GDataFileError error; | |
| 110 scoped_ptr<DriveEntryProto> proto; | |
| 111 }; | |
| 112 | |
| 113 // The result of GetEntryInfoPairCallback(). Used to get a pair of entries | |
| 114 // in one function call. | |
| 115 struct EntryInfoPairResult { | |
| 116 EntryInfoPairResult(); | |
| 117 ~EntryInfoPairResult(); | |
| 118 | |
| 119 EntryInfoResult first; | |
| 120 EntryInfoResult second; // Only filled if the first entry is found. | |
| 121 }; | |
| 122 | |
| 123 // Used to receive the result from GetEntryInfoPairCallback(). | |
| 124 typedef base::Callback<void(scoped_ptr<EntryInfoPairResult> pair_result)> | |
| 125 GetEntryInfoPairCallback; | |
| 126 | |
| 127 // Class to handle DriveEntry* lookups, add/remove DriveEntry*. | |
| 128 class GDataDirectoryService { | |
| 129 public: | |
| 130 // Callback for GetEntryByResourceIdAsync. | |
| 131 typedef base::Callback<void(DriveEntry* entry)> GetEntryByResourceIdCallback; | |
| 132 | |
| 133 // Map of resource id and serialized DriveEntry. | |
| 134 typedef std::map<std::string, std::string> SerializedMap; | |
| 135 // Map of resource id strings to DriveEntry*. | |
| 136 typedef std::map<std::string, DriveEntry*> ResourceMap; | |
| 137 | |
| 138 GDataDirectoryService(); | |
| 139 ~GDataDirectoryService(); | |
| 140 | |
| 141 DriveDirectory* root() { return root_.get(); } | |
| 142 | |
| 143 // Last time when we dumped serialized file system to disk. | |
| 144 const base::Time& last_serialized() const { return last_serialized_; } | |
| 145 void set_last_serialized(const base::Time& time) { last_serialized_ = time; } | |
| 146 // Size of serialized file system on disk in bytes. | |
| 147 const size_t serialized_size() const { return serialized_size_; } | |
| 148 void set_serialized_size(size_t size) { serialized_size_ = size; } | |
| 149 | |
| 150 // Largest change timestamp that was the source of content for the current | |
| 151 // state of the root directory. | |
| 152 const int64 largest_changestamp() const { return largest_changestamp_; } | |
| 153 void set_largest_changestamp(int64 value) { largest_changestamp_ = value; } | |
| 154 | |
| 155 // The root directory content origin. | |
| 156 const ContentOrigin origin() const { return origin_; } | |
| 157 void set_origin(ContentOrigin value) { origin_ = value; } | |
| 158 | |
| 159 // Creates a DriveEntry from a DocumentEntry. | |
| 160 DriveEntry* FromDocumentEntry(const DocumentEntry& doc); | |
| 161 | |
| 162 // Creates a DriveFile instance. | |
| 163 DriveFile* CreateDriveFile(); | |
| 164 | |
| 165 // Creates a DriveDirectory instance. | |
| 166 DriveDirectory* CreateDriveDirectory(); | |
| 167 | |
| 168 // Sets root directory resource id and initialize the root entry. | |
| 169 void InitializeRootEntry(const std::string& root_id); | |
| 170 | |
| 171 // Add |new entry| to |directory| and invoke the callback asynchronously. | |
| 172 // |callback| may not be null. | |
| 173 // TODO(achuith,satorux): Use DriveEntryProto instead for new_entry. | |
| 174 // crbug.com/142048 | |
| 175 void AddEntryToDirectory(DriveDirectory* directory, | |
| 176 DriveEntry* new_entry, | |
| 177 const FileMoveCallback& callback); | |
| 178 | |
| 179 // Moves |entry| to |directory_path| asynchronously. Removes entry from | |
| 180 // previous parent. Must be called on UI thread. |callback| is called on the | |
| 181 // UI thread. |callback| may not be null. | |
| 182 void MoveEntryToDirectory(const FilePath& directory_path, | |
| 183 DriveEntry* entry, | |
| 184 const FileMoveCallback& callback); | |
| 185 | |
| 186 // Removes |entry| from its parent. Calls |callback| with the path of the | |
| 187 // parent directory. |callback| may not be null. | |
| 188 void RemoveEntryFromParent(DriveEntry* entry, | |
| 189 const FileMoveCallback& callback); | |
| 190 | |
| 191 // Adds the entry to resource map. | |
| 192 void AddEntryToResourceMap(DriveEntry* entry); | |
| 193 | |
| 194 // Removes the entry from resource map. | |
| 195 void RemoveEntryFromResourceMap(const std::string& resource_id); | |
| 196 | |
| 197 // Searches for |file_path| synchronously. | |
| 198 // TODO(satorux): Replace this with an async version crbug.com/137160 | |
| 199 DriveEntry* FindEntryByPathSync(const FilePath& file_path); | |
| 200 | |
| 201 // Returns the DriveEntry* with the corresponding |resource_id|. | |
| 202 // TODO(satorux): Remove this in favor of GetEntryInfoByResourceId() | |
| 203 // but can be difficult. See crbug.com/137374 | |
| 204 DriveEntry* GetEntryByResourceId(const std::string& resource_id); | |
| 205 | |
| 206 // Returns the DriveEntry* in the callback with the corresponding | |
| 207 // |resource_id|. TODO(satorux): Remove this in favor of | |
| 208 // GetEntryInfoByResourceId(). crbug.com/137512 | |
| 209 void GetEntryByResourceIdAsync(const std::string& resource_id, | |
| 210 const GetEntryByResourceIdCallback& callback); | |
| 211 | |
| 212 // Finds an entry (a file or a directory) by |resource_id|. | |
| 213 // | |
| 214 // Must be called from UI thread. |callback| is run on UI thread. | |
| 215 // |callback| must not be null. | |
| 216 void GetEntryInfoByResourceId( | |
| 217 const std::string& resource_id, | |
| 218 const GetEntryInfoWithFilePathCallback& callback); | |
| 219 | |
| 220 // Finds an entry (a file or a directory) by |file_path|. | |
| 221 // | |
| 222 // Must be called from UI thread. |callback| is run on UI thread. | |
| 223 // |callback| must not be null. | |
| 224 void GetEntryInfoByPath(const FilePath& file_path, | |
| 225 const GetEntryInfoCallback& callback); | |
| 226 | |
| 227 // Finds and reads a directory by |file_path|. | |
| 228 // | |
| 229 // Must be called from UI thread. |callback| is run on UI thread. | |
| 230 // |callback| must not be null. | |
| 231 void ReadDirectoryByPath(const FilePath& file_path, | |
| 232 const ReadDirectoryCallback& callback); | |
| 233 | |
| 234 // Similar to GetEntryInfoByPath() but this function finds a pair of | |
| 235 // entries by |first_path| and |second_path|. If the entry for | |
| 236 // |first_path| is not found, this function does not try to get the | |
| 237 // entry of |second_path|. | |
| 238 // | |
| 239 // Must be called from UI thread. |callback| is run on UI thread. | |
| 240 // |callback| must not be null. | |
| 241 void GetEntryInfoPairByPaths( | |
| 242 const FilePath& first_path, | |
| 243 const FilePath& second_path, | |
| 244 const GetEntryInfoPairCallback& callback); | |
| 245 | |
| 246 // Replaces file entry with the same resource id as |fresh_file| with its | |
| 247 // fresh value |fresh_file|. | |
| 248 void RefreshFile(scoped_ptr<DriveFile> fresh_file); | |
| 249 | |
| 250 // Removes all child files of |directory| and replace with file_map. | |
| 251 // |callback| is called with the directory path. |callback| may not be null. | |
| 252 void RefreshDirectory(const std::string& directory_resource_id, | |
| 253 const ResourceMap& file_map, | |
| 254 const FileMoveCallback& callback); | |
| 255 | |
| 256 // Serializes/Parses to/from string via proto classes. | |
| 257 void SerializeToString(std::string* serialized_proto) const; | |
| 258 bool ParseFromString(const std::string& serialized_proto); | |
| 259 | |
| 260 // Restores from and saves to database. | |
| 261 void InitFromDB(const FilePath& db_path, | |
| 262 base::SequencedTaskRunner* blocking_task_runner, | |
| 263 const FileOperationCallback& callback); | |
| 264 void SaveToDB(); | |
| 265 | |
| 266 private: | |
| 267 // Initializes the resource map using serialized_resources fetched from the | |
| 268 // database. | |
| 269 void InitResourceMap(CreateDBParams* create_params, | |
| 270 const FileOperationCallback& callback); | |
| 271 | |
| 272 // Clears root_ and the resource map. | |
| 273 void ClearRoot(); | |
| 274 | |
| 275 // Creates DriveEntry from serialized string. | |
| 276 scoped_ptr<DriveEntry> FromProtoString( | |
| 277 const std::string& serialized_proto); | |
| 278 | |
| 279 // Continues with GetEntryInfoPairByPaths after the first DriveEntry has been | |
| 280 // asynchronously fetched. This fetches the second DriveEntry only if the | |
| 281 // first was found. | |
| 282 void GetEntryInfoPairByPathsAfterGetFirst( | |
| 283 const FilePath& first_path, | |
| 284 const FilePath& second_path, | |
| 285 const GetEntryInfoPairCallback& callback, | |
| 286 GDataFileError error, | |
| 287 scoped_ptr<DriveEntryProto> entry_proto); | |
| 288 | |
| 289 // Continues with GetIntroInfoPairByPaths after the second DriveEntry has been | |
| 290 // asynchronously fetched. | |
| 291 void GetEntryInfoPairByPathsAfterGetSecond( | |
| 292 const FilePath& second_path, | |
| 293 const GetEntryInfoPairCallback& callback, | |
| 294 scoped_ptr<EntryInfoPairResult> result, | |
| 295 GDataFileError error, | |
| 296 scoped_ptr<DriveEntryProto> entry_proto); | |
| 297 | |
| 298 // These internal functions need friend access to private DriveDirectory | |
| 299 // methods. | |
| 300 // Replaces file entry |old_entry| with its fresh value |fresh_file|. | |
| 301 static void RefreshFileInternal(scoped_ptr<DriveFile> fresh_file, | |
| 302 DriveEntry* old_entry); | |
| 303 | |
| 304 // Removes all child files of |directory| and replace with file_map. | |
| 305 // |callback| may not be null. | |
| 306 static void RefreshDirectoryInternal(const ResourceMap& file_map, | |
| 307 const FileMoveCallback& callback, | |
| 308 DriveEntry* directory_entry); | |
| 309 | |
| 310 // Private data members. | |
| 311 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | |
| 312 scoped_ptr<ResourceMetadataDB> directory_service_db_; | |
| 313 | |
| 314 ResourceMap resource_map_; | |
| 315 | |
| 316 scoped_ptr<DriveDirectory> root_; // Stored in the serialized proto. | |
| 317 | |
| 318 base::Time last_serialized_; | |
| 319 size_t serialized_size_; | |
| 320 int64 largest_changestamp_; // Stored in the serialized proto. | |
| 321 ContentOrigin origin_; | |
| 322 | |
| 323 // This should remain the last member so it'll be destroyed first and | |
| 324 // invalidate its weak pointers before other members are destroyed. | |
| 325 base::WeakPtrFactory<GDataDirectoryService> weak_ptr_factory_; | |
| 326 | |
| 327 DISALLOW_COPY_AND_ASSIGN(GDataDirectoryService); | |
| 328 }; | |
| 329 | |
| 330 } // namespace gdata | |
| 331 | |
| 332 #endif // CHROME_BROWSER_CHROMEOS_GDATA_GDATA_DIRECTORY_SERVICE_H_ | |
| OLD | NEW |