Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3258)

Unified Diff: chrome/browser/chromeos/drive/resource_metadata.cc

Issue 1296483003: Move chrome/browser/chromeos/drive/resource* (+deps) into components/drive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing... Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/drive/resource_metadata.cc
diff --git a/chrome/browser/chromeos/drive/resource_metadata.cc b/chrome/browser/chromeos/drive/resource_metadata.cc
deleted file mode 100644
index 1842fe5bcd8c77a5fdaba4b85314be91c9ee5c83..0000000000000000000000000000000000000000
--- a/chrome/browser/chromeos/drive/resource_metadata.cc
+++ /dev/null
@@ -1,607 +0,0 @@
-// 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.
-
-#include "chrome/browser/chromeos/drive/resource_metadata.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/guid.h"
-#include "base/location.h"
-#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/sys_info.h"
-#include "chrome/browser/chromeos/drive/file_cache.h"
-#include "chrome/browser/chromeos/drive/file_system_core_util.h"
-#include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
-#include "components/drive/drive.pb.h"
-
-namespace drive {
-namespace internal {
-namespace {
-
-// Returns true if enough disk space is available for DB operation.
-// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface.
-bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) {
- const int64 kRequiredDiskSpaceInMB = 128; // 128 MB seems to be large enough.
- return base::SysInfo::AmountOfFreeDiskSpace(path) >=
- kRequiredDiskSpaceInMB * (1 << 20);
-}
-
-// Returns a file name with a uniquifier appended. (e.g. "File (1).txt")
-std::string GetUniquifiedName(const std::string& name, int uniquifier) {
- base::FilePath name_path = base::FilePath::FromUTF8Unsafe(name);
- name_path = name_path.InsertBeforeExtensionASCII(
- base::StringPrintf(" (%d)", uniquifier));
- return name_path.AsUTF8Unsafe();
-}
-
-// Returns true when there is no entry with the specified name under the parent
-// other than the specified entry.
-FileError EntryCanUseName(ResourceMetadataStorage* storage,
- const std::string& parent_local_id,
- const std::string& local_id,
- const std::string& base_name,
- bool* result) {
- std::string existing_entry_id;
- FileError error = storage->GetChild(parent_local_id, base_name,
- &existing_entry_id);
- if (error == FILE_ERROR_OK)
- *result = existing_entry_id == local_id;
- else if (error == FILE_ERROR_NOT_FOUND)
- *result = true;
- else
- return error;
- return FILE_ERROR_OK;
-}
-
-// Returns true when the ID is used by an immutable entry.
-bool IsImmutableEntry(const std::string& id) {
- return id == util::kDriveGrandRootLocalId ||
- id == util::kDriveOtherDirLocalId ||
- id == util::kDriveTrashDirLocalId;
-}
-
-} // namespace
-
-ResourceMetadata::ResourceMetadata(
- ResourceMetadataStorage* storage,
- FileCache* cache,
- scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
- : blocking_task_runner_(blocking_task_runner),
- storage_(storage),
- cache_(cache) {
-}
-
-FileError ResourceMetadata::Initialize() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- return SetUpDefaultEntries();
-}
-
-void ResourceMetadata::Destroy() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- blocking_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ResourceMetadata::DestroyOnBlockingPool,
- base::Unretained(this)));
-}
-
-FileError ResourceMetadata::Reset() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
- return FILE_ERROR_NO_LOCAL_SPACE;
-
- FileError error = storage_->SetLargestChangestamp(0);
- if (error != FILE_ERROR_OK)
- return error;
-
- // Remove all root entries.
- scoped_ptr<Iterator> it = GetIterator();
- for (; !it->IsAtEnd(); it->Advance()) {
- if (it->GetValue().parent_local_id().empty()) {
- error = RemoveEntryRecursively(it->GetID());
- if (error != FILE_ERROR_OK)
- return error;
- }
- }
- if (it->HasError())
- return FILE_ERROR_FAILED;
-
- return SetUpDefaultEntries();
-}
-
-ResourceMetadata::~ResourceMetadata() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-}
-
-FileError ResourceMetadata::SetUpDefaultEntries() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- // Initialize "/drive".
- ResourceEntry entry;
- FileError error = storage_->GetEntry(util::kDriveGrandRootLocalId, &entry);
- if (error == FILE_ERROR_NOT_FOUND) {
- ResourceEntry root;
- root.mutable_file_info()->set_is_directory(true);
- root.set_local_id(util::kDriveGrandRootLocalId);
- root.set_title(util::kDriveGrandRootDirName);
- root.set_base_name(util::kDriveGrandRootDirName);
- error = storage_->PutEntry(root);
- if (error != FILE_ERROR_OK)
- return error;
- } else if (error == FILE_ERROR_OK) {
- if (!entry.resource_id().empty()) {
- // Old implementations used kDriveGrandRootLocalId as a resource ID.
- entry.clear_resource_id();
- error = storage_->PutEntry(entry);
- if (error != FILE_ERROR_OK)
- return error;
- }
- } else {
- return error;
- }
-
- // Initialize "/drive/other".
- error = storage_->GetEntry(util::kDriveOtherDirLocalId, &entry);
- if (error == FILE_ERROR_NOT_FOUND) {
- ResourceEntry other_dir;
- other_dir.mutable_file_info()->set_is_directory(true);
- other_dir.set_local_id(util::kDriveOtherDirLocalId);
- other_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
- other_dir.set_title(util::kDriveOtherDirName);
- error = PutEntryUnderDirectory(other_dir);
- if (error != FILE_ERROR_OK)
- return error;
- } else if (error == FILE_ERROR_OK) {
- if (!entry.resource_id().empty()) {
- // Old implementations used kDriveOtherDirLocalId as a resource ID.
- entry.clear_resource_id();
- error = storage_->PutEntry(entry);
- if (error != FILE_ERROR_OK)
- return error;
- }
- } else {
- return error;
- }
-
- // Initialize "drive/trash".
- error = storage_->GetEntry(util::kDriveTrashDirLocalId, &entry);
- if (error == FILE_ERROR_NOT_FOUND) {
- ResourceEntry trash_dir;
- trash_dir.mutable_file_info()->set_is_directory(true);
- trash_dir.set_local_id(util::kDriveTrashDirLocalId);
- trash_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
- trash_dir.set_title(util::kDriveTrashDirName);
- error = PutEntryUnderDirectory(trash_dir);
- if (error != FILE_ERROR_OK)
- return error;
- } else if (error != FILE_ERROR_OK) {
- return error;
- }
-
- // Initialize "drive/root".
- std::string child_id;
- error = storage_->GetChild(
- util::kDriveGrandRootLocalId, util::kDriveMyDriveRootDirName, &child_id);
- if (error == FILE_ERROR_NOT_FOUND) {
- ResourceEntry mydrive;
- mydrive.mutable_file_info()->set_is_directory(true);
- mydrive.set_parent_local_id(util::kDriveGrandRootLocalId);
- mydrive.set_title(util::kDriveMyDriveRootDirName);
-
- std::string local_id;
- error = AddEntry(mydrive, &local_id);
- if (error != FILE_ERROR_OK)
- return error;
- } else if (error != FILE_ERROR_OK) {
- return error;
- }
- return FILE_ERROR_OK;
-}
-
-void ResourceMetadata::DestroyOnBlockingPool() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- delete this;
-}
-
-FileError ResourceMetadata::GetLargestChangestamp(int64* out_value) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- return storage_->GetLargestChangestamp(out_value);
-}
-
-FileError ResourceMetadata::SetLargestChangestamp(int64 value) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
- return FILE_ERROR_NO_LOCAL_SPACE;
-
- return storage_->SetLargestChangestamp(value);
-}
-
-FileError ResourceMetadata::AddEntry(const ResourceEntry& entry,
- std::string* out_id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(entry.local_id().empty());
-
- if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
- return FILE_ERROR_NO_LOCAL_SPACE;
-
- ResourceEntry parent;
- FileError error = storage_->GetEntry(entry.parent_local_id(), &parent);
- if (error != FILE_ERROR_OK)
- return error;
- if (!parent.file_info().is_directory())
- return FILE_ERROR_NOT_A_DIRECTORY;
-
- // Multiple entries with the same resource ID should not be present.
- std::string local_id;
- ResourceEntry existing_entry;
- if (!entry.resource_id().empty()) {
- error = storage_->GetIdByResourceId(entry.resource_id(), &local_id);
- if (error == FILE_ERROR_OK)
- error = storage_->GetEntry(local_id, &existing_entry);
-
- if (error == FILE_ERROR_OK)
- return FILE_ERROR_EXISTS;
- else if (error != FILE_ERROR_NOT_FOUND)
- return error;
- }
-
- // Generate unique local ID when needed.
- // We don't check for ID collisions as its probability is extremely low.
- if (local_id.empty())
- local_id = base::GenerateGUID();
-
- ResourceEntry new_entry(entry);
- new_entry.set_local_id(local_id);
-
- error = PutEntryUnderDirectory(new_entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- *out_id = local_id;
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RemoveEntry(const std::string& id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
- return FILE_ERROR_NO_LOCAL_SPACE;
-
- // Disallow deletion of default entries.
- if (IsImmutableEntry(id))
- return FILE_ERROR_ACCESS_DENIED;
-
- ResourceEntry entry;
- FileError error = storage_->GetEntry(id, &entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- return RemoveEntryRecursively(id);
-}
-
-FileError ResourceMetadata::GetResourceEntryById(const std::string& id,
- ResourceEntry* out_entry) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(!id.empty());
- DCHECK(out_entry);
-
- return storage_->GetEntry(id, out_entry);
-}
-
-FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path,
- ResourceEntry* out_entry) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(out_entry);
-
- std::string id;
- FileError error = GetIdByPath(path, &id);
- if (error != FILE_ERROR_OK)
- return error;
-
- return GetResourceEntryById(id, out_entry);
-}
-
-FileError ResourceMetadata::ReadDirectoryByPath(
- const base::FilePath& path,
- ResourceEntryVector* out_entries) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(out_entries);
-
- std::string id;
- FileError error = GetIdByPath(path, &id);
- if (error != FILE_ERROR_OK)
- return error;
- return ReadDirectoryById(id, out_entries);
-}
-
-FileError ResourceMetadata::ReadDirectoryById(
- const std::string& id,
- ResourceEntryVector* out_entries) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(out_entries);
-
- ResourceEntry entry;
- FileError error = GetResourceEntryById(id, &entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- if (!entry.file_info().is_directory())
- return FILE_ERROR_NOT_A_DIRECTORY;
-
- std::vector<std::string> children;
- error = storage_->GetChildren(id, &children);
- if (error != FILE_ERROR_OK)
- return error;
-
- ResourceEntryVector entries(children.size());
- for (size_t i = 0; i < children.size(); ++i) {
- error = storage_->GetEntry(children[i], &entries[i]);
- if (error != FILE_ERROR_OK)
- return error;
- }
- out_entries->swap(entries);
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
- return FILE_ERROR_NO_LOCAL_SPACE;
-
- ResourceEntry old_entry;
- FileError error = storage_->GetEntry(entry.local_id(), &old_entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- if (IsImmutableEntry(entry.local_id()) ||
- old_entry.file_info().is_directory() != // Reject incompatible input.
- entry.file_info().is_directory())
- return FILE_ERROR_INVALID_OPERATION;
-
- if (!entry.resource_id().empty()) {
- // Multiple entries cannot share the same resource ID.
- std::string local_id;
- FileError error = GetIdByResourceId(entry.resource_id(), &local_id);
- switch (error) {
- case FILE_ERROR_OK:
- if (local_id != entry.local_id())
- return FILE_ERROR_INVALID_OPERATION;
- break;
-
- case FILE_ERROR_NOT_FOUND:
- break;
-
- default:
- return error;
- }
- }
-
- // Make sure that the new parent exists and it is a directory.
- ResourceEntry new_parent;
- error = storage_->GetEntry(entry.parent_local_id(), &new_parent);
- if (error != FILE_ERROR_OK)
- return error;
-
- if (!new_parent.file_info().is_directory())
- return FILE_ERROR_NOT_A_DIRECTORY;
-
- // Do not overwrite cache states.
- // Cache state should be changed via FileCache.
- ResourceEntry updated_entry(entry);
- if (old_entry.file_specific_info().has_cache_state()) {
- *updated_entry.mutable_file_specific_info()->mutable_cache_state() =
- old_entry.file_specific_info().cache_state();
- } else if (updated_entry.file_specific_info().has_cache_state()) {
- updated_entry.mutable_file_specific_info()->clear_cache_state();
- }
- // Remove from the old parent and add it to the new parent with the new data.
- return PutEntryUnderDirectory(updated_entry);
-}
-
-FileError ResourceMetadata::GetSubDirectoriesRecursively(
- const std::string& id,
- std::set<base::FilePath>* sub_directories) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- std::vector<std::string> children;
- FileError error = storage_->GetChildren(id, &children);
- if (error != FILE_ERROR_OK)
- return error;
- for (size_t i = 0; i < children.size(); ++i) {
- ResourceEntry entry;
- error = storage_->GetEntry(children[i], &entry);
- if (error != FILE_ERROR_OK)
- return error;
- if (entry.file_info().is_directory()) {
- base::FilePath path;
- error = GetFilePath(children[i], &path);
- if (error != FILE_ERROR_OK)
- return error;
- sub_directories->insert(path);
- GetSubDirectoriesRecursively(children[i], sub_directories);
- }
- }
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetChildId(const std::string& parent_local_id,
- const std::string& base_name,
- std::string* out_child_id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- return storage_->GetChild(parent_local_id, base_name, out_child_id);
-}
-
-scoped_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- return storage_->GetIterator();
-}
-
-FileError ResourceMetadata::GetFilePath(const std::string& id,
- base::FilePath* out_file_path) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- ResourceEntry entry;
- FileError error = storage_->GetEntry(id, &entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- base::FilePath path;
- if (!entry.parent_local_id().empty()) {
- error = GetFilePath(entry.parent_local_id(), &path);
- if (error != FILE_ERROR_OK)
- return error;
- } else if (entry.local_id() != util::kDriveGrandRootLocalId) {
- DVLOG(1) << "Entries not under the grand root don't have paths.";
- return FILE_ERROR_NOT_FOUND;
- }
- path = path.Append(base::FilePath::FromUTF8Unsafe(entry.base_name()));
- *out_file_path = path;
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetIdByPath(const base::FilePath& file_path,
- std::string* out_id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- // Start from the root.
- std::vector<base::FilePath::StringType> components;
- file_path.GetComponents(&components);
- if (components.empty() ||
- components[0] != util::GetDriveGrandRootPath().value())
- return FILE_ERROR_NOT_FOUND;
-
- // Iterate over the remaining components.
- std::string id = util::kDriveGrandRootLocalId;
- for (size_t i = 1; i < components.size(); ++i) {
- const std::string component = base::FilePath(components[i]).AsUTF8Unsafe();
- std::string child_id;
- FileError error = storage_->GetChild(id, component, &child_id);
- if (error != FILE_ERROR_OK)
- return error;
- id = child_id;
- }
- *out_id = id;
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::GetIdByResourceId(const std::string& resource_id,
- std::string* out_local_id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- return storage_->GetIdByResourceId(resource_id, out_local_id);
-}
-
-FileError ResourceMetadata::PutEntryUnderDirectory(const ResourceEntry& entry) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(!entry.local_id().empty());
- DCHECK(!entry.parent_local_id().empty());
-
- std::string base_name;
- FileError error = GetDeduplicatedBaseName(entry, &base_name);
- if (error != FILE_ERROR_OK)
- return error;
- ResourceEntry updated_entry(entry);
- updated_entry.set_base_name(base_name);
- return storage_->PutEntry(updated_entry);
-}
-
-FileError ResourceMetadata::GetDeduplicatedBaseName(
- const ResourceEntry& entry,
- std::string* base_name) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
- DCHECK(!entry.parent_local_id().empty());
- DCHECK(!entry.title().empty());
-
- // The entry name may have been changed due to prior name de-duplication.
- // We need to first restore the file name based on the title before going
- // through name de-duplication again when it is added to another directory.
- *base_name = entry.title();
- if (entry.has_file_specific_info() &&
- entry.file_specific_info().is_hosted_document()) {
- *base_name += entry.file_specific_info().document_extension();
- }
- *base_name = util::NormalizeFileName(*base_name);
-
- // If |base_name| is not used, just return it.
- bool can_use_name = false;
- FileError error = EntryCanUseName(storage_, entry.parent_local_id(),
- entry.local_id(), *base_name,
- &can_use_name);
- if (error != FILE_ERROR_OK || can_use_name)
- return error;
-
- // Find an unused number with binary search.
- int smallest_known_unused_modifier = 1;
- while (true) {
- error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
- GetUniquifiedName(*base_name,
- smallest_known_unused_modifier),
- &can_use_name);
- if (error != FILE_ERROR_OK)
- return error;
- if (can_use_name)
- break;
-
- const int delta = base::RandInt(1, smallest_known_unused_modifier);
- if (smallest_known_unused_modifier <= INT_MAX - delta) {
- smallest_known_unused_modifier += delta;
- } else { // No luck finding an unused number. Try again.
- smallest_known_unused_modifier = 1;
- }
- }
-
- int largest_known_used_modifier = 1;
- while (smallest_known_unused_modifier - largest_known_used_modifier > 1) {
- const int modifier = largest_known_used_modifier +
- (smallest_known_unused_modifier - largest_known_used_modifier) / 2;
-
- error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
- GetUniquifiedName(*base_name, modifier),
- &can_use_name);
- if (error != FILE_ERROR_OK)
- return error;
- if (can_use_name) {
- smallest_known_unused_modifier = modifier;
- } else {
- largest_known_used_modifier = modifier;
- }
- }
- *base_name = GetUniquifiedName(*base_name, smallest_known_unused_modifier);
- return FILE_ERROR_OK;
-}
-
-FileError ResourceMetadata::RemoveEntryRecursively(const std::string& id) {
- DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
-
- ResourceEntry entry;
- FileError error = storage_->GetEntry(id, &entry);
- if (error != FILE_ERROR_OK)
- return error;
-
- if (entry.file_info().is_directory()) {
- std::vector<std::string> children;
- error = storage_->GetChildren(id, &children);
- if (error != FILE_ERROR_OK)
- return error;
- for (size_t i = 0; i < children.size(); ++i) {
- error = RemoveEntryRecursively(children[i]);
- if (error != FILE_ERROR_OK)
- return error;
- }
- }
-
- error = cache_->Remove(id);
- if (error != FILE_ERROR_OK)
- return error;
-
- return storage_->RemoveEntry(id);
-}
-
-} // namespace internal
-} // namespace drive
« no previous file with comments | « chrome/browser/chromeos/drive/resource_metadata.h ('k') | chrome/browser/chromeos/drive/resource_metadata_storage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698