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

Side by Side Diff: webkit/fileapi/isolated_context.cc

Issue 10713007: Make isolated file system works for a device root (e.g. X:\\) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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/fileapi/isolated_context.h" 5 #include "webkit/fileapi/isolated_context.h"
6 6
7 #include "base/file_path.h"
7 #include "base/basictypes.h" 8 #include "base/basictypes.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/rand_util.h" 10 #include "base/rand_util.h"
10 #include "base/string_number_conversions.h" 11 #include "base/string_number_conversions.h"
11 #include "base/string_util.h" 12 #include "base/string_util.h"
12 13
13 namespace fileapi { 14 namespace fileapi {
14 15
15 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = 16 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
16 LAZY_INSTANCE_INITIALIZER; 17 LAZY_INSTANCE_INITIALIZER;
17 18
19 IsolatedContext::FileInfo::FileInfo() {}
20 IsolatedContext::FileInfo::FileInfo(
21 const std::string& name, const FilePath& path)
22 : name(name), path(path) {}
23
18 // static 24 // static
19 IsolatedContext* IsolatedContext::GetInstance() { 25 IsolatedContext* IsolatedContext::GetInstance() {
20 return g_isolated_context.Pointer(); 26 return g_isolated_context.Pointer();
21 } 27 }
22 28
23 std::string IsolatedContext::RegisterIsolatedFileSystem( 29 std::string IsolatedContext::GetNameForPath(const FilePath& path) {
24 const std::set<FilePath>& files) { 30 // If it's not a root path simply return a base name.
31 if (path.DirName() != path)
32 return path.BaseName().AsUTF8Unsafe();
33
34 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
35 FilePath::StringType name;
36 for (size_t i = 0;
37 i < path.value().size() && !FilePath::IsSeparator(path.value()[i]);
38 ++i) {
39 if (path.value()[i] == L':') {
40 name.append(L"_drive");
41 break;
42 }
43 name.append(1, path.value()[i]);
44 }
45 return FilePath(name).AsUTF8Unsafe();
46 #else
47 return "<root>";
48 #endif
49 }
50
51 std::string IsolatedContext::RegisterFileSystem(
52 const std::vector<FileInfo>& files) {
25 base::AutoLock locker(lock_); 53 base::AutoLock locker(lock_);
26 std::string filesystem_id = GetNewFileSystemId(); 54 std::string filesystem_id = GetNewFileSystemId();
27 // Stores basename to fullpath map, as we store the basenames as 55 // Stores name to fullpath map, as we store the name as a key in
28 // the filesystem's toplevel entries. 56 // the filesystem's toplevel entries.
29 PathMap toplevels; 57 FileSet toplevels;
30 for (std::set<FilePath>::const_iterator iter = files.begin(); 58 for (size_t i = 0; i < files.size(); ++i) {
31 iter != files.end(); ++iter) { 59 const FileInfo& info = files[i];
32 // The given path should not contain any '..' and should be absolute. 60 // The given path should not contain any '..' and should be absolute.
33 if (iter->ReferencesParent() || !iter->IsAbsolute()) 61 if (info.path.ReferencesParent() || !info.path.IsAbsolute())
34 continue; 62 continue;
35 63
36 // Register the basename -> fullpath map. (We only expose the basename 64 // Register the basename -> fullpath map. (We only expose the basename
37 // part to the user scripts) 65 // part to the user scripts)
38 FilePath fullpath = iter->NormalizePathSeparators(); 66 FilePath fullpath = info.path.NormalizePathSeparators();
39 FilePath basename = iter->BaseName(); 67 bool inserted = toplevels.insert(FileInfo(info.name, fullpath)).second;
40 // TODO(kinuko): Append a suffix or something if we have multiple pathnames 68 DCHECK(inserted);
41 // with the same basename. For now we only register the first one.
42 toplevels.insert(std::make_pair(basename, fullpath));
43 } 69 }
44 70
45 // TODO(kinuko): we may not want to register the file system if there're 71 // TODO(kinuko): we may not want to register the file system if there're
46 // no valid paths in the given file set. 72 // no valid paths in the given file set.
47 73
48 toplevel_map_[filesystem_id] = toplevels; 74 toplevel_map_[filesystem_id] = toplevels;
49 75
50 // Each file system is created with refcount == 0. 76 // Each file system is created with refcount == 0.
51 ref_counts_[filesystem_id] = 0; 77 ref_counts_[filesystem_id] = 0;
52 78
53 return filesystem_id; 79 return filesystem_id;
54 } 80 }
55 81
56 void IsolatedContext::RevokeIsolatedFileSystem( 82 std::string IsolatedContext::RegisterFileSystemForFile(
57 const std::string& filesystem_id) { 83 const std::string& display_name,
84 const FilePath& path) {
85 std::vector<FileInfo> files;
86 files.push_back(FileInfo(display_name, path));
87 return RegisterFileSystem(files);
88 }
89
90 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
58 base::AutoLock locker(lock_); 91 base::AutoLock locker(lock_);
59 RevokeWithoutLocking(filesystem_id); 92 RevokeWithoutLocking(filesystem_id);
60 } 93 }
61 94
62 void IsolatedContext::AddReference(const std::string& filesystem_id) { 95 void IsolatedContext::AddReference(const std::string& filesystem_id) {
63 base::AutoLock locker(lock_); 96 base::AutoLock locker(lock_);
64 DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end()); 97 DCHECK(ref_counts_.find(filesystem_id) != ref_counts_.end());
65 ref_counts_[filesystem_id]++; 98 ref_counts_[filesystem_id]++;
66 } 99 }
67 100
68 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { 101 void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
69 base::AutoLock locker(lock_); 102 base::AutoLock locker(lock_);
70 // This could get called for non-existent filesystem if it has been 103 // This could get called for non-existent filesystem if it has been
71 // already deleted by RevokeIsolatedFileSystem. 104 // already deleted by RevokeFileSystem.
72 if (ref_counts_.find(filesystem_id) == ref_counts_.end()) 105 if (ref_counts_.find(filesystem_id) == ref_counts_.end())
73 return; 106 return;
74 DCHECK(ref_counts_[filesystem_id] > 0); 107 DCHECK(ref_counts_[filesystem_id] > 0);
75 if (--ref_counts_[filesystem_id] == 0) 108 if (--ref_counts_[filesystem_id] == 0)
76 RevokeWithoutLocking(filesystem_id); 109 RevokeWithoutLocking(filesystem_id);
77 } 110 }
78 111
79 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, 112 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
80 std::string* filesystem_id, 113 std::string* filesystem_id,
81 FilePath* root_path, 114 FileInfo* root_info,
82 FilePath* platform_path) const { 115 FilePath* platform_path) const {
83 DCHECK(filesystem_id); 116 DCHECK(filesystem_id);
84 DCHECK(platform_path); 117 DCHECK(platform_path);
85 118
86 // This should not contain any '..' references. 119 // This should not contain any '..' references.
87 if (virtual_path.ReferencesParent()) 120 if (virtual_path.ReferencesParent())
88 return false; 121 return false;
89 122
90 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. 123 // The virtual_path should comprise <filesystem_id> and <relative_path> parts.
91 std::vector<FilePath::StringType> components; 124 std::vector<FilePath::StringType> components;
92 virtual_path.GetComponents(&components); 125 virtual_path.GetComponents(&components);
93 if (components.size() < 1) 126 if (components.size() < 1)
94 return false; 127 return false;
95 128
96 base::AutoLock locker(lock_); 129 base::AutoLock locker(lock_);
97 std::string fsid = FilePath(components[0]).MaybeAsASCII(); 130 std::string fsid = FilePath(components[0]).MaybeAsASCII();
98 if (fsid.empty()) 131 if (fsid.empty())
99 return false; 132 return false;
100 IDToPathMap::const_iterator found_toplevels = toplevel_map_.find(fsid); 133 IDToFileSet::const_iterator found_toplevels = toplevel_map_.find(fsid);
101 if (found_toplevels == toplevel_map_.end()) 134 if (found_toplevels == toplevel_map_.end())
102 return false; 135 return false;
103 *filesystem_id = fsid; 136 *filesystem_id = fsid;
104 if (components.size() == 1) { 137 if (components.size() == 1) {
105 platform_path->clear(); 138 platform_path->clear();
106 return true; 139 return true;
107 } 140 }
108 // components[1] should be a toplevel path of the dropped paths. 141 // components[1] should be a name of the dropped paths.
109 PathMap::const_iterator found = found_toplevels->second.find( 142 FileSet::const_iterator found = found_toplevels->second.find(
110 FilePath(components[1])); 143 FileInfo(FilePath(components[1]).AsUTF8Unsafe(), FilePath()));
111 if (found == found_toplevels->second.end()) 144 if (found == found_toplevels->second.end())
112 return false; 145 return false;
113 FilePath path = found->second; 146 if (root_info)
114 if (root_path) 147 *root_info = *found;
115 *root_path = path; 148 FilePath path = found->path;
116 for (size_t i = 2; i < components.size(); ++i) { 149 for (size_t i = 2; i < components.size(); ++i)
117 path = path.Append(components[i]); 150 path = path.Append(components[i]);
118 }
119 *platform_path = path; 151 *platform_path = path;
120 return true; 152 return true;
121 } 153 }
122 154
123 bool IsolatedContext::GetTopLevelPaths(const std::string& filesystem_id, 155 bool IsolatedContext::GetRegisteredFileInfo(
124 std::vector<FilePath>* paths) const { 156 const std::string& filesystem_id, std::vector<FileInfo>* files) const {
125 DCHECK(paths); 157 DCHECK(files);
126 base::AutoLock locker(lock_); 158 base::AutoLock locker(lock_);
127 IDToPathMap::const_iterator found = toplevel_map_.find(filesystem_id); 159 IDToFileSet::const_iterator found = toplevel_map_.find(filesystem_id);
128 if (found == toplevel_map_.end()) 160 if (found == toplevel_map_.end())
129 return false; 161 return false;
130 paths->clear(); 162 files->assign(found->second.begin(), found->second.end());
131 PathMap toplevels = found->second;
132 for (PathMap::const_iterator iter = toplevels.begin();
133 iter != toplevels.end(); ++iter) {
134 // Each path map entry holds a map of a toplevel name to its full path.
135 paths->push_back(iter->second);
136 }
137 return true; 163 return true;
138 } 164 }
139 165
140 bool IsolatedContext::SetWritable(const std::string& filesystem_id, 166 bool IsolatedContext::SetWritable(const std::string& filesystem_id,
141 bool writable) { 167 bool writable) {
142 base::AutoLock locker(lock_); 168 base::AutoLock locker(lock_);
143 if (toplevel_map_.find(filesystem_id) == toplevel_map_.end()) 169 if (toplevel_map_.find(filesystem_id) == toplevel_map_.end())
144 return false; 170 return false;
145 if (writable) 171 if (writable)
146 writable_ids_.insert(filesystem_id); 172 writable_ids_.insert(filesystem_id);
147 else 173 else
148 writable_ids_.erase(filesystem_id); 174 writable_ids_.erase(filesystem_id);
149 return true; 175 return true;
150 } 176 }
151 177
152 bool IsolatedContext::IsWritable(const std::string& filesystem_id) const { 178 bool IsolatedContext::IsWritable(const std::string& filesystem_id) const {
153 base::AutoLock locker(lock_); 179 base::AutoLock locker(lock_);
154 return (writable_ids_.find(filesystem_id) != writable_ids_.end()); 180 return (writable_ids_.find(filesystem_id) != writable_ids_.end());
155 } 181 }
156 182
157 FilePath IsolatedContext::CreateVirtualPath( 183 FilePath IsolatedContext::CreateVirtualRootPath(
158 const std::string& filesystem_id, const FilePath& relative_path) const { 184 const std::string& filesystem_id) const {
159 FilePath full_path; 185 return FilePath().AppendASCII(filesystem_id);
160 full_path = full_path.AppendASCII(filesystem_id);
161 if (relative_path.value() != FILE_PATH_LITERAL("/"))
162 full_path = full_path.Append(relative_path);
163 return full_path;
164 } 186 }
165 187
166 IsolatedContext::IsolatedContext() { 188 IsolatedContext::IsolatedContext() {
167 } 189 }
168 190
169 IsolatedContext::~IsolatedContext() { 191 IsolatedContext::~IsolatedContext() {
170 } 192 }
171 193
172 void IsolatedContext::RevokeWithoutLocking( 194 void IsolatedContext::RevokeWithoutLocking(
173 const std::string& filesystem_id) { 195 const std::string& filesystem_id) {
174 toplevel_map_.erase(filesystem_id); 196 toplevel_map_.erase(filesystem_id);
175 writable_ids_.erase(filesystem_id); 197 writable_ids_.erase(filesystem_id);
176 ref_counts_.erase(filesystem_id); 198 ref_counts_.erase(filesystem_id);
177 } 199 }
178 200
179 std::string IsolatedContext::GetNewFileSystemId() const { 201 std::string IsolatedContext::GetNewFileSystemId() const {
180 // Returns an arbitrary random string which must be unique in the map. 202 // Returns an arbitrary random string which must be unique in the map.
181 uint32 random_data[4]; 203 uint32 random_data[4];
182 std::string id; 204 std::string id;
183 do { 205 do {
184 base::RandBytes(random_data, sizeof(random_data)); 206 base::RandBytes(random_data, sizeof(random_data));
185 id = base::HexEncode(random_data, sizeof(random_data)); 207 id = base::HexEncode(random_data, sizeof(random_data));
186 } while (toplevel_map_.find(id) != toplevel_map_.end()); 208 } while (toplevel_map_.find(id) != toplevel_map_.end());
187 return id; 209 return id;
188 } 210 }
189 211
190 } // namespace fileapi 212 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698