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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" 6 7 #include "chrome/browser/extensions/extension_prefs.h" 8 #include "content/public/browser/child_process_security_policy.h" 9 #include "net/base/mime_util.h" 10 #include "webkit/browser/fileapi/isolated_context.h" 11 #include "webkit/common/fileapi/file_system_types.h" 12 13 namespace extensions { 14 15 namespace app_file_handler_util { 16 17 namespace { 18 19 bool FileHandlerCanHandleFileWithExtension( 20 const FileHandlerInfo& handler, 21 const base::FilePath& path) { 22 for (std::set<std::string>::const_iterator extension = 23 handler.extensions.begin(); 24 extension != handler.extensions.end(); ++extension) { 25 if (*extension == "*") 26 return true; 27 28 if (path.MatchesExtension( 29 base::FilePath::kExtensionSeparator + 30 base::FilePath::FromUTF8Unsafe(*extension).value())) { 31 return true; 32 } 33 34 // Also accept files with no extension for handlers that support an 35 // empty extension, i.e. both "foo" and "foo." match. 36 if (extension->empty() && 37 path.MatchesExtension(base::FilePath::StringType())) { 38 return true; 39 } 40 } 41 return false; 42 } 43 44 bool FileHandlerCanHandleFileWithMimeType( 45 const FileHandlerInfo& handler, 46 const std::string& mime_type) { 47 for (std::set<std::string>::const_iterator type = handler.types.begin(); 48 type != handler.types.end(); ++type) { 49 if (net::MatchesMimeType(*type, mime_type)) 50 return true; 51 } 52 return false; 53 } 54 55 } // namespace 56 57 typedef std::vector<FileHandlerInfo> FileHandlerList; 58 59 const FileHandlerInfo* FileHandlerForId(const Extension& app, 60 const std::string& handler_id) { 61 const FileHandlerList* file_handlers = FileHandlers::GetFileHandlers(&app); 62 if (!file_handlers) 63 return NULL; 64 65 for (FileHandlerList::const_iterator i = file_handlers->begin(); 66 i != file_handlers->end(); i++) { 67 if (i->id == handler_id) 68 return &*i; 69 } 70 return NULL; 71 } 72 73 const FileHandlerInfo* FirstFileHandlerForFile( 74 const Extension& app, 75 const std::string& mime_type, 76 const base::FilePath& path) { 77 const FileHandlerList* file_handlers = FileHandlers::GetFileHandlers(&app); 78 if (!file_handlers) 79 return NULL; 80 81 for (FileHandlerList::const_iterator i = file_handlers->begin(); 82 i != file_handlers->end(); i++) { 83 if (FileHandlerCanHandleFile(*i, mime_type, path)) 84 return &*i; 85 } 86 return NULL; 87 } 88 89 std::vector<const FileHandlerInfo*> FindFileHandlersForFiles( 90 const Extension& app, const PathAndMimeTypeSet& files) { 91 std::vector<const FileHandlerInfo*> handlers; 92 if (files.empty()) 93 return handlers; 94 95 // Look for file handlers which can handle all the MIME types specified. 96 const FileHandlerList* file_handlers = FileHandlers::GetFileHandlers(&app); 97 if (!file_handlers) 98 return handlers; 99 100 for (FileHandlerList::const_iterator data = file_handlers->begin(); 101 data != file_handlers->end(); ++data) { 102 bool handles_all_types = true; 103 for (PathAndMimeTypeSet::const_iterator it = files.begin(); 104 it != files.end(); ++it) { 105 if (!FileHandlerCanHandleFile(*data, it->second, it->first)) { 106 handles_all_types = false; 107 break; 108 } 109 } 110 if (handles_all_types) 111 handlers.push_back(&*data); 112 } 113 return handlers; 114 } 115 116 bool FileHandlerCanHandleFile( 117 const FileHandlerInfo& handler, 118 const std::string& mime_type, 119 const base::FilePath& path) { 120 return FileHandlerCanHandleFileWithMimeType(handler, mime_type) || 121 FileHandlerCanHandleFileWithExtension(handler, path); 122 } 123 124 GrantedFileEntry CreateFileEntry( 125 Profile* profile, 126 const std::string& extension_id, 127 int renderer_id, 128 const base::FilePath& path, 129 bool writable) { 130 GrantedFileEntry result; 131 fileapi::IsolatedContext* isolated_context = 132 fileapi::IsolatedContext::GetInstance(); 133 DCHECK(isolated_context); 134 135 result.filesystem_id = isolated_context->RegisterFileSystemForPath( 136 fileapi::kFileSystemTypeNativeForPlatformApp, path, 137 &result.registered_name); 138 139 content::ChildProcessSecurityPolicy* policy = 140 content::ChildProcessSecurityPolicy::GetInstance(); 141 policy->GrantReadFileSystem(renderer_id, result.filesystem_id); 142 if (writable) 143 policy->GrantWriteFileSystem(renderer_id, result.filesystem_id); 144 145 result.id = result.filesystem_id + ":" + result.registered_name; 146 return result; 147 } 148 149 } // namespace app_file_handler_util 150 151 } // namespace extensions 152