// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_RESOURCE_METADATA_H_ #define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_RESOURCE_METADATA_H_ #include #include #include #include "base/callback_forward.h" #include "base/file_path.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time.h" #include "chrome/browser/chromeos/drive/drive_file_error.h" namespace base { class SequencedTaskRunner; } namespace google_apis { class DocumentEntry; } namespace drive { struct CreateDBParams; class DriveDirectory; class DriveEntry; class DriveEntryProto; class DriveFile; class ResourceMetadataDB; typedef std::vector DriveEntryProtoVector; typedef std::map DriveEntryProtoMap; // File type on the drive file system can be either a regular file or // a hosted document. enum DriveFileType { REGULAR_FILE, HOSTED_DOCUMENT, }; // The root directory name used for the Google Drive file system tree. The // name is used in URLs for the file manager, hence user-visible. const FilePath::CharType kDriveRootDirectory[] = FILE_PATH_LITERAL("drive"); // The resource ID for the root directory for WAPI is defined in the spec: // https://developers.google.com/google-apps/documents-list/ // Note that this special ID only applies to WAPI. Drive uses a non-constant // unique ID given in About resource. const char kWAPIRootDirectoryResourceId[] = "folder:root"; // This should be incremented when incompatibility change is made in // drive.proto. const int32 kProtoVersion = 2; // Used for file operations like removing files. typedef base::Callback FileOperationCallback; // Callback similar to FileOperationCallback but with a given |file_path|. // Used for operations that change a file path like moving files. typedef base::Callback FileMoveCallback; // Used to get entry info from the file system. // If |error| is not DRIVE_FILE_OK, |entry_info| is set to NULL. typedef base::Callback entry_proto)> GetEntryInfoCallback; typedef base::Callback entries)> ReadDirectoryCallback; // Used to get entry info from the file system, with the Drive file path. // If |error| is not DRIVE_FILE_OK, |entry_proto| is set to NULL. // // |drive_file_path| parameter is provided as DriveEntryProto does not contain // the Drive file path (i.e. only contains the base name without parent // directory names). typedef base::Callback entry_proto)> GetEntryInfoWithFilePathCallback; // This is a part of EntryInfoPairResult. struct EntryInfoResult { EntryInfoResult(); ~EntryInfoResult(); FilePath path; DriveFileError error; scoped_ptr proto; }; // The result of GetEntryInfoPairCallback(). Used to get a pair of entries // in one function call. struct EntryInfoPairResult { EntryInfoPairResult(); ~EntryInfoPairResult(); EntryInfoResult first; EntryInfoResult second; // Only filled if the first entry is found. }; // Used to receive the result from GetEntryInfoPairCallback(). typedef base::Callback pair_result)> GetEntryInfoPairCallback; // Class to handle DriveEntry* lookups, add/remove DriveEntry*. class DriveResourceMetadata { public: // Map of resource id and serialized DriveEntry. typedef std::map SerializedMap; // Map of resource id strings to DriveEntry*. typedef std::map ResourceMap; DriveResourceMetadata(); ~DriveResourceMetadata(); DriveDirectory* root() { return root_.get(); } // Last time when we dumped serialized file system to disk. const base::Time& last_serialized() const { return last_serialized_; } void set_last_serialized(const base::Time& time) { last_serialized_ = time; } // Size of serialized file system on disk in bytes. size_t serialized_size() const { return serialized_size_; } void set_serialized_size(size_t size) { serialized_size_ = size; } // Largest change timestamp that was the source of content for the current // state of the root directory. int64 largest_changestamp() const { return largest_changestamp_; } void set_largest_changestamp(int64 value) { largest_changestamp_ = value; } // True if the file system feed is loaded from the cache or from the server. bool loaded() const { return loaded_; } void set_loaded(bool loaded) { loaded_ = loaded; } // Creates a DriveFile instance. scoped_ptr CreateDriveFile(); // Creates a DriveDirectory instance. scoped_ptr CreateDriveDirectory(); // Sets root directory resource ID and put root to ResourceMap. void InitializeRootEntry(const std::string& id); // Add |doc entry| to directory with path |directory_path| and invoke the // callback asynchronously. // |callback| must not be null. void AddEntryToDirectory(const FilePath& directory_path, scoped_ptr doc_entry, const FileMoveCallback& callback); // Moves entry specified by |file_path| to the directory specified by // |directory_path| and calls the callback asynchronously. Removes the entry // from the previous parent. // |callback| must not be null. void MoveEntryToDirectory(const FilePath& file_path, const FilePath& directory_path, const FileMoveCallback& callback); // Renames entry specified by |file_path| with the new name |new_name| and // calls |callback| asynchronously. // |callback| must not be null. void RenameEntry(const FilePath& file_path, const FilePath::StringType& new_name, const FileMoveCallback& callback); // Removes entry with |resource_id| from its parent. Calls |callback| with the // path of the parent directory. |callback| must not be null. void RemoveEntryFromParent(const std::string& resource_id, const FileMoveCallback& callback); // Adds the entry to resource map. Returns false if an entry with the same // resource_id exists. bool AddEntryToResourceMap(DriveEntry* entry); // Removes the entry from resource map. void RemoveEntryFromResourceMap(const std::string& resource_id); // Returns the DriveEntry* with the corresponding |resource_id|. // TODO(satorux): Remove this in favor of GetEntryInfoByResourceId() // but can be difficult. See crbug.com/137374 DriveEntry* GetEntryByResourceId(const std::string& resource_id); // Finds an entry (a file or a directory) by |resource_id|. // // Must be called from UI thread. |callback| is run on UI thread. // |callback| must not be null. void GetEntryInfoByResourceId( const std::string& resource_id, const GetEntryInfoWithFilePathCallback& callback); // Finds an entry (a file or a directory) by |file_path|. // // Must be called from UI thread. |callback| is run on UI thread. // |callback| must not be null. void GetEntryInfoByPath(const FilePath& file_path, const GetEntryInfoCallback& callback); // Finds and reads a directory by |file_path|. // // Must be called from UI thread. |callback| is run on UI thread. // |callback| must not be null. void ReadDirectoryByPath(const FilePath& file_path, const ReadDirectoryCallback& callback); // Similar to GetEntryInfoByPath() but this function finds a pair of // entries by |first_path| and |second_path|. If the entry for // |first_path| is not found, this function does not try to get the // entry of |second_path|. // // Must be called from UI thread. |callback| is run on UI thread. // |callback| must not be null. void GetEntryInfoPairByPaths( const FilePath& first_path, const FilePath& second_path, const GetEntryInfoPairCallback& callback); // Replaces a file entry with the same resource id as |doc_entry| by deleting // the existing entry, creating a new DriveFile from |doc_entry|, and adding // it to the parent of the old entry. For directories, this just returns the // existing directory proto. |callback| is run with the error, file path and // proto of the entry. |callback| must not be null. void RefreshFile(scoped_ptr doc_entry, const GetEntryInfoWithFilePathCallback& callback); // Removes all child files of |directory| and replaces them with // |entry_proto_map|. |callback| is called with the directory path. // |callback| must not be null. void RefreshDirectory(const std::string& directory_resource_id, const DriveEntryProtoMap& entry_proto_map, const FileMoveCallback& callback); // Moves all child entries from the directory represented by // |source_resource_id| to the directory respresented by // |destination_resource_id|. |callback| must not be null. void TakeOverEntries(const std::string& source_resource_id, const std::string& destination_resource_id, const FileMoveCallback& callback); // Serializes/Parses to/from string via proto classes. void SerializeToString(std::string* serialized_proto) const; bool ParseFromString(const std::string& serialized_proto); // Restores from and saves to database, calling |callback| asynchronously. // |callback| must not be null. void InitFromDB(const FilePath& db_path, base::SequencedTaskRunner* blocking_task_runner, const FileOperationCallback& callback); void SaveToDB(); // Creates DriveEntry from proto. scoped_ptr CreateDriveEntryFromProto( const DriveEntryProto& entry_proto); private: // Initializes the resource map using serialized_resources fetched from the // database. // |callback| must not be null. void InitResourceMap(CreateDBParams* create_params, const FileOperationCallback& callback); // Clears root_ and the resource map. void ClearRoot(); // Creates DriveEntry from serialized string. scoped_ptr CreateDriveEntryFromProtoString( const std::string& serialized_proto); // Continues with GetEntryInfoPairByPaths after the first DriveEntry has been // asynchronously fetched. This fetches the second DriveEntry only if the // first was found. void GetEntryInfoPairByPathsAfterGetFirst( const FilePath& first_path, const FilePath& second_path, const GetEntryInfoPairCallback& callback, DriveFileError error, scoped_ptr entry_proto); // Continues with GetIntroInfoPairByPaths after the second DriveEntry has been // asynchronously fetched. void GetEntryInfoPairByPathsAfterGetSecond( const FilePath& second_path, const GetEntryInfoPairCallback& callback, scoped_ptr result, DriveFileError error, scoped_ptr entry_proto); // Searches for |file_path| synchronously. // TODO(satorux): Replace this with an async version crbug.com/137160 DriveEntry* FindEntryByPathSync(const FilePath& file_path); // Private data members. scoped_refptr blocking_task_runner_; scoped_ptr resource_metadata_db_; ResourceMap resource_map_; scoped_ptr root_; // Stored in the serialized proto. base::Time last_serialized_; size_t serialized_size_; int64 largest_changestamp_; // Stored in the serialized proto. bool loaded_; // This should remain the last member so it'll be destroyed first and // invalidate its weak pointers before other members are destroyed. base::WeakPtrFactory weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(DriveResourceMetadata); }; } // namespace drive #endif // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_RESOURCE_METADATA_H_