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

Unified Diff: chrome/browser/chromeos/file_manager/snapshot_manager.cc

Issue 339323002: Implement snapshotting for non-Drive non-local file systems. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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/file_manager/snapshot_manager.cc
diff --git a/chrome/browser/chromeos/file_manager/snapshot_manager.cc b/chrome/browser/chromeos/file_manager/snapshot_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..452eaec1c82d12241cb674a7888bf4fbe350f11a
--- /dev/null
+++ b/chrome/browser/chromeos/file_manager/snapshot_manager.cc
@@ -0,0 +1,155 @@
+// Copyright 2014 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/file_manager/snapshot_manager.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/sequenced_task_runner.h"
+#include "base/sys_info.h"
+#include "base/task_runner_util.h"
+#include "chrome/browser/chromeos/file_manager/app_id.h"
+#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/public/browser/browser_thread.h"
+#include "google_apis/drive/task_util.h"
+#include "third_party/cros_system_api/constants/cryptohome.h"
+#include "webkit/common/blob/shareable_file_reference.h"
+
+namespace file_manager {
+namespace {
+
+// Name of the directory for storing the snapshot files under the storage
+// partition path.
+const base::FilePath::CharType kFileManagerSnapshotDirectoryName[] =
+ FILE_PATH_LITERAL("FileDialogSnapshot");
+
+// Cleans up the specified directory.
+void DeleteDirectory(const base::FilePath& directory) {
hashimoto 2014/06/19 02:26:01 nit: What is the point of having this function ins
kinaba 2014/06/19 04:41:56 Good catch. Removed. (Actually I hadn't been able
+ base::DeleteFile(directory, true /* recursive */);
+}
+
+// Returns true if there is sufficient disk space in |directory| for file
+// |size|. Besides, it heuristically cleans up old files under |directory|.
+bool MakeSpaceIfNecessary(const base::FilePath& directory, int64 size) {
+ int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(directory);
+ free_space -= cryptohome::kMinFreeSpaceInBytes;
+
+ // TODO(kinaba): clean old snapshot files.
+ return (size <= free_space);
+}
+
+// Part of CreateManagedSnapshot. Used for retaining |file_ref| until the
+// blocking pool job finished. After returning from this function, |file_ref| is
+// freed on the IO thread.
+void CopyDone(
+ const SnapshotManager::LocalPathCallback& callback,
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
+ const base::FilePath& local_path) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ callback.Run(local_path);
+}
+
+// Part of CreateManagedSnapshot.
+// Copy |path| into |directory| with space management.
+base::FilePath CopyOnBlockingPool(const base::FilePath& directory,
+ const base::FilePath& path) {
+ base::File::Info info;
+ base::FilePath copied;
+ if (!base::GetFileInfo(path, &info) ||
+ !base::CreateDirectory(directory) ||
+ !MakeSpaceIfNecessary(directory, info.size) ||
+ !base::CreateTemporaryFileInDir(directory, &copied) ||
+ !base::CopyFile(path, copied)) {
+ return base::FilePath();
+ }
+ return copied;
+}
+
+// Part of CreateManagedSnapshot. Copies the created file to a temporary
+// path. The snapshot file itself may be removed once |file_ref| is deleted.
+void OnCreateSnapshotFile(
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ const base::FilePath& base_path,
+ const SnapshotManager::LocalPathCallback& callback,
+ base::File::Error result,
+ const base::File::Info& file_info,
+ const base::FilePath& platform_path,
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ if (result != base::File::FILE_OK) {
+ callback.Run(base::FilePath());
+ return;
+ }
+
+ base::PostTaskAndReplyWithResult(
+ task_runner,
+ FROM_HERE,
+ base::Bind(&CopyOnBlockingPool, base_path, platform_path),
+ base::Bind(&CopyDone, callback, file_ref));
+}
+
+// Part of CreateManagedSnapshot. Runs CreateSnapshotFile method of fileapi.
+void CreateSnapshotFileOnIOThread(
+ scoped_refptr<fileapi::FileSystemContext> context,
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ const base::FilePath& base_path,
+ const fileapi::FileSystemURL& url,
+ const SnapshotManager::LocalPathCallback& callback) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+
+ context->operation_runner()->CreateSnapshotFile(
+ url, base::Bind(&OnCreateSnapshotFile, task_runner, base_path, callback));
+}
+
+} // namespace
+
+SnapshotManager::SnapshotManager(Profile* profile)
+ : profile_(profile) {
+ base::SequencedWorkerPool* pool =
+ content::BrowserThread::GetBlockingPool();
+ task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken());
+}
+
+SnapshotManager::~SnapshotManager() {
+ if (task_runner_ && !base_path_.empty()) {
hashimoto 2014/06/19 02:26:01 nit: In which case task_runner_ becomes NULL?
kinaba 2014/06/19 04:41:56 Never.
+ // Clean up all snapshots in the current run.
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&DeleteDirectory, base_path_));
hashimoto 2014/06/19 02:26:01 I don't remember in which order objects are destru
kinaba 2014/06/19 04:41:56 It is still alive at this point (profile destructi
+ }
+}
+
+void SnapshotManager::CreateManagedSnapshot(
+ const base::FilePath& absolute_file_path,
+ const LocalPathCallback& callback) {
+ fileapi::FileSystemContext* context =
+ util::GetFileSystemContextForExtensionId(profile_, kFileManagerAppId);
+ DCHECK(context);
+
+ GURL url;
+ if (!util::ConvertAbsoluteFilePathToFileSystemUrl(
+ profile_, absolute_file_path, kFileManagerAppId, &url)) {
+ callback.Run(base::FilePath());
+ return;
+ }
+
+ if (base_path_.empty()) {
hashimoto 2014/06/19 02:26:01 nit: Why can't this be initialized in the ctor?
kinaba 2014/06/19 04:41:56 StorageParition/FileSystemContext related part is
+ base_path_ = context->partition_path().Append(
+ kFileManagerSnapshotDirectoryName);
+ }
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&CreateSnapshotFileOnIOThread,
+ make_scoped_refptr(context),
+ task_runner_,
+ base_path_,
+ context->CrackURL(url),
+ google_apis::CreateRelayCallback(callback)));
+}
+
+} // namespace file_manager

Powered by Google App Engine
This is Rietveld 408576698