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

Side by Side Diff: webkit/chromeos/fileapi/cros_mount_point_provider.cc

Issue 10823273: Integrate external mount points to IsolatedContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove too strict DCHECK Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/chromeos/fileapi/cros_mount_point_provider.h" 5 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h"
6 6
7 #include "base/chromeos/chromeos_version.h" 7 #include "base/chromeos/chromeos_version.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h " 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h "
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFileSyste m.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFileSyste m.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
19 #include "webkit/chromeos/fileapi/file_access_permissions.h" 19 #include "webkit/chromeos/fileapi/file_access_permissions.h"
20 #include "webkit/chromeos/fileapi/remote_file_stream_writer.h" 20 #include "webkit/chromeos/fileapi/remote_file_stream_writer.h"
21 #include "webkit/chromeos/fileapi/remote_file_system_operation.h" 21 #include "webkit/chromeos/fileapi/remote_file_system_operation.h"
22 #include "webkit/fileapi/file_system_file_stream_reader.h" 22 #include "webkit/fileapi/file_system_file_stream_reader.h"
23 #include "webkit/fileapi/file_system_operation_context.h" 23 #include "webkit/fileapi/file_system_operation_context.h"
24 #include "webkit/fileapi/file_system_url.h" 24 #include "webkit/fileapi/file_system_url.h"
25 #include "webkit/fileapi/file_system_util.h" 25 #include "webkit/fileapi/file_system_util.h"
26 #include "webkit/fileapi/isolated_context.h"
27 #include "webkit/fileapi/isolated_file_util.h"
26 #include "webkit/fileapi/local_file_stream_writer.h" 28 #include "webkit/fileapi/local_file_stream_writer.h"
27 #include "webkit/fileapi/local_file_system_operation.h" 29 #include "webkit/fileapi/local_file_system_operation.h"
28 #include "webkit/glue/webkit_glue.h" 30 #include "webkit/glue/webkit_glue.h"
29 31
30 namespace { 32 namespace {
31 33
32 const char kChromeUIScheme[] = "chrome"; 34 const char kChromeUIScheme[] = "chrome";
33 35
34 } // namespace 36 } // namespace
35 37
36 namespace chromeos { 38 namespace chromeos {
37 39
38 CrosMountPointProvider::MountPoint::MountPoint( 40 // static
39 const FilePath& in_web_root_path, 41 bool CrosMountPointProvider::CanHandleURL(const fileapi::FileSystemURL& url) {
40 const FilePath& in_local_root_path, 42 if (!url.is_valid())
41 FileSystemLocation in_location, 43 return false;
42 fileapi::RemoteFileSystemProxyInterface* in_proxy) 44 return url.type() == fileapi::kFileSystemTypeNativeLocal ||
43 : web_root_path(in_web_root_path), local_root_path(in_local_root_path), 45 url.type() == fileapi::kFileSystemTypeDrive;
44 location(in_location), remote_proxy(in_proxy) {
45 }
46
47 CrosMountPointProvider::MountPoint::~MountPoint() {
48 } 46 }
49 47
50 CrosMountPointProvider::CrosMountPointProvider( 48 CrosMountPointProvider::CrosMountPointProvider(
51 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy) 49 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy)
52 : special_storage_policy_(special_storage_policy), 50 : special_storage_policy_(special_storage_policy),
53 file_access_permissions_(new FileAccessPermissions()), 51 file_access_permissions_(new FileAccessPermissions()),
54 local_file_util_(new fileapi::LocalFileUtil()) { 52 local_file_util_(new fileapi::IsolatedFileUtil()) {
55 FilePath home_path; 53 FilePath home_path;
56 if (PathService::Get(base::DIR_HOME, &home_path)) 54 if (PathService::Get(base::DIR_HOME, &home_path))
57 AddLocalMountPoint(home_path.AppendASCII("Downloads")); 55 AddLocalMountPoint(home_path.AppendASCII("Downloads"));
58 AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/archive"))); 56 AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/archive")));
59 AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/removable"))); 57 AddLocalMountPoint(FilePath(FILE_PATH_LITERAL("/media/removable")));
60 } 58 }
61 59
62 CrosMountPointProvider::~CrosMountPointProvider() { 60 CrosMountPointProvider::~CrosMountPointProvider() {
63 } 61 }
64 62
65 bool CrosMountPointProvider::GetRootForVirtualPath(
66 const FilePath& virtual_path, FilePath* root_path) {
67 const MountPoint* mount_point = GetMountPoint(virtual_path);
68 if (!mount_point)
69 return false;
70
71 DCHECK(root_path);
72 *root_path = mount_point->local_root_path;
73 return true;
74 }
75
76 void CrosMountPointProvider::ValidateFileSystemRoot( 63 void CrosMountPointProvider::ValidateFileSystemRoot(
77 const GURL& origin_url, 64 const GURL& origin_url,
78 fileapi::FileSystemType type, 65 fileapi::FileSystemType type,
79 bool create, 66 bool create,
80 const ValidateFileSystemCallback& callback) { 67 const ValidateFileSystemCallback& callback) {
81 // Nothing to validate for external filesystem. 68 // Nothing to validate for external filesystem.
82 DCHECK(type == fileapi::kFileSystemTypeExternal); 69 DCHECK(type == fileapi::kFileSystemTypeExternal);
83 callback.Run(base::PLATFORM_FILE_OK); 70 callback.Run(base::PLATFORM_FILE_OK);
84 } 71 }
85 72
86 FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread( 73 FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
87 const GURL& origin_url, 74 const GURL& origin_url,
88 fileapi::FileSystemType type, 75 fileapi::FileSystemType type,
89 const FilePath& virtual_path, 76 const FilePath& virtual_path,
90 bool create) { 77 bool create) {
91 DCHECK(type == fileapi::kFileSystemTypeExternal); 78 DCHECK(type == fileapi::kFileSystemTypeExternal);
92 FilePath root_path; 79 fileapi::FileSystemURL url(origin_url, type, virtual_path);
93 if (!GetRootForVirtualPath(virtual_path, &root_path)) 80 if (!url.is_valid())
94 return FilePath(); 81 return FilePath();
95 82
96 return root_path; 83 FilePath root_path;
84 if (!isolated_context()->GetRegisteredPath(url.filesystem_id(), &root_path))
85 return FilePath();
86
87 return root_path.DirName();
97 } 88 }
98 89
99 bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url, 90 bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
100 fileapi::FileSystemType type, 91 fileapi::FileSystemType type,
101 const FilePath& virtual_path) { 92 const FilePath& virtual_path) {
102 if (type != fileapi::kFileSystemTypeExternal) 93 // TODO(kinuko): this should call CanHandleURL() once
94 // http://crbug.com/142267 is fixed.
95 if (type != fileapi::kFileSystemTypeNativeLocal &&
96 type != fileapi::kFileSystemTypeDrive)
103 return false; 97 return false;
104 98
105 // Permit access to mount points from internal WebUI. 99 // Permit access to mount points from internal WebUI.
106 if (origin_url.SchemeIs(kChromeUIScheme)) 100 if (origin_url.SchemeIs(kChromeUIScheme))
107 return true; 101 return true;
108 102
109 std::string extension_id = origin_url.host(); 103 std::string extension_id = origin_url.host();
110 // Check first to make sure this extension has fileBrowserHander permissions. 104 // Check first to make sure this extension has fileBrowserHander permissions.
111 if (!special_storage_policy_->IsFileHandler(extension_id)) 105 if (!special_storage_policy_->IsFileHandler(extension_id))
112 return false; 106 return false;
(...skipping 15 matching lines...) Expand all
128 void CrosMountPointProvider::DeleteFileSystem( 122 void CrosMountPointProvider::DeleteFileSystem(
129 const GURL& origin_url, 123 const GURL& origin_url,
130 fileapi::FileSystemType type, 124 fileapi::FileSystemType type,
131 fileapi::FileSystemContext* context, 125 fileapi::FileSystemContext* context,
132 const DeleteFileSystemCallback& callback) { 126 const DeleteFileSystemCallback& callback) {
133 NOTREACHED(); 127 NOTREACHED();
134 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); 128 callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
135 } 129 }
136 130
137 bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) { 131 bool CrosMountPointProvider::HasMountPoint(const FilePath& mount_point) {
138 base::AutoLock locker(mount_point_map_lock_); 132 std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
139 MountPointMap::const_iterator iter = mount_point_map_.find( 133 FilePath path;
140 mount_point.BaseName().value()); 134 const bool valid = isolated_context()->GetRegisteredPath(mount_name, &path);
141 DCHECK(iter == mount_point_map_.end() || 135 return valid && path == mount_point;
142 iter->second.local_root_path == mount_point.DirName());
143 return iter != mount_point_map_.end();
144 } 136 }
145 137
146 void CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) { 138 void CrosMountPointProvider::AddLocalMountPoint(const FilePath& mount_point) {
139 std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
140 isolated_context()->RevokeFileSystem(mount_name);
141 isolated_context()->RegisterExternalFileSystem(
142 mount_name,
143 fileapi::kFileSystemTypeNativeLocal,
144 mount_point);
147 base::AutoLock locker(mount_point_map_lock_); 145 base::AutoLock locker(mount_point_map_lock_);
148 mount_point_map_.erase(mount_point.BaseName().value()); 146 local_to_virtual_map_[mount_point] = mount_point.BaseName();
149 mount_point_map_.insert(std::make_pair(
150 mount_point.BaseName().value(),
151 MountPoint(mount_point.BaseName(),
152 mount_point.DirName(),
153 LOCAL,
154 NULL)));
155 } 147 }
156 148
157 void CrosMountPointProvider::AddRemoteMountPoint( 149 void CrosMountPointProvider::AddRemoteMountPoint(
158 const FilePath& mount_point, 150 const FilePath& mount_point,
159 fileapi::RemoteFileSystemProxyInterface* remote_proxy) { 151 fileapi::RemoteFileSystemProxyInterface* remote_proxy) {
160 DCHECK(remote_proxy); 152 DCHECK(remote_proxy);
153 std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
154 isolated_context()->RevokeFileSystem(mount_name);
155 isolated_context()->RegisterExternalFileSystem(mount_name,
156 fileapi::kFileSystemTypeDrive,
157 mount_point);
161 base::AutoLock locker(mount_point_map_lock_); 158 base::AutoLock locker(mount_point_map_lock_);
162 mount_point_map_.erase(mount_point.BaseName().value()); 159 remote_proxy_map_[mount_name] = remote_proxy;
163 mount_point_map_.insert(std::make_pair( 160 local_to_virtual_map_[mount_point] = mount_point.BaseName();
164 mount_point.BaseName().value(),
165 MountPoint(mount_point.BaseName(),
166 mount_point.DirName(),
167 REMOTE,
168 remote_proxy)));
169 } 161 }
170 162
171 void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) { 163 void CrosMountPointProvider::RemoveMountPoint(const FilePath& mount_point) {
164 std::string mount_name = mount_point.BaseName().AsUTF8Unsafe();
165 isolated_context()->RevokeFileSystem(mount_name);
172 base::AutoLock locker(mount_point_map_lock_); 166 base::AutoLock locker(mount_point_map_lock_);
173 mount_point_map_.erase(mount_point.BaseName().value()); 167 remote_proxy_map_.erase(mount_name);
168 local_to_virtual_map_.erase(mount_point);
174 } 169 }
175 170
176 void CrosMountPointProvider::GrantFullAccessToExtension( 171 void CrosMountPointProvider::GrantFullAccessToExtension(
177 const std::string& extension_id) { 172 const std::string& extension_id) {
178 DCHECK(special_storage_policy_->IsFileHandler(extension_id)); 173 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
179 if (!special_storage_policy_->IsFileHandler(extension_id)) 174 if (!special_storage_policy_->IsFileHandler(extension_id))
180 return; 175 return;
181 for (MountPointMap::const_iterator iter = mount_point_map_.begin(); 176 std::vector<fileapi::IsolatedContext::FileInfo> files =
182 iter != mount_point_map_.end(); 177 isolated_context()->GetExternalMountPoints();
183 ++iter) { 178 for (size_t i = 0; i < files.size(); ++i) {
184 GrantFileAccessToExtension(extension_id, FilePath(iter->first)); 179 GrantFileAccessToExtension(extension_id,
180 FilePath::FromUTF8Unsafe(files[i].name));
185 } 181 }
186 } 182 }
187 183
188 void CrosMountPointProvider::GrantFileAccessToExtension( 184 void CrosMountPointProvider::GrantFileAccessToExtension(
189 const std::string& extension_id, const FilePath& virtual_path) { 185 const std::string& extension_id, const FilePath& virtual_path) {
190 // All we care about here is access from extensions for now. 186 // All we care about here is access from extensions for now.
191 DCHECK(special_storage_policy_->IsFileHandler(extension_id)); 187 DCHECK(special_storage_policy_->IsFileHandler(extension_id));
192 if (!special_storage_policy_->IsFileHandler(extension_id)) 188 if (!special_storage_policy_->IsFileHandler(extension_id))
193 return; 189 return;
194 file_access_permissions_->GrantAccessPermission(extension_id, virtual_path); 190 file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
195 } 191 }
196 192
197 void CrosMountPointProvider::RevokeAccessForExtension( 193 void CrosMountPointProvider::RevokeAccessForExtension(
198 const std::string& extension_id) { 194 const std::string& extension_id) {
199 file_access_permissions_->RevokePermissions(extension_id); 195 file_access_permissions_->RevokePermissions(extension_id);
200 } 196 }
201 197
202 std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const { 198 std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const {
199 std::vector<fileapi::IsolatedContext::FileInfo> files =
200 isolated_context()->GetExternalMountPoints();
203 std::vector<FilePath> root_dirs; 201 std::vector<FilePath> root_dirs;
204 for (MountPointMap::const_iterator iter = mount_point_map_.begin(); 202 for (size_t i = 0; i < files.size(); ++i)
205 iter != mount_point_map_.end(); 203 root_dirs.push_back(files[i].path);
206 ++iter) {
207 root_dirs.push_back(iter->second.local_root_path.Append(iter->first));
208 }
209 return root_dirs; 204 return root_dirs;
210 } 205 }
211 206
212 fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil( 207 fileapi::FileSystemFileUtil* CrosMountPointProvider::GetFileUtil(
213 fileapi::FileSystemType type) { 208 fileapi::FileSystemType type) {
209 DCHECK(type == fileapi::kFileSystemTypeNativeLocal);
214 return local_file_util_.get(); 210 return local_file_util_.get();
215 } 211 }
216 212
217 FilePath CrosMountPointProvider::GetPathForPermissionsCheck( 213 FilePath CrosMountPointProvider::GetPathForPermissionsCheck(
218 const FilePath& virtual_path) const { 214 const FilePath& virtual_path) const {
219 const MountPoint* mount_point = GetMountPoint(virtual_path); 215 return virtual_path;
220 if (!mount_point)
221 return FilePath();
222
223 FilePath root_path = mount_point->local_root_path;
224
225 return root_path.Append(virtual_path);
226 }
227
228 const CrosMountPointProvider::MountPoint*
229 CrosMountPointProvider::GetMountPoint(const FilePath& virtual_path) const {
230 std::vector<FilePath::StringType> components;
231 virtual_path.GetComponents(&components);
232 if (components.empty())
233 return NULL;
234
235 base::AutoLock locker(
236 const_cast<CrosMountPointProvider*>(this)->mount_point_map_lock_);
237 // Check if this root mount point is exposed by this provider.
238 MountPointMap::const_iterator iter = mount_point_map_.find(components[0]);
239 if (iter == mount_point_map_.end())
240 return NULL;
241
242 return &(iter->second);
243 } 216 }
244 217
245 fileapi::FileSystemOperationInterface* 218 fileapi::FileSystemOperationInterface*
246 CrosMountPointProvider::CreateFileSystemOperation( 219 CrosMountPointProvider::CreateFileSystemOperation(
247 const fileapi::FileSystemURL& url, 220 const fileapi::FileSystemURL& url,
248 fileapi::FileSystemContext* context) const { 221 fileapi::FileSystemContext* context) const {
249 const MountPoint* mount_point = GetMountPoint(url.path()); 222 if (url.type() == fileapi::kFileSystemTypeDrive) {
250 if (mount_point && mount_point->location == REMOTE) 223 base::AutoLock locker(mount_point_map_lock_);
251 return new chromeos::RemoteFileSystemOperation(mount_point->remote_proxy); 224 RemoteProxyMap::const_iterator found = remote_proxy_map_.find(
225 url.filesystem_id());
226 // TODO(kinuko): we should handle not-found case gracefully.
227 // http://crbug.com/141617
228 if (found != remote_proxy_map_.end()) {
229 return new chromeos::RemoteFileSystemOperation(found->second);
230 }
231 }
252 232
233 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
253 scoped_ptr<fileapi::FileSystemOperationContext> operation_context( 234 scoped_ptr<fileapi::FileSystemOperationContext> operation_context(
254 new fileapi::FileSystemOperationContext(context)); 235 new fileapi::FileSystemOperationContext(context));
255 return new fileapi::LocalFileSystemOperation(context, 236 return new fileapi::LocalFileSystemOperation(context,
256 operation_context.Pass()); 237 operation_context.Pass());
257 } 238 }
258 239
259 webkit_blob::FileStreamReader* CrosMountPointProvider::CreateFileStreamReader( 240 webkit_blob::FileStreamReader* CrosMountPointProvider::CreateFileStreamReader(
260 const fileapi::FileSystemURL& url, 241 const fileapi::FileSystemURL& url,
261 int64 offset, 242 int64 offset,
262 fileapi::FileSystemContext* context) const { 243 fileapi::FileSystemContext* context) const {
263 // For now we return a generic Reader implementation which utilizes 244 // For now we return a generic Reader implementation which utilizes
264 // CreateSnapshotFile internally (i.e. will download everything first). 245 // CreateSnapshotFile internally (i.e. will download everything first).
265 // TODO(satorux,zel): implement more efficient reader for remote cases. 246 // TODO(satorux,zel): implement more efficient reader for remote cases.
266 return new fileapi::FileSystemFileStreamReader(context, url, offset); 247 return new fileapi::FileSystemFileStreamReader(context, url, offset);
267 } 248 }
268 249
269 fileapi::FileStreamWriter* CrosMountPointProvider::CreateFileStreamWriter( 250 fileapi::FileStreamWriter* CrosMountPointProvider::CreateFileStreamWriter(
270 const fileapi::FileSystemURL& url, 251 const fileapi::FileSystemURL& url,
271 int64 offset, 252 int64 offset,
272 fileapi::FileSystemContext* context) const { 253 fileapi::FileSystemContext* context) const {
273 if (!url.is_valid()) 254 if (!url.is_valid())
274 return NULL; 255 return NULL;
275 const MountPoint* mount_point = GetMountPoint(url.path()); 256 if (url.type() == fileapi::kFileSystemTypeDrive) {
276 if (!mount_point) 257 base::AutoLock locker(mount_point_map_lock_);
277 return NULL; 258 RemoteProxyMap::const_iterator found = remote_proxy_map_.find(
278 if (mount_point->location == REMOTE) { 259 url.filesystem_id());
279 return new fileapi::RemoteFileStreamWriter(mount_point->remote_proxy, 260 if (found == remote_proxy_map_.end())
280 url, 261 return NULL;
281 offset); 262 return new fileapi::RemoteFileStreamWriter(found->second, url, offset);
282 } 263 }
283 FilePath root_path = mount_point->local_root_path; 264
284 return new fileapi::LocalFileStreamWriter( 265 DCHECK(url.type() == fileapi::kFileSystemTypeNativeLocal);
285 root_path.Append(url.path()), offset); 266 return new fileapi::LocalFileStreamWriter(url.path(), offset);
286 } 267 }
287 268
288 bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path, 269 bool CrosMountPointProvider::GetVirtualPath(const FilePath& filesystem_path,
289 FilePath* virtual_path) { 270 FilePath* virtual_path) {
290 for (MountPointMap::const_iterator iter = mount_point_map_.begin(); 271 base::AutoLock locker(mount_point_map_lock_);
291 iter != mount_point_map_.end(); 272 std::map<FilePath, FilePath>::reverse_iterator iter(
292 ++iter) { 273 local_to_virtual_map_.upper_bound(filesystem_path));
293 FilePath mount_prefix = iter->second.local_root_path.Append(iter->first); 274 if (iter == local_to_virtual_map_.rend())
294 *virtual_path = FilePath(iter->first); 275 return false;
295 if (mount_prefix == filesystem_path) { 276 if (iter->first == filesystem_path) {
296 return true; 277 *virtual_path = iter->second;
297 } else if (mount_prefix.AppendRelativePath(filesystem_path, virtual_path)) { 278 return true;
298 return true;
299 }
300 } 279 }
301 return false; 280 return iter->first.DirName().AppendRelativePath(
281 filesystem_path, virtual_path);
282 }
283
284 fileapi::IsolatedContext* CrosMountPointProvider::isolated_context() const {
285 return fileapi::IsolatedContext::GetInstance();
302 } 286 }
303 287
304 } // namespace chromeos 288 } // namespace chromeos
OLDNEW
« no previous file with comments | « webkit/chromeos/fileapi/cros_mount_point_provider.h ('k') | webkit/fileapi/file_system_context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698