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

Side by Side Diff: content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc

Issue 26803004: PPAPI: Add PluginPrivateFileSystem (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review fix and remove ChromeOS check Created 7 years, 1 month 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 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
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
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();
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::GeneratePluginId() const {
297 // TODO(nhiroki): This function is very specialized for specific plugins (MIME
298 // types). If we bring this API to stable, we might have to make it more
299 // general.
300
301 base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath();
302 PepperPluginInfo* info =
303 PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path);
304 if (!info || info->mime_types.empty())
305 return std::string();
306
307 // Use the first element in |info->mime_types| even if several elements exist.
308 std::string output = info->mime_types[0].mime_type;
309 if (!net::IsMimeType(output))
310 return std::string();
311
312 // Replace a slash used for type/subtype separator with an underscore.
313 // NOTE: This assumes there is only one slash in the MIME type.
314 ReplaceFirstSubstringAfterOffset(&output, 0, "/", "_");
315
316 // Verify |output| contains only alphabets, digits, or "._-".
317 for (std::string::const_iterator it = output.begin();
Tom Sepez 2013/11/18 19:12:29 What if the string is entirely dots, eg. "." or ".
nhiroki 2013/11/19 12:15:59 These cases would be covered by IsMimeType(). It m
Tom Sepez 2013/11/19 18:20:39 feels frail if this changes down the road, but OK.
318 it != output.end(); ++it) {
319 if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) &&
320 *it != '.' && *it != '_' && *it != '-') {
321 LOG(WARNING) << "Failed to generate a plugin id.";
322 return std::string();
323 }
324 }
325 return output;
326 }
327
245 } // namespace content 328 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698