1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/guid.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/rand_util.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/sys_info.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_cache.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using content::BrowserThread;
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace drive {
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace internal {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns true if enough disk space is available for DB operation.
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int64 kRequiredDiskSpaceInMB = 128;  // 128 MB seems to be large enough.
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::SysInfo::AmountOfFreeDiskSpace(path) >=
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kRequiredDiskSpaceInMB * (1 << 20);
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns a file name with a uniquifier appended. (e.g. "File (1).txt")
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::string GetUniquifiedName(const std::string& name, int uniquifier) {
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::FilePath name_path = base::FilePath::FromUTF8Unsafe(name);
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  name_path = name_path.InsertBeforeExtension(
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::StringPrintf(" (%d)", uniquifier));
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return name_path.AsUTF8Unsafe();
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns true when there is no entry with the specified name under the parent
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// other than the specified entry.
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError EntryCanUseName(ResourceMetadataStorage* storage,
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const std::string& parent_local_id,
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const std::string& local_id,
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const std::string& base_name,
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          bool* result) {
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string existing_entry_id;
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage->GetChild(parent_local_id, base_name,
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      &existing_entry_id);
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error == FILE_ERROR_OK)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *result = existing_entry_id == local_id;
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else if (error == FILE_ERROR_NOT_FOUND)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *result = true;
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FILE_ERROR_OK;
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Returns true when the ID is used by an immutable entry.
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool IsImmutableEntry(const std::string& id) {
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return id == util::kDriveGrandRootLocalId ||
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      id == util::kDriveOtherDirLocalId ||
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      id == util::kDriveTrashDirLocalId;
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::ResourceMetadata(
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ResourceMetadataStorage* storage,
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FileCache* cache,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : blocking_task_runner_(blocking_task_runner),
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      storage_(storage),
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      cache_(cache) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)FileError ResourceMetadata::Initialize() {
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return SetUpDefaultEntries();
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::Destroy() {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blocking_task_runner_->PostTask(
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      FROM_HERE,
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&ResourceMetadata::DestroyOnBlockingPool,
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 base::Unretained(this)));
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::Reset() {
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return FILE_ERROR_NO_LOCAL_SPACE;
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->SetLargestChangestamp(0);
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Remove all root entries.
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<Iterator> it = GetIterator();
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (; !it->IsAtEnd(); it->Advance()) {
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (it->GetValue().parent_local_id().empty()) {
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = RemoveEntryRecursively(it->GetID());
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (error != FILE_ERROR_OK)
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return error;
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (it->HasError())
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return FILE_ERROR_FAILED;
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return SetUpDefaultEntries();
115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ResourceMetadata::~ResourceMetadata() {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::SetUpDefaultEntries() {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Initialize "/drive".
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry entry;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(util::kDriveGrandRootLocalId, &entry);
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error == FILE_ERROR_NOT_FOUND) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ResourceEntry root;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root.mutable_file_info()->set_is_directory(true);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    root.set_local_id(util::kDriveGrandRootLocalId);
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    root.set_title(util::kDriveGrandRootDirName);
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    root.set_base_name(util::kDriveGrandRootDirName);
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = storage_->PutEntry(root);
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (error == FILE_ERROR_OK) {
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!entry.resource_id().empty()) {
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Old implementations used kDriveGrandRootLocalId as a resource ID.
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry.clear_resource_id();
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = storage_->PutEntry(entry);
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (error != FILE_ERROR_OK)
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return error;
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Initialize "/drive/other".
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = storage_->GetEntry(util::kDriveOtherDirLocalId, &entry);
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error == FILE_ERROR_NOT_FOUND) {
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ResourceEntry other_dir;
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    other_dir.mutable_file_info()->set_is_directory(true);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    other_dir.set_local_id(util::kDriveOtherDirLocalId);
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    other_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    other_dir.set_title(util::kDriveOtherDirName);
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = PutEntryUnderDirectory(other_dir);
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (error == FILE_ERROR_OK) {
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!entry.resource_id().empty()) {
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Old implementations used kDriveOtherDirLocalId as a resource ID.
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      entry.clear_resource_id();
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = storage_->PutEntry(entry);
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (error != FILE_ERROR_OK)
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return error;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Initialize "drive/trash".
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = storage_->GetEntry(util::kDriveTrashDirLocalId, &entry);
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error == FILE_ERROR_NOT_FOUND) {
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResourceEntry trash_dir;
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trash_dir.mutable_file_info()->set_is_directory(true);
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trash_dir.set_local_id(util::kDriveTrashDirLocalId);
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trash_dir.set_parent_local_id(util::kDriveGrandRootLocalId);
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trash_dir.set_title(util::kDriveTrashDirName);
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = PutEntryUnderDirectory(trash_dir);
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (error != FILE_ERROR_OK) {
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Initialize "drive/root".
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string child_id;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = storage_->GetChild(
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      util::kDriveGrandRootLocalId, util::kDriveMyDriveRootDirName, &child_id);
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error == FILE_ERROR_NOT_FOUND) {
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceEntry mydrive;
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mydrive.mutable_file_info()->set_is_directory(true);
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mydrive.set_parent_local_id(util::kDriveGrandRootLocalId);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mydrive.set_title(util::kDriveMyDriveRootDirName);
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string local_id;
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = AddEntry(mydrive, &local_id);
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (error != FILE_ERROR_OK) {
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FILE_ERROR_OK;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceMetadata::DestroyOnBlockingPool() {
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delete this;
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetLargestChangestamp(int64* out_value) {
212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return storage_->GetLargestChangestamp(out_value);
214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)FileError ResourceMetadata::SetLargestChangestamp(int64 value) {
217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return FILE_ERROR_NO_LOCAL_SPACE;
221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return storage_->SetLargestChangestamp(value);
223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FileError ResourceMetadata::AddEntry(const ResourceEntry& entry,
226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                     std::string* out_id) {
227b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(entry.local_id().empty());
229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return FILE_ERROR_NO_LOCAL_SPACE;
232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry parent;
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(entry.parent_local_id(), &parent);
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!parent.file_info().is_directory())
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return FILE_ERROR_NOT_A_DIRECTORY;
239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Multiple entries with the same resource ID should not be present.
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string local_id;
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ResourceEntry existing_entry;
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!entry.resource_id().empty()) {
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = storage_->GetIdByResourceId(entry.resource_id(), &local_id);
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error == FILE_ERROR_OK)
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = storage_->GetEntry(local_id, &existing_entry);
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error == FILE_ERROR_OK)
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return FILE_ERROR_EXISTS;
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    else if (error != FILE_ERROR_NOT_FOUND)
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Generate unique local ID when needed.
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We don't check for ID collisions as its probability is extremely low.
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (local_id.empty())
2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    local_id = base::GenerateGUID();
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceEntry new_entry(entry);
26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  new_entry.set_local_id(local_id);
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = PutEntryUnderDirectory(new_entry);
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  *out_id = local_id;
267b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return FILE_ERROR_OK;
268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::RemoveEntry(const std::string& id) {
271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return FILE_ERROR_NO_LOCAL_SPACE;
275b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Disallow deletion of default entries.
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (IsImmutableEntry(id))
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return FILE_ERROR_ACCESS_DENIED;
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry entry;
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(id, &entry);
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RemoveEntryRecursively(id);
286b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::GetResourceEntryById(const std::string& id,
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                 ResourceEntry* out_entry) {
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!id.empty());
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(out_entry);
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return storage_->GetEntry(id, out_entry);
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path,
298a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                                   ResourceEntry* out_entry) {
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(out_entry);
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string id;
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FileError error = GetIdByPath(path, &id);
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (error != FILE_ERROR_OK)
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return error;
3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return GetResourceEntryById(id, out_entry);
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileError ResourceMetadata::ReadDirectoryByPath(
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::FilePath& path,
312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ResourceEntryVector* out_entries) {
313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(out_entries);
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string id;
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FileError error = GetIdByPath(path, &id);
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (error != FILE_ERROR_OK)
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return error;
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ReadDirectoryById(id, out_entries);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FileError ResourceMetadata::ReadDirectoryById(
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& id,
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceEntryVector* out_entries) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(out_entries);
3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry entry;
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileError error = GetResourceEntryById(id, &entry);
3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (error != FILE_ERROR_OK)
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return error;
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!entry.file_info().is_directory())
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return FILE_ERROR_NOT_A_DIRECTORY;
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<std::string> children;
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = storage_->GetChildren(id, &children);
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntryVector entries(children.size());
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < children.size(); ++i) {
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = storage_->GetEntry(children[i], &entries[i]);
345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  out_entries->swap(entries);
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return FILE_ERROR_OK;
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry) {
353b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path()))
356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return FILE_ERROR_NO_LOCAL_SPACE;
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry old_entry;
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(entry.local_id(), &old_entry);
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (IsImmutableEntry(entry.local_id()) ||
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      old_entry.file_info().is_directory() !=  // Reject incompatible input.
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      entry.file_info().is_directory())
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return FILE_ERROR_INVALID_OPERATION;
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!entry.resource_id().empty()) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Multiple entries cannot share the same resource ID.
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string local_id;
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FileError error = GetIdByResourceId(entry.resource_id(), &local_id);
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (error) {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case FILE_ERROR_OK:
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (local_id != entry.local_id())
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          return FILE_ERROR_INVALID_OPERATION;
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case FILE_ERROR_NOT_FOUND:
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default:
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return error;
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Make sure that the new parent exists and it is a directory.
3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry new_parent;
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = storage_->GetEntry(entry.parent_local_id(), &new_parent);
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!new_parent.file_info().is_directory())
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return FILE_ERROR_NOT_A_DIRECTORY;
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do not overwrite cache states.
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Cache state should be changed via FileCache.
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ResourceEntry updated_entry(entry);
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (old_entry.file_specific_info().has_cache_state()) {
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *updated_entry.mutable_file_specific_info()->mutable_cache_state() =
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        old_entry.file_specific_info().cache_state();
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (updated_entry.file_specific_info().has_cache_state()) {
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    updated_entry.mutable_file_specific_info()->clear_cache_state();
403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Remove from the old parent and add it to the new parent with the new data.
405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return PutEntryUnderDirectory(updated_entry);
406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
407b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetSubDirectoriesRecursively(
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& id,
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::set<base::FilePath>* sub_directories) {
411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<std::string> children;
414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetChildren(id, &children);
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  for (size_t i = 0; i < children.size(); ++i) {
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ResourceEntry entry;
419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = storage_->GetEntry(children[i], &entry);
420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (entry.file_info().is_directory()) {
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::FilePath path;
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = GetFilePath(children[i], &path);
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (error != FILE_ERROR_OK)
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return error;
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      sub_directories->insert(path);
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetSubDirectoriesRecursively(children[i], sub_directories);
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FILE_ERROR_OK;
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetChildId(const std::string& parent_local_id,
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       const std::string& base_name,
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       std::string* out_child_id) {
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return storage_->GetChild(parent_local_id, base_name, out_child_id);
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
441a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() {
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
443b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
444a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return storage_->GetIterator();
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetFilePath(const std::string& id,
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        base::FilePath* out_file_path) {
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry entry;
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(id, &entry);
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::FilePath path;
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!entry.parent_local_id().empty()) {
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = GetFilePath(entry.parent_local_id(), &path);
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else if (entry.local_id() != util::kDriveGrandRootLocalId) {
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DVLOG(1) << "Entries not under the grand root don't have paths.";
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return FILE_ERROR_NOT_FOUND;
464b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  path = path.Append(base::FilePath::FromUTF8Unsafe(entry.base_name()));
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *out_file_path = path;
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FILE_ERROR_OK;
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError ResourceMetadata::GetIdByPath(const base::FilePath& file_path,
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        std::string* out_id) {
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start from the root.
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<base::FilePath::StringType> components;
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_path.GetComponents(&components);
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (components.empty() || components[0] != util::kDriveGrandRootDirName)
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return FILE_ERROR_NOT_FOUND;
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Iterate over the remaining components.
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string id = util::kDriveGrandRootLocalId;
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 1; i < components.size(); ++i) {
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string component = base::FilePath(components[i]).AsUTF8Unsafe();
484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string child_id;
485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FileError error = storage_->GetChild(id, component, &child_id);
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    id = child_id;
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  *out_id = id;
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return FILE_ERROR_OK;
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)FileError ResourceMetadata::GetIdByResourceId(const std::string& resource_id,
495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                              std::string* out_local_id) {
496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return storage_->GetIdByResourceId(resource_id, out_local_id);
498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::PutEntryUnderDirectory(const ResourceEntry& entry) {
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!entry.local_id().empty());
50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!entry.parent_local_id().empty());
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string base_name;
506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = GetDeduplicatedBaseName(entry, &base_name);
507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ResourceEntry updated_entry(entry);
510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  updated_entry.set_base_name(base_name);
5115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return storage_->PutEntry(updated_entry);
5125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::GetDeduplicatedBaseName(
515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ResourceEntry& entry,
516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string* base_name) {
5175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
5185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(!entry.parent_local_id().empty());
5195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(!entry.title().empty());
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The entry name may have been changed due to prior name de-duplication.
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We need to first restore the file name based on the title before going
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // through name de-duplication again when it is added to another directory.
524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *base_name = entry.title();
5255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (entry.has_file_specific_info() &&
5265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      entry.file_specific_info().is_hosted_document()) {
527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    *base_name += entry.file_specific_info().document_extension();
5285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *base_name = util::NormalizeFileName(*base_name);
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
5315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If |base_name| is not used, just return it.
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool can_use_name = false;
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = EntryCanUseName(storage_, entry.parent_local_id(),
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    entry.local_id(), *base_name,
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    &can_use_name);
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK || can_use_name)
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Find an unused number with binary search.
5405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int smallest_known_unused_modifier = 1;
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (true) {
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            GetUniquifiedName(*base_name,
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                              smallest_known_unused_modifier),
545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            &can_use_name);
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (can_use_name)
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const int delta = base::RandInt(1, smallest_known_unused_modifier);
5525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (smallest_known_unused_modifier <= INT_MAX - delta) {
5535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      smallest_known_unused_modifier += delta;
5545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    } else {  // No luck finding an unused number. Try again.
5555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      smallest_known_unused_modifier = 1;
5565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int largest_known_used_modifier = 1;
5605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  while (smallest_known_unused_modifier - largest_known_used_modifier > 1) {
5615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const int modifier = largest_known_used_modifier +
5625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        (smallest_known_unused_modifier - largest_known_used_modifier) / 2;
5635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(),
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            GetUniquifiedName(*base_name, modifier),
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            &can_use_name);
567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (can_use_name) {
5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      smallest_known_unused_modifier = modifier;
5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    } else {
5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      largest_known_used_modifier = modifier;
5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *base_name = GetUniquifiedName(*base_name, smallest_known_unused_modifier);
576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return FILE_ERROR_OK;
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FileError ResourceMetadata::RemoveEntryRecursively(const std::string& id) {
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(blocking_task_runner_->RunsTasksOnCurrentThread());
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceEntry entry;
583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FileError error = storage_->GetEntry(id, &entry);
584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (entry.file_info().is_directory()) {
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::vector<std::string> children;
589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    error = storage_->GetChildren(id, &children);
590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (error != FILE_ERROR_OK)
591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return error;
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (size_t i = 0; i < children.size(); ++i) {
593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      error = RemoveEntryRecursively(children[i]);
594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (error != FILE_ERROR_OK)
595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return error;
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  error = cache_->Remove(id);
600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error != FILE_ERROR_OK)
601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return error;
602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return storage_->RemoveEntry(id);
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace internal
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace drive
608