Chromium Code Reviews| 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" |
| 20 #include "ppapi/shared_impl/file_system_util.h" | |
| 17 #include "ppapi/shared_impl/file_type_conversion.h" | 21 #include "ppapi/shared_impl/file_type_conversion.h" |
| 18 #include "webkit/browser/fileapi/file_system_context.h" | 22 #include "webkit/browser/fileapi/file_system_context.h" |
| 19 #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" | |
| 20 #include "webkit/common/fileapi/file_system_util.h" | 25 #include "webkit/common/fileapi/file_system_util.h" |
| 21 | 26 |
| 22 namespace content { | 27 namespace content { |
| 23 | 28 |
| 24 namespace { | 29 namespace { |
| 25 | 30 |
| 26 scoped_refptr<fileapi::FileSystemContext> | 31 scoped_refptr<fileapi::FileSystemContext> |
| 27 GetFileSystemContextFromRenderId(int render_process_id) { | 32 GetFileSystemContextFromRenderId(int render_process_id) { |
| 28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 29 RenderProcessHost* render_process_host = | 34 RenderProcessHost* render_process_host = |
| 30 RenderProcessHost::FromID(render_process_id); | 35 RenderProcessHost::FromID(render_process_id); |
| 31 if (!render_process_host) | 36 if (!render_process_host) |
| 32 return NULL; | 37 return NULL; |
| 33 StoragePartition* storage_partition = | 38 StoragePartition* storage_partition = |
| 34 render_process_host->GetStoragePartition(); | 39 render_process_host->GetStoragePartition(); |
| 35 if (!storage_partition) | 40 if (!storage_partition) |
| 36 return NULL; | 41 return NULL; |
| 37 return storage_partition->GetFileSystemContext(); | 42 return storage_partition->GetFileSystemContext(); |
| 38 } | 43 } |
| 39 | 44 |
| 40 // TODO(nhiroki): Move this function somewhere else to be shared. | |
| 41 std::string IsolatedFileSystemTypeToRootName( | |
| 42 PP_IsolatedFileSystemType_Private type) { | |
| 43 switch (type) { | |
| 44 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID: | |
| 45 break; | |
| 46 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: | |
| 47 return "crxfs"; | |
| 48 } | |
| 49 NOTREACHED() << type; | |
| 50 return std::string(); | |
| 51 } | |
| 52 | |
| 53 } // namespace | 45 } // namespace |
| 54 | 46 |
| 55 PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host, | 47 PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host, |
| 56 PP_Instance instance, | 48 PP_Instance instance, |
| 57 PP_Resource resource, | 49 PP_Resource resource, |
| 58 PP_FileSystemType type) | 50 PP_FileSystemType type) |
| 59 : ResourceHost(host->GetPpapiHost(), instance, resource), | 51 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 60 browser_ppapi_host_(host), | 52 browser_ppapi_host_(host), |
| 61 type_(type), | 53 type_(type), |
| 62 opened_(false), | 54 opened_(false), |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( | 172 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( |
| 181 pp_instance()).GetOrigin(); | 173 pp_instance()).GetOrigin(); |
| 182 fs_context->OpenFileSystem(origin, file_system_type, | 174 fs_context->OpenFileSystem(origin, file_system_type, |
| 183 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | 175 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, |
| 184 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, | 176 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, |
| 185 weak_factory_.GetWeakPtr(), | 177 weak_factory_.GetWeakPtr(), |
| 186 reply_context)); | 178 reply_context)); |
| 187 fs_context_ = fs_context; | 179 fs_context_ = fs_context; |
| 188 } | 180 } |
| 189 | 181 |
| 190 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext( | |
| 191 ppapi::host::ReplyMessageContext reply_context, | |
| 192 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
| 193 fs_context_ = fs_context; | |
| 194 if (fs_context.get()) | |
| 195 reply_context.params.set_result(PP_OK); | |
| 196 else | |
| 197 reply_context.params.set_result(PP_ERROR_FAILED); | |
| 198 host()->SendReply(reply_context, | |
| 199 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 200 } | |
| 201 | |
| 202 void PepperFileSystemBrowserHost::OpenFileSystemComplete( | 182 void PepperFileSystemBrowserHost::OpenFileSystemComplete( |
| 203 ppapi::host::ReplyMessageContext reply_context, | 183 ppapi::host::ReplyMessageContext reply_context, |
| 204 const GURL& root, | 184 const GURL& root, |
| 205 const std::string& /* unused */, | 185 const std::string& /* unused */, |
| 206 base::PlatformFileError error) { | 186 base::PlatformFileError error) { |
| 207 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); | 187 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); |
| 208 if (pp_error == PP_OK) { | 188 if (pp_error == PP_OK) { |
| 209 opened_ = true; | 189 opened_ = true; |
| 210 root_url_ = root; | 190 root_url_ = root; |
| 211 } | 191 } |
| 212 reply_context.params.set_result(pp_error); | 192 reply_context.params.set_result(pp_error); |
| 213 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); | 193 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); |
| 214 } | 194 } |
| 215 | 195 |
| 196 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext( | |
| 197 ppapi::host::ReplyMessageContext reply_context, | |
| 198 const std::string& fsid, | |
| 199 PP_IsolatedFileSystemType_Private type, | |
| 200 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
| 201 fs_context_ = fs_context; | |
| 202 if (!fs_context.get()) { | |
| 203 reply_context.params.set_result(PP_ERROR_FAILED); | |
| 204 host()->SendReply(reply_context, | |
| 205 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 206 return; | |
| 207 } | |
| 208 | |
| 209 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( | |
|
teravest
2013/11/12 18:04:53
Should we do anything if root_url_.is_valid() is f
nhiroki
2013/11/14 11:34:39
Done.
| |
| 210 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()), | |
| 211 fsid, ppapi::IsolatedFileSystemTypeToRootName(type))); | |
| 212 | |
| 213 switch (type) { | |
| 214 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_INVALID: | |
|
teravest
2013/11/12 18:04:53
Should this just be the default case for the switc
nhiroki
2013/11/14 11:34:39
Done.
| |
| 215 NOTREACHED(); | |
| 216 reply_context.params.set_result(PP_ERROR_BADARGUMENT); | |
| 217 break; | |
| 218 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: | |
| 219 opened_ = true; | |
| 220 reply_context.params.set_result(PP_OK); | |
| 221 break; | |
| 222 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE: | |
| 223 OpenPluginPrivateFileSystem(reply_context, fsid, fs_context); | |
| 224 return; | |
| 225 } | |
| 226 host()->SendReply(reply_context, | |
| 227 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 228 } | |
| 229 | |
| 230 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystem( | |
| 231 ppapi::host::ReplyMessageContext reply_context, | |
| 232 const std::string& fsid, | |
| 233 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
| 234 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( | |
|
teravest
2013/11/12 18:04:53
Should we do a validity check on origin here?
nhiroki
2013/11/14 11:34:39
Done.
| |
| 235 pp_instance()).GetOrigin(); | |
| 236 | |
| 237 const std::string plugin_id = GeneratePluginId(); | |
| 238 if (plugin_id.empty()) { | |
| 239 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid); | |
| 240 reply_context.params.set_result(PP_ERROR_BADARGUMENT); | |
| 241 host()->SendReply(reply_context, | |
| 242 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 243 return; | |
| 244 } | |
| 245 | |
| 246 fs_context->OpenPluginPrivateFileSystem( | |
| 247 origin, fileapi::kFileSystemTypePluginPrivate, fsid, plugin_id, | |
| 248 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | |
| 249 base::Bind( | |
| 250 &PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete, | |
| 251 weak_factory_.GetWeakPtr(), reply_context)); | |
| 252 } | |
| 253 | |
| 254 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete( | |
| 255 ppapi::host::ReplyMessageContext reply_context, | |
| 256 base::PlatformFileError error) { | |
| 257 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); | |
| 258 if (pp_error == PP_OK) | |
| 259 opened_ = true; | |
| 260 reply_context.params.set_result(pp_error); | |
| 261 host()->SendReply( | |
| 262 reply_context, | |
| 263 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 264 } | |
| 265 | |
| 216 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( | 266 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( |
| 217 ppapi::host::HostMessageContext* context, | 267 ppapi::host::HostMessageContext* context, |
| 218 const std::string& fsid, | 268 const std::string& fsid, |
| 219 PP_IsolatedFileSystemType_Private type) { | 269 PP_IsolatedFileSystemType_Private type) { |
| 220 // Do not allow multiple opens. | 270 // Do not allow multiple opens. |
| 221 if (called_open_) | 271 if (called_open_) |
| 222 return PP_ERROR_INPROGRESS; | 272 return PP_ERROR_INPROGRESS; |
| 223 called_open_ = true; | 273 called_open_ = true; |
| 224 | 274 |
| 225 // Do a sanity check. | 275 // Do a sanity check. |
| 226 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) | 276 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) |
| 227 return PP_ERROR_BADARGUMENT; | 277 return PP_ERROR_BADARGUMENT; |
| 228 | 278 |
| 229 const GURL& url = | |
| 230 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); | |
| 231 const std::string root_name = IsolatedFileSystemTypeToRootName(type); | |
| 232 if (root_name.empty()) | |
| 233 return PP_ERROR_BADARGUMENT; | |
| 234 | |
| 235 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( | |
| 236 url.GetOrigin(), fsid, root_name)); | |
| 237 opened_ = true; | |
| 238 | |
| 239 int render_process_id = 0; | 279 int render_process_id = 0; |
| 240 int unused; | 280 int unused; |
| 241 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), | 281 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), |
| 242 &render_process_id, | 282 &render_process_id, |
| 243 &unused)) { | 283 &unused)) { |
| 244 return PP_ERROR_FAILED; | 284 return PP_ERROR_FAILED; |
| 245 } | 285 } |
| 246 BrowserThread::PostTaskAndReplyWithResult( | 286 BrowserThread::PostTaskAndReplyWithResult( |
| 247 BrowserThread::UI, | 287 BrowserThread::UI, |
| 248 FROM_HERE, | 288 FROM_HERE, |
| 249 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), | 289 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), |
| 250 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, | 290 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, |
| 251 weak_factory_.GetWeakPtr(), | 291 weak_factory_.GetWeakPtr(), |
| 252 context->MakeReplyMessageContext())); | 292 context->MakeReplyMessageContext(), fsid, type)); |
| 253 return PP_OK_COMPLETIONPENDING; | 293 return PP_OK_COMPLETIONPENDING; |
| 254 } | 294 } |
| 255 | 295 |
| 296 std::string PepperFileSystemBrowserHost::GeneratePluginId() { | |
| 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 | |
| 303 // Use the first element in |info->mime_types| even if several elements exist. | |
| 304 std::string output = info->mime_types[0].mime_type; | |
| 305 if (!net::IsMimeType(output)) | |
| 306 return std::string(); | |
| 307 | |
| 308 // Replace a slash used for type/subtype separator with an underscore. | |
| 309 // NOTE: This assumes there is only one slash in the MIME type. | |
| 310 ReplaceFirstSubstringAfterOffset(&output, 0, "/", "_"); | |
| 311 | |
| 312 // Verify |output| contains only alphabets, digits, or "._-". | |
|
teravest
2013/11/12 18:04:53
This is stricter than what mime types require, rig
nhiroki
2013/11/14 11:34:39
That's right. MIME type requires at least one slas
| |
| 313 for (std::string::const_iterator it = output.begin(); | |
| 314 it != output.end(); ++it) { | |
| 315 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && | |
| 316 *it != '.' && *it != '_' && *it != '-') { | |
| 317 return std::string(); | |
| 318 } | |
| 319 } | |
| 320 return output; | |
| 321 } | |
| 322 | |
| 256 } // namespace content | 323 } // namespace content |
| OLD | NEW |