• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "chrome/browser/chromeos/file_manager/app_id.h"
9 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "google_apis/drive/task_util.h"
12 #include "webkit/browser/fileapi/file_system_context.h"
13 #include "webkit/common/blob/shareable_file_reference.h"
14 
15 namespace file_manager {
16 namespace {
17 
18 // Part of CreateManagedSnapshot. Runs CreateSnapshotFile method of fileapi.
CreateSnapshotFileOnIOThread(scoped_refptr<fileapi::FileSystemContext> context,const fileapi::FileSystemURL & url,const fileapi::FileSystemOperation::SnapshotFileCallback & callback)19 void CreateSnapshotFileOnIOThread(
20     scoped_refptr<fileapi::FileSystemContext> context,
21     const fileapi::FileSystemURL& url,
22     const fileapi::FileSystemOperation::SnapshotFileCallback& callback) {
23   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
24   context->operation_runner()->CreateSnapshotFile(url, callback);
25 }
26 
27 // Utility for destructing the bound |file_refs| on IO thread. This is meant
28 // to be used together with base::Bind. After this function finishes, the
29 // Bind callback should destruct the bound argument.
FreeReferenceOnIOThread(const std::vector<scoped_refptr<webkit_blob::ShareableFileReference>> & file_refs)30 void FreeReferenceOnIOThread(const std::vector<
31     scoped_refptr<webkit_blob::ShareableFileReference> >& file_refs) {
32   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
33 }
34 
35 }  // namespace
36 
SnapshotManager(Profile * profile)37 SnapshotManager::SnapshotManager(Profile* profile)
38     : profile_(profile), weak_ptr_factory_(this) {
39 }
40 
~SnapshotManager()41 SnapshotManager::~SnapshotManager() {
42   if (!file_refs_.empty()) {
43     bool posted = content::BrowserThread::PostTask(
44         content::BrowserThread::IO,
45         FROM_HERE,
46         base::Bind(&FreeReferenceOnIOThread, file_refs_));
47     DCHECK(posted);
48   }
49 }
50 
CreateManagedSnapshot(const base::FilePath & absolute_file_path,const LocalPathCallback & callback)51 void SnapshotManager::CreateManagedSnapshot(
52     const base::FilePath& absolute_file_path,
53     const LocalPathCallback& callback) {
54   fileapi::FileSystemContext* context =
55       util::GetFileSystemContextForExtensionId(profile_, kFileManagerAppId);
56   DCHECK(context);
57 
58   GURL url;
59   if (!util::ConvertAbsoluteFilePathToFileSystemUrl(
60           profile_, absolute_file_path, kFileManagerAppId, &url)) {
61     callback.Run(base::FilePath());
62     return;
63   }
64 
65   // TODO(kinaba): crbug.com/386519 evict old |file_refs_| before creating a new
66   // one if necessary.
67   content::BrowserThread::PostTask(
68       content::BrowserThread::IO,
69       FROM_HERE,
70       base::Bind(&CreateSnapshotFileOnIOThread,
71                  make_scoped_refptr(context),
72                  context->CrackURL(url),
73                  google_apis::CreateRelayCallback(
74                      base::Bind(&SnapshotManager::OnCreateSnapshotFile,
75                                 weak_ptr_factory_.GetWeakPtr(),
76                                 callback))));
77 }
78 
OnCreateSnapshotFile(const 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)79 void SnapshotManager::OnCreateSnapshotFile(
80     const LocalPathCallback& callback,
81     base::File::Error result,
82     const base::File::Info& file_info,
83     const base::FilePath& platform_path,
84     const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
85   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
86 
87   if (result != base::File::FILE_OK) {
88     callback.Run(base::FilePath());
89     return;
90   }
91 
92   file_refs_.push_back(file_ref);
93   callback.Run(platform_path);
94 }
95 
96 }  // namespace file_manager
97