OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
" | 5 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h
" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "content/public/browser/browser_ppapi_host.h" | 9 #include "content/public/browser/browser_ppapi_host.h" |
10 #include "content/public/browser/browser_thread.h" | 10 #include "content/public/browser/browser_thread.h" |
| 11 #include "content/public/browser/plugin_service.h" |
11 #include "content/public/browser/render_process_host.h" | 12 #include "content/public/browser/render_process_host.h" |
12 #include "content/public/browser/storage_partition.h" | 13 #include "content/public/browser/storage_partition.h" |
| 14 #include "content/public/common/pepper_plugin_info.h" |
| 15 #include "net/base/mime_util.h" |
13 #include "ppapi/c/pp_errors.h" | 16 #include "ppapi/c/pp_errors.h" |
14 #include "ppapi/host/dispatch_host_message.h" | 17 #include "ppapi/host/dispatch_host_message.h" |
15 #include "ppapi/host/ppapi_host.h" | 18 #include "ppapi/host/ppapi_host.h" |
16 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
17 #include "ppapi/shared_impl/file_system_util.h" | 20 #include "ppapi/shared_impl/file_system_util.h" |
18 #include "ppapi/shared_impl/file_type_conversion.h" | 21 #include "ppapi/shared_impl/file_type_conversion.h" |
19 #include "webkit/browser/fileapi/file_system_context.h" | 22 #include "webkit/browser/fileapi/file_system_context.h" |
20 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 23 #include "webkit/browser/fileapi/file_system_operation_runner.h" |
| 24 #include "webkit/browser/fileapi/isolated_context.h" |
21 #include "webkit/common/fileapi/file_system_util.h" | 25 #include "webkit/common/fileapi/file_system_util.h" |
22 | 26 |
23 namespace content { | 27 namespace content { |
24 | 28 |
25 namespace { | 29 namespace { |
26 | 30 |
27 scoped_refptr<fileapi::FileSystemContext> | 31 scoped_refptr<fileapi::FileSystemContext> |
28 GetFileSystemContextFromRenderId(int render_process_id) { | 32 GetFileSystemContextFromRenderId(int render_process_id) { |
29 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
30 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); | 34 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); |
31 if (!host) | 35 if (!host) |
32 return NULL; | 36 return NULL; |
33 StoragePartition* storage_partition = host->GetStoragePartition(); | 37 StoragePartition* storage_partition = host->GetStoragePartition(); |
34 if (!storage_partition) | 38 if (!storage_partition) |
35 return NULL; | 39 return NULL; |
36 return storage_partition->GetFileSystemContext(); | 40 return storage_partition->GetFileSystemContext(); |
37 } | 41 } |
38 | 42 |
39 // TODO(nhiroki): Move this function somewhere else to be shared. | |
40 std::string IsolatedFileSystemTypeToRootName( | |
41 PP_IsolatedFileSystemType_Private type) { | |
42 switch (type) { | |
43 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID: | |
44 break; | |
45 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: | |
46 return "crxfs"; | |
47 } | |
48 NOTREACHED() << type; | |
49 return std::string(); | |
50 } | |
51 | |
52 } // namespace | 43 } // namespace |
53 | 44 |
54 PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host, | 45 PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host, |
55 PP_Instance instance, | 46 PP_Instance instance, |
56 PP_Resource resource, | 47 PP_Resource resource, |
57 PP_FileSystemType type) | 48 PP_FileSystemType type) |
58 : ResourceHost(host->GetPpapiHost(), instance, resource), | 49 : ResourceHost(host->GetPpapiHost(), instance, resource), |
59 browser_ppapi_host_(host), | 50 browser_ppapi_host_(host), |
60 type_(type), | 51 type_(type), |
61 opened_(false), | 52 opened_(false), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 if (file_system_type == fileapi::kFileSystemTypeUnknown) | 115 if (file_system_type == fileapi::kFileSystemTypeUnknown) |
125 return PP_ERROR_FAILED; | 116 return PP_ERROR_FAILED; |
126 | 117 |
127 int render_process_id = 0; | 118 int render_process_id = 0; |
128 int unused; | 119 int unused; |
129 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), | 120 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), |
130 &render_process_id, | 121 &render_process_id, |
131 &unused)) { | 122 &unused)) { |
132 return PP_ERROR_FAILED; | 123 return PP_ERROR_FAILED; |
133 } | 124 } |
| 125 |
134 BrowserThread::PostTaskAndReplyWithResult( | 126 BrowserThread::PostTaskAndReplyWithResult( |
135 BrowserThread::UI, | 127 BrowserThread::UI, |
136 FROM_HERE, | 128 FROM_HERE, |
137 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), | 129 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), |
138 base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext, | 130 base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext, |
139 weak_factory_.GetWeakPtr(), | 131 weak_factory_.GetWeakPtr(), |
140 context->MakeReplyMessageContext(), | 132 context->MakeReplyMessageContext(), |
141 file_system_type)); | 133 file_system_type)); |
142 return PP_OK_COMPLETIONPENDING; | 134 return PP_OK_COMPLETIONPENDING; |
143 } | 135 } |
(...skipping 20 matching lines...) Expand all Loading... |
164 if (!fs_context.get()) { | 156 if (!fs_context.get()) { |
165 OpenFileSystemComplete( | 157 OpenFileSystemComplete( |
166 reply_context, GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED); | 158 reply_context, GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED); |
167 return; | 159 return; |
168 } | 160 } |
169 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( | 161 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( |
170 pp_instance()).GetOrigin(); | 162 pp_instance()).GetOrigin(); |
171 fs_context->OpenFileSystem(origin, file_system_type, | 163 fs_context->OpenFileSystem(origin, file_system_type, |
172 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | 164 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, |
173 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, | 165 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, |
174 weak_factory_.GetWeakPtr(), | 166 weak_factory_.GetWeakPtr(), reply_context)); |
175 reply_context)); | |
176 fs_context_ = fs_context; | 167 fs_context_ = fs_context; |
177 } | 168 } |
178 | 169 |
179 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext( | |
180 ppapi::host::ReplyMessageContext reply_context, | |
181 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
182 fs_context_ = fs_context; | |
183 if (fs_context.get()) | |
184 reply_context.params.set_result(PP_OK); | |
185 else | |
186 reply_context.params.set_result(PP_ERROR_FAILED); | |
187 host()->SendReply(reply_context, | |
188 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
189 } | |
190 | |
191 void PepperFileSystemBrowserHost::OpenFileSystemComplete( | 170 void PepperFileSystemBrowserHost::OpenFileSystemComplete( |
192 ppapi::host::ReplyMessageContext reply_context, | 171 ppapi::host::ReplyMessageContext reply_context, |
193 const GURL& root, | 172 const GURL& root, |
194 const std::string& /* unused */, | 173 const std::string& /* unused */, |
195 base::PlatformFileError error) { | 174 base::PlatformFileError error) { |
196 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); | 175 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); |
197 if (pp_error == PP_OK) { | 176 if (pp_error == PP_OK) { |
198 opened_ = true; | 177 opened_ = true; |
199 root_url_ = root; | 178 root_url_ = root; |
200 } | 179 } |
201 reply_context.params.set_result(pp_error); | 180 reply_context.params.set_result(pp_error); |
202 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); | 181 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); |
203 } | 182 } |
204 | 183 |
| 184 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext( |
| 185 ppapi::host::ReplyMessageContext reply_context, |
| 186 const std::string& fsid, |
| 187 PP_IsolatedFileSystemType_Private type, |
| 188 scoped_refptr<fileapi::FileSystemContext> fs_context) { |
| 189 fs_context_ = fs_context; |
| 190 if (!fs_context.get()) { |
| 191 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED); |
| 192 return; |
| 193 } |
| 194 |
| 195 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( |
| 196 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(), |
| 197 fsid, ppapi::IsolatedFileSystemTypeToRootName(type))); |
| 198 if (!root_url_.is_valid()) { |
| 199 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED); |
| 200 return; |
| 201 } |
| 202 |
| 203 switch (type) { |
| 204 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: |
| 205 opened_ = true; |
| 206 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_OK); |
| 207 return; |
| 208 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE: |
| 209 OpenPluginPrivateFileSystem(reply_context, fsid, fs_context); |
| 210 return; |
| 211 default: |
| 212 NOTREACHED(); |
| 213 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT); |
| 214 return; |
| 215 } |
| 216 } |
| 217 |
| 218 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystem( |
| 219 ppapi::host::ReplyMessageContext reply_context, |
| 220 const std::string& fsid, |
| 221 scoped_refptr<fileapi::FileSystemContext> fs_context) { |
| 222 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( |
| 223 pp_instance()).GetOrigin(); |
| 224 if (!origin.is_valid()) { |
| 225 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED); |
| 226 return; |
| 227 } |
| 228 |
| 229 const std::string& plugin_id = GeneratePluginId(GetPluginMimeType()); |
| 230 if (plugin_id.empty()) { |
| 231 SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT); |
| 232 return; |
| 233 } |
| 234 |
| 235 fs_context->OpenPluginPrivateFileSystem( |
| 236 origin, fileapi::kFileSystemTypePluginPrivate, fsid, plugin_id, |
| 237 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, |
| 238 base::Bind( |
| 239 &PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete, |
| 240 weak_factory_.GetWeakPtr(), reply_context, fsid)); |
| 241 } |
| 242 |
| 243 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete( |
| 244 ppapi::host::ReplyMessageContext reply_context, |
| 245 const std::string& fsid, |
| 246 base::PlatformFileError error) { |
| 247 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); |
| 248 if (pp_error == PP_OK) |
| 249 opened_ = true; |
| 250 SendReplyForIsolatedFileSystem(reply_context, fsid, pp_error); |
| 251 } |
| 252 |
205 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( | 253 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( |
206 ppapi::host::HostMessageContext* context, | 254 ppapi::host::HostMessageContext* context, |
207 const std::string& fsid, | 255 const std::string& fsid, |
208 PP_IsolatedFileSystemType_Private type) { | 256 PP_IsolatedFileSystemType_Private type) { |
209 // Do not allow multiple opens. | 257 // Do not allow multiple opens. |
210 if (called_open_) | 258 if (called_open_) |
211 return PP_ERROR_INPROGRESS; | 259 return PP_ERROR_INPROGRESS; |
212 called_open_ = true; | 260 called_open_ = true; |
213 | 261 |
214 // Do a sanity check. | 262 // Do a sanity check. |
215 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) | 263 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) |
216 return PP_ERROR_BADARGUMENT; | 264 return PP_ERROR_BADARGUMENT; |
217 | 265 |
218 const GURL& url = | |
219 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); | |
220 const std::string root_name = IsolatedFileSystemTypeToRootName(type); | |
221 if (root_name.empty()) | |
222 return PP_ERROR_BADARGUMENT; | |
223 | |
224 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( | |
225 url.GetOrigin(), fsid, root_name)); | |
226 opened_ = true; | |
227 | |
228 int render_process_id = 0; | 266 int render_process_id = 0; |
229 int unused; | 267 int unused; |
230 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), | 268 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), |
231 &render_process_id, | 269 &render_process_id, |
232 &unused)) { | 270 &unused)) { |
| 271 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid); |
233 return PP_ERROR_FAILED; | 272 return PP_ERROR_FAILED; |
234 } | 273 } |
| 274 |
235 BrowserThread::PostTaskAndReplyWithResult( | 275 BrowserThread::PostTaskAndReplyWithResult( |
236 BrowserThread::UI, | 276 BrowserThread::UI, |
237 FROM_HERE, | 277 FROM_HERE, |
238 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), | 278 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), |
239 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, | 279 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, |
240 weak_factory_.GetWeakPtr(), | 280 weak_factory_.GetWeakPtr(), |
241 context->MakeReplyMessageContext())); | 281 context->MakeReplyMessageContext(), fsid, type)); |
242 return PP_OK_COMPLETIONPENDING; | 282 return PP_OK_COMPLETIONPENDING; |
243 } | 283 } |
244 | 284 |
| 285 void PepperFileSystemBrowserHost::SendReplyForIsolatedFileSystem( |
| 286 ppapi::host::ReplyMessageContext reply_context, |
| 287 const std::string& fsid, |
| 288 int32_t error) { |
| 289 if (error != PP_OK) |
| 290 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid); |
| 291 reply_context.params.set_result(error); |
| 292 host()->SendReply(reply_context, |
| 293 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); |
| 294 } |
| 295 |
| 296 std::string PepperFileSystemBrowserHost::GetPluginMimeType() const { |
| 297 base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath(); |
| 298 PepperPluginInfo* info = |
| 299 PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path); |
| 300 if (!info || info->mime_types.empty()) |
| 301 return std::string(); |
| 302 // Use the first element in |info->mime_types| even if several elements exist. |
| 303 return info->mime_types[0].mime_type; |
| 304 } |
| 305 |
| 306 std::string PepperFileSystemBrowserHost::GeneratePluginId( |
| 307 const std::string& mime_type) const { |
| 308 // TODO(nhiroki): This function is very specialized for specific plugins (MIME |
| 309 // types). If we bring this API to stable, we might have to make it more |
| 310 // general. |
| 311 |
| 312 if (!net::IsMimeType(mime_type)) |
| 313 return std::string(); |
| 314 std::string output = mime_type; |
| 315 |
| 316 // Replace a slash used for type/subtype separator with an underscore. |
| 317 // NOTE: This assumes there is only one slash in the MIME type. |
| 318 ReplaceFirstSubstringAfterOffset(&output, 0, "/", "_"); |
| 319 |
| 320 // Verify |output| contains only alphabets, digits, or "._-". |
| 321 for (std::string::const_iterator it = output.begin(); |
| 322 it != output.end(); ++it) { |
| 323 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && |
| 324 *it != '.' && *it != '_' && *it != '-') { |
| 325 LOG(WARNING) << "Failed to generate a plugin id."; |
| 326 return std::string(); |
| 327 } |
| 328 } |
| 329 return output; |
| 330 } |
| 331 |
245 } // namespace content | 332 } // namespace content |
OLD | NEW |