OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" | 5 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root.h" |
6 | 6 |
7 #include "base/files/file.h" | |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/ptr_util.h" | |
10 #include "base/strings/string_util.h" | |
11 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_document.h" | |
12 #include "chrome/browser/chromeos/arc/fileapi/arc_documents_provider_util.h" | |
13 #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_instance_util.h" | |
8 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
15 #include "url/gurl.h" | |
9 | 16 |
10 using content::BrowserThread; | 17 using content::BrowserThread; |
18 using EntryList = storage::AsyncFileUtil::EntryList; | |
11 | 19 |
12 namespace arc { | 20 namespace arc { |
13 | 21 |
22 namespace { | |
23 | |
24 base::FilePath StripBaseName(const base::FilePath& path) { | |
25 base::FilePath dirname = path.DirName(); | |
26 // base::FilePath::DirName() returns kCurrentDirectory if the path does not | |
27 // contain separators. In this case we want an empty path. | |
28 if (dirname.value() == base::FilePath::kCurrentDirectory) { | |
29 return base::FilePath(); | |
30 } | |
31 return dirname; | |
32 } | |
33 | |
34 } // namespace | |
35 | |
14 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot( | 36 ArcDocumentsProviderRoot::ArcDocumentsProviderRoot( |
15 const std::string& authority, | 37 const std::string& authority, |
16 const std::string& root_document_id) {} | 38 const std::string& root_document_id) |
39 : authority_(authority), | |
40 root_directory_( | |
41 base::MakeUnique<ArcDocumentsProviderDocument>(root_document_id, | |
42 true)), | |
43 weak_ptr_factory_(this) {} | |
17 | 44 |
18 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() { | 45 ArcDocumentsProviderRoot::~ArcDocumentsProviderRoot() { |
19 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 46 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
20 } | 47 } |
21 | 48 |
22 void ArcDocumentsProviderRoot::GetFileInfo( | 49 void ArcDocumentsProviderRoot::GetFileInfo( |
23 const base::FilePath& path, | 50 const base::FilePath& path, |
24 const GetFileInfoCallback& callback) { | 51 const GetFileInfoCallback& callback) { |
25 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 52 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
26 NOTIMPLEMENTED(); // TODO(crbug.com/671511): Implement this function. | 53 // Skip a cache update if possible. |
54 ArcDocumentsProviderDocument* entry = root_directory_->Lookup(path); | |
55 if (entry) { | |
56 GetFileInfoAfterCacheUpdate(path, callback); | |
57 return; | |
58 } | |
59 DCHECK(!path.empty()); | |
60 UpdateDirectoryCacheUpTo( | |
61 StripBaseName(path), | |
62 base::Bind(&ArcDocumentsProviderRoot::GetFileInfoAfterCacheUpdate, | |
Luis Héctor Chávez
2016/12/15 23:54:26
nit: #include "base/bind.h"
Shuhei Takahashi
2016/12/16 05:47:14
Done.
| |
63 weak_ptr_factory_.GetWeakPtr(), path, callback)); | |
27 } | 64 } |
28 | 65 |
29 void ArcDocumentsProviderRoot::ReadDirectory( | 66 void ArcDocumentsProviderRoot::ReadDirectory( |
30 const base::FilePath& path, | 67 const base::FilePath& path, |
31 const ReadDirectoryCallback& callback) { | 68 const ReadDirectoryCallback& callback) { |
32 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 69 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
33 NOTIMPLEMENTED(); // TODO(crbug.com/671511): Implement this function. | 70 if (path.empty()) { |
71 ReadDirectoryAfterCacheUpdate(path, callback); | |
72 return; | |
73 } | |
74 UpdateDirectoryCacheUpTo( | |
75 StripBaseName(path), | |
76 base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryAfterCacheUpdate, | |
77 weak_ptr_factory_.GetWeakPtr(), path, callback)); | |
78 } | |
79 | |
80 void ArcDocumentsProviderRoot::GetFileInfoAfterCacheUpdate( | |
81 const base::FilePath& path, | |
82 const GetFileInfoCallback& callback) { | |
83 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
84 ArcDocumentsProviderDocument* entry = root_directory_->Lookup(path); | |
85 if (!entry) { | |
86 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); | |
87 return; | |
88 } | |
89 file_system_instance_util::GetDocumentOnIOThread( | |
90 authority_, entry->document_id(), | |
91 base::Bind(&ArcDocumentsProviderRoot::GetFileInfoWithDocument, | |
92 weak_ptr_factory_.GetWeakPtr(), callback)); | |
93 } | |
94 | |
95 void ArcDocumentsProviderRoot::GetFileInfoWithDocument( | |
96 const GetFileInfoCallback& callback, | |
97 mojom::DocumentPtr document) { | |
98 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
99 if (document.is_null()) { | |
100 callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info()); | |
101 return; | |
102 } | |
103 | |
104 base::File::Info info; | |
105 info.size = document->size; | |
106 info.is_directory = document->mime_type == kAndroidDirectoryMimeType; | |
107 info.is_symbolic_link = false; | |
108 info.last_modified = info.last_accessed = info.creation_time = | |
109 base::Time::FromDoubleT(document->last_modified / 1000.0); | |
Luis Héctor Chávez
2016/12/15 23:54:26
nit: base::Time::FromJavaTime(document->last_modif
Shuhei Takahashi
2016/12/16 05:47:14
Thanks, that should be better.
| |
110 callback.Run(base::File::FILE_OK, info); | |
111 } | |
112 | |
113 void ArcDocumentsProviderRoot::ReadDirectoryAfterCacheUpdate( | |
114 const base::FilePath& path, | |
115 const ReadDirectoryCallback& callback) { | |
116 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
117 ArcDocumentsProviderDocument* parent_directory = | |
118 root_directory_->Lookup(path); | |
119 if (!parent_directory || !parent_directory->is_directory()) { | |
120 callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), | |
121 false /* has_more */); | |
122 return; | |
123 } | |
124 file_system_instance_util::GetChildDocumentsOnIOThread( | |
125 authority_, parent_directory->document_id(), | |
126 base::Bind(&ArcDocumentsProviderRoot::ReadDirectoryWithChildDocuments, | |
127 weak_ptr_factory_.GetWeakPtr(), path, callback)); | |
128 } | |
129 | |
130 void ArcDocumentsProviderRoot::ReadDirectoryWithChildDocuments( | |
131 const base::FilePath& path, | |
132 const ReadDirectoryCallback& callback, | |
133 base::Optional<std::vector<mojom::DocumentPtr>> children) { | |
134 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
135 if (!children) { | |
136 callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), | |
137 false /* has_more */); | |
138 return; | |
139 } | |
140 | |
141 ArcDocumentsProviderDocument* parent_directory = | |
142 root_directory_->Lookup(path); | |
143 if (!parent_directory || !parent_directory->is_directory()) { | |
144 callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), | |
145 false /* has_more */); | |
146 return; | |
147 } | |
148 parent_directory->UpdateWithChildDocuments(children.value()); | |
149 | |
150 std::vector<storage::DirectoryEntry> entry_list; | |
151 for (const auto& pair : parent_directory->children()) { | |
152 entry_list.emplace_back(pair.first, pair.second->is_directory() | |
153 ? storage::DirectoryEntry::DIRECTORY | |
154 : storage::DirectoryEntry::FILE); | |
155 } | |
156 callback.Run(base::File::FILE_OK, entry_list, false /* has_more */); | |
157 } | |
158 | |
159 void ArcDocumentsProviderRoot::UpdateDirectoryCacheUpTo( | |
160 const base::FilePath& path, | |
161 const base::Closure& callback) { | |
162 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
163 UpdateDirectoryCacheIter(base::FilePath(), path, callback); | |
164 } | |
165 | |
166 void ArcDocumentsProviderRoot::UpdateDirectoryCacheIter( | |
167 const base::FilePath& parent_directory_path, | |
168 const base::FilePath& remaining_path, | |
169 const base::Closure& callback) { | |
170 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
171 | |
172 ArcDocumentsProviderDocument* parent_directory = | |
173 root_directory_->Lookup(parent_directory_path); | |
174 if (!parent_directory || !parent_directory->is_directory()) { | |
175 callback.Run(); | |
176 return; | |
177 } | |
178 | |
179 file_system_instance_util::GetChildDocumentsOnIOThread( | |
180 authority_, parent_directory->document_id(), | |
181 base::Bind( | |
182 &ArcDocumentsProviderRoot::UpdateDirectoryCacheIterWithChildDocuments, | |
183 weak_ptr_factory_.GetWeakPtr(), parent_directory_path, remaining_path, | |
184 callback)); | |
185 } | |
186 | |
187 void ArcDocumentsProviderRoot::UpdateDirectoryCacheIterWithChildDocuments( | |
188 const base::FilePath& parent_directory_path, | |
189 const base::FilePath& remaining_path, | |
190 const base::Closure& callback, | |
191 base::Optional<std::vector<mojom::DocumentPtr>> children) { | |
192 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
193 if (!children) { | |
194 callback.Run(); | |
195 return; | |
196 } | |
197 | |
198 ArcDocumentsProviderDocument* parent_directory = | |
199 root_directory_->Lookup(parent_directory_path); | |
200 if (!parent_directory || !parent_directory->is_directory()) { | |
201 callback.Run(); | |
202 return; | |
203 } | |
204 parent_directory->UpdateWithChildDocuments(children.value()); | |
205 | |
206 if (remaining_path.empty()) { | |
207 callback.Run(); | |
208 return; | |
209 } | |
210 | |
211 using Components = std::vector<base::FilePath::StringType>; | |
212 Components components; | |
213 remaining_path.GetComponents(&components); | |
214 DCHECK(!components.empty()); | |
215 | |
216 base::FilePath next_parent_directory_path = | |
217 parent_directory_path.Append(components[0]); | |
218 base::FilePath next_remaining_path = | |
219 base::FilePath::FromUTF8Unsafe(base::JoinString( | |
220 Components(components.begin() + 1, components.end()), "/")); | |
221 | |
222 UpdateDirectoryCacheIter(next_parent_directory_path, next_remaining_path, | |
223 callback); | |
34 } | 224 } |
35 | 225 |
36 } // namespace arc | 226 } // namespace arc |
OLD | NEW |