OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/chromeos/file_manager/snapshot_manager.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/file_util.h" | |
9 #include "base/files/file_path.h" | |
10 #include "base/sequenced_task_runner.h" | |
11 #include "base/sys_info.h" | |
12 #include "base/task_runner_util.h" | |
13 #include "chrome/browser/chromeos/file_manager/app_id.h" | |
14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h" | |
15 #include "chrome/browser/profiles/profile.h" | |
16 #include "content/public/browser/browser_thread.h" | |
17 #include "google_apis/drive/task_util.h" | |
18 #include "third_party/cros_system_api/constants/cryptohome.h" | |
19 #include "webkit/common/blob/shareable_file_reference.h" | |
20 | |
21 namespace file_manager { | |
22 namespace { | |
23 | |
24 // Name of the directory for storing the snapshot files under the storage | |
25 // partition path. | |
26 const base::FilePath::CharType kFileManagerSnapshotDirectoryName[] = | |
27 FILE_PATH_LITERAL("FileDialogSnapshot"); | |
28 | |
29 // Cleans up the specified directory. | |
30 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
| |
31 base::DeleteFile(directory, true /* recursive */); | |
32 } | |
33 | |
34 // Returns true if there is sufficient disk space in |directory| for file | |
35 // |size|. Besides, it heuristically cleans up old files under |directory|. | |
36 bool MakeSpaceIfNecessary(const base::FilePath& directory, int64 size) { | |
37 int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(directory); | |
38 free_space -= cryptohome::kMinFreeSpaceInBytes; | |
39 | |
40 // TODO(kinaba): clean old snapshot files. | |
41 return (size <= free_space); | |
42 } | |
43 | |
44 // Part of CreateManagedSnapshot. Used for retaining |file_ref| until the | |
45 // blocking pool job finished. After returning from this function, |file_ref| is | |
46 // freed on the IO thread. | |
47 void CopyDone( | |
48 const SnapshotManager::LocalPathCallback& callback, | |
49 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref, | |
50 const base::FilePath& local_path) { | |
51 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
52 callback.Run(local_path); | |
53 } | |
54 | |
55 // Part of CreateManagedSnapshot. | |
56 // Copy |path| into |directory| with space management. | |
57 base::FilePath CopyOnBlockingPool(const base::FilePath& directory, | |
58 const base::FilePath& path) { | |
59 base::File::Info info; | |
60 base::FilePath copied; | |
61 if (!base::GetFileInfo(path, &info) || | |
62 !base::CreateDirectory(directory) || | |
63 !MakeSpaceIfNecessary(directory, info.size) || | |
64 !base::CreateTemporaryFileInDir(directory, &copied) || | |
65 !base::CopyFile(path, copied)) { | |
66 return base::FilePath(); | |
67 } | |
68 return copied; | |
69 } | |
70 | |
71 // Part of CreateManagedSnapshot. Copies the created file to a temporary | |
72 // path. The snapshot file itself may be removed once |file_ref| is deleted. | |
73 void OnCreateSnapshotFile( | |
74 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
75 const base::FilePath& base_path, | |
76 const SnapshotManager::LocalPathCallback& callback, | |
77 base::File::Error result, | |
78 const base::File::Info& file_info, | |
79 const base::FilePath& platform_path, | |
80 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | |
81 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
82 | |
83 if (result != base::File::FILE_OK) { | |
84 callback.Run(base::FilePath()); | |
85 return; | |
86 } | |
87 | |
88 base::PostTaskAndReplyWithResult( | |
89 task_runner, | |
90 FROM_HERE, | |
91 base::Bind(&CopyOnBlockingPool, base_path, platform_path), | |
92 base::Bind(&CopyDone, callback, file_ref)); | |
93 } | |
94 | |
95 // Part of CreateManagedSnapshot. Runs CreateSnapshotFile method of fileapi. | |
96 void CreateSnapshotFileOnIOThread( | |
97 scoped_refptr<fileapi::FileSystemContext> context, | |
98 scoped_refptr<base::SequencedTaskRunner> task_runner, | |
99 const base::FilePath& base_path, | |
100 const fileapi::FileSystemURL& url, | |
101 const SnapshotManager::LocalPathCallback& callback) { | |
102 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
103 | |
104 context->operation_runner()->CreateSnapshotFile( | |
105 url, base::Bind(&OnCreateSnapshotFile, task_runner, base_path, callback)); | |
106 } | |
107 | |
108 } // namespace | |
109 | |
110 SnapshotManager::SnapshotManager(Profile* profile) | |
111 : profile_(profile) { | |
112 base::SequencedWorkerPool* pool = | |
113 content::BrowserThread::GetBlockingPool(); | |
114 task_runner_ = pool->GetSequencedTaskRunner(pool->GetSequenceToken()); | |
115 } | |
116 | |
117 SnapshotManager::~SnapshotManager() { | |
118 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.
| |
119 // Clean up all snapshots in the current run. | |
120 task_runner_->PostTask( | |
121 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
| |
122 } | |
123 } | |
124 | |
125 void SnapshotManager::CreateManagedSnapshot( | |
126 const base::FilePath& absolute_file_path, | |
127 const LocalPathCallback& callback) { | |
128 fileapi::FileSystemContext* context = | |
129 util::GetFileSystemContextForExtensionId(profile_, kFileManagerAppId); | |
130 DCHECK(context); | |
131 | |
132 GURL url; | |
133 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( | |
134 profile_, absolute_file_path, kFileManagerAppId, &url)) { | |
135 callback.Run(base::FilePath()); | |
136 return; | |
137 } | |
138 | |
139 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
| |
140 base_path_ = context->partition_path().Append( | |
141 kFileManagerSnapshotDirectoryName); | |
142 } | |
143 | |
144 content::BrowserThread::PostTask( | |
145 content::BrowserThread::IO, | |
146 FROM_HERE, | |
147 base::Bind(&CreateSnapshotFileOnIOThread, | |
148 make_scoped_refptr(context), | |
149 task_runner_, | |
150 base_path_, | |
151 context->CrackURL(url), | |
152 google_apis::CreateRelayCallback(callback))); | |
153 } | |
154 | |
155 } // namespace file_manager | |
OLD | NEW |