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