Home | History | Annotate | Download | only in file_handlers
      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