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" |
| 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 | |
| 126 reply_context_ = context->MakeReplyMessageContext(); | |
|
dmichael (off chromium)
2013/11/14 18:09:31
Did you change this for any particular reason? Pas
nhiroki
2013/11/15 12:24:01
I see. That was just clean-up purpose. Reverted th
| |
| 134 BrowserThread::PostTaskAndReplyWithResult( | 127 BrowserThread::PostTaskAndReplyWithResult( |
| 135 BrowserThread::UI, | 128 BrowserThread::UI, |
| 136 FROM_HERE, | 129 FROM_HERE, |
| 137 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), | 130 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), |
| 138 base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext, | 131 base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext, |
| 139 weak_factory_.GetWeakPtr(), | 132 weak_factory_.GetWeakPtr(), |
| 140 context->MakeReplyMessageContext(), | |
| 141 file_system_type)); | 133 file_system_type)); |
| 142 return PP_OK_COMPLETIONPENDING; | 134 return PP_OK_COMPLETIONPENDING; |
| 143 } | 135 } |
| 144 | 136 |
| 145 void PepperFileSystemBrowserHost::OpenExistingWithContext( | 137 void PepperFileSystemBrowserHost::OpenExistingWithContext( |
| 146 const base::Closure& callback, | 138 const base::Closure& callback, |
| 147 scoped_refptr<fileapi::FileSystemContext> fs_context) { | 139 scoped_refptr<fileapi::FileSystemContext> fs_context) { |
| 148 if (fs_context.get()) { | 140 if (fs_context.get()) { |
| 149 opened_ = true; | 141 opened_ = true; |
| 150 } else { | 142 } else { |
| 151 // If there is no file system context, we log a warning and continue with an | 143 // If there is no file system context, we log a warning and continue with an |
| 152 // invalid resource (which will produce errors when used), since we have no | 144 // invalid resource (which will produce errors when used), since we have no |
| 153 // way to communicate the error to the caller. | 145 // way to communicate the error to the caller. |
| 154 LOG(WARNING) << "Could not retrieve file system context."; | 146 LOG(WARNING) << "Could not retrieve file system context."; |
| 155 } | 147 } |
| 156 fs_context_ = fs_context; | 148 fs_context_ = fs_context; |
| 157 callback.Run(); | 149 callback.Run(); |
| 158 } | 150 } |
| 159 | 151 |
| 160 void PepperFileSystemBrowserHost::GotFileSystemContext( | 152 void PepperFileSystemBrowserHost::GotFileSystemContext( |
| 161 ppapi::host::ReplyMessageContext reply_context, | |
| 162 fileapi::FileSystemType file_system_type, | 153 fileapi::FileSystemType file_system_type, |
| 163 scoped_refptr<fileapi::FileSystemContext> fs_context) { | 154 scoped_refptr<fileapi::FileSystemContext> fs_context) { |
| 164 if (!fs_context.get()) { | 155 if (!fs_context.get()) { |
| 165 OpenFileSystemComplete( | 156 OpenFileSystemComplete( |
| 166 reply_context, GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED); | 157 GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED); |
| 167 return; | 158 return; |
| 168 } | 159 } |
| 169 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( | 160 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( |
| 170 pp_instance()).GetOrigin(); | 161 pp_instance()).GetOrigin(); |
| 171 fs_context->OpenFileSystem(origin, file_system_type, | 162 fs_context->OpenFileSystem(origin, file_system_type, |
| 172 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | 163 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, |
| 173 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, | 164 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete, |
| 174 weak_factory_.GetWeakPtr(), | 165 weak_factory_.GetWeakPtr())); |
| 175 reply_context)); | |
| 176 fs_context_ = fs_context; | 166 fs_context_ = fs_context; |
| 177 } | 167 } |
| 178 | 168 |
| 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( | 169 void PepperFileSystemBrowserHost::OpenFileSystemComplete( |
| 192 ppapi::host::ReplyMessageContext reply_context, | |
| 193 const GURL& root, | 170 const GURL& root, |
| 194 const std::string& /* unused */, | 171 const std::string& /* unused */, |
| 195 base::PlatformFileError error) { | 172 base::PlatformFileError error) { |
| 196 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); | 173 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); |
| 197 if (pp_error == PP_OK) { | 174 if (pp_error == PP_OK) { |
| 198 opened_ = true; | 175 opened_ = true; |
| 199 root_url_ = root; | 176 root_url_ = root; |
| 200 } | 177 } |
| 201 reply_context.params.set_result(pp_error); | 178 reply_context_.params.set_result(pp_error); |
| 202 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply()); | 179 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); |
| 180 } | |
| 181 | |
| 182 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext( | |
| 183 const std::string& fsid, | |
| 184 PP_IsolatedFileSystemType_Private type, | |
| 185 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
| 186 fs_context_ = fs_context; | |
| 187 if (!fs_context.get()) { | |
| 188 SendReplyForIsolatedFileSystem(fsid, PP_ERROR_FAILED); | |
| 189 return; | |
| 190 } | |
| 191 | |
| 192 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( | |
| 193 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(), | |
| 194 fsid, ppapi::IsolatedFileSystemTypeToRootName(type))); | |
| 195 if (!root_url_.is_valid()) { | |
| 196 SendReplyForIsolatedFileSystem(fsid, PP_ERROR_FAILED); | |
| 197 return; | |
| 198 } | |
| 199 | |
| 200 switch (type) { | |
| 201 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX: | |
| 202 opened_ = true; | |
| 203 SendReplyForIsolatedFileSystem(fsid, PP_OK); | |
| 204 return; | |
| 205 case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE: | |
| 206 OpenPluginPrivateFileSystem(fsid, fs_context); | |
| 207 return; | |
| 208 default: | |
| 209 NOTREACHED(); | |
| 210 SendReplyForIsolatedFileSystem(fsid, PP_ERROR_BADARGUMENT); | |
| 211 return; | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystem( | |
| 216 const std::string& fsid, | |
| 217 scoped_refptr<fileapi::FileSystemContext> fs_context) { | |
| 218 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance( | |
| 219 pp_instance()).GetOrigin(); | |
| 220 if (!origin.is_valid()) { | |
| 221 SendReplyForIsolatedFileSystem(fsid, PP_ERROR_FAILED); | |
| 222 return; | |
| 223 } | |
| 224 | |
| 225 const std::string plugin_id = GeneratePluginId(); | |
| 226 if (plugin_id.empty()) { | |
| 227 SendReplyForIsolatedFileSystem(fsid, PP_ERROR_BADARGUMENT); | |
| 228 return; | |
| 229 } | |
| 230 | |
| 231 fs_context->OpenPluginPrivateFileSystem( | |
| 232 origin, fileapi::kFileSystemTypePluginPrivate, fsid, plugin_id, | |
| 233 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | |
| 234 base::Bind( | |
| 235 &PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete, | |
| 236 weak_factory_.GetWeakPtr(), fsid)); | |
| 237 } | |
| 238 | |
| 239 void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete( | |
| 240 const std::string& fsid, | |
| 241 base::PlatformFileError error) { | |
| 242 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); | |
| 243 if (pp_error == PP_OK) | |
| 244 opened_ = true; | |
| 245 SendReplyForIsolatedFileSystem(fsid, pp_error); | |
| 203 } | 246 } |
| 204 | 247 |
| 205 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( | 248 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem( |
| 206 ppapi::host::HostMessageContext* context, | 249 ppapi::host::HostMessageContext* context, |
| 207 const std::string& fsid, | 250 const std::string& fsid, |
| 208 PP_IsolatedFileSystemType_Private type) { | 251 PP_IsolatedFileSystemType_Private type) { |
| 209 // Do not allow multiple opens. | 252 // Do not allow multiple opens. |
| 210 if (called_open_) | 253 if (called_open_) |
| 211 return PP_ERROR_INPROGRESS; | 254 return PP_ERROR_INPROGRESS; |
| 212 called_open_ = true; | 255 called_open_ = true; |
| 213 | 256 |
| 214 // Do a sanity check. | 257 // Do a sanity check. |
| 215 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) | 258 if (!fileapi::ValidateIsolatedFileSystemId(fsid)) |
| 216 return PP_ERROR_BADARGUMENT; | 259 return PP_ERROR_BADARGUMENT; |
| 217 | 260 |
| 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; | 261 int render_process_id = 0; |
| 229 int unused; | 262 int unused; |
| 230 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), | 263 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(), |
| 231 &render_process_id, | 264 &render_process_id, |
| 232 &unused)) { | 265 &unused)) { |
| 266 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid); | |
| 233 return PP_ERROR_FAILED; | 267 return PP_ERROR_FAILED; |
| 234 } | 268 } |
| 269 | |
| 270 reply_context_ = context->MakeReplyMessageContext(); | |
| 235 BrowserThread::PostTaskAndReplyWithResult( | 271 BrowserThread::PostTaskAndReplyWithResult( |
| 236 BrowserThread::UI, | 272 BrowserThread::UI, |
| 237 FROM_HERE, | 273 FROM_HERE, |
| 238 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), | 274 base::Bind(&GetFileSystemContextFromRenderId, render_process_id), |
| 239 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, | 275 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext, |
| 240 weak_factory_.GetWeakPtr(), | 276 weak_factory_.GetWeakPtr(), fsid, type)); |
| 241 context->MakeReplyMessageContext())); | |
| 242 return PP_OK_COMPLETIONPENDING; | 277 return PP_OK_COMPLETIONPENDING; |
| 243 } | 278 } |
| 244 | 279 |
| 280 void PepperFileSystemBrowserHost::SendReplyForIsolatedFileSystem( | |
| 281 const std::string& fsid, | |
| 282 int32_t error) { | |
| 283 if (error != PP_OK) | |
| 284 fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid); | |
| 285 reply_context_.params.set_result(error); | |
| 286 host()->SendReply(reply_context_, | |
| 287 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply()); | |
| 288 } | |
| 289 | |
| 290 std::string PepperFileSystemBrowserHost::GeneratePluginId() { | |
| 291 base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath(); | |
| 292 PepperPluginInfo* info = | |
| 293 PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path); | |
| 294 if (!info || info->mime_types.empty()) | |
| 295 return std::string(); | |
| 296 | |
| 297 // Use the first element in |info->mime_types| even if several elements exist. | |
| 298 std::string output = info->mime_types[0].mime_type; | |
| 299 if (!net::IsMimeType(output)) | |
| 300 return std::string(); | |
| 301 | |
| 302 // Replace a slash used for type/subtype separator with an underscore. | |
| 303 // NOTE: This assumes there is only one slash in the MIME type. | |
| 304 ReplaceFirstSubstringAfterOffset(&output, 0, "/", "_"); | |
| 305 | |
| 306 // Verify |output| contains only alphabets, digits, or "._-". | |
| 307 for (std::string::const_iterator it = output.begin(); | |
| 308 it != output.end(); ++it) { | |
| 309 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && | |
| 310 *it != '.' && *it != '_' && *it != '-') { | |
| 311 LOG(WARNING) << "Failed to generate a plugin id."; | |
| 312 return std::string(); | |
| 313 } | |
| 314 } | |
| 315 return output; | |
| 316 } | |
| 317 | |
| 245 } // namespace content | 318 } // namespace content |
| OLD | NEW |