Home | History | Annotate | Download | only in renderer
      1 // Copyright 2014 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 "extensions/renderer/file_system_natives.h"
      6 
      7 #include <string>
      8 
      9 #include "extensions/common/constants.h"
     10 #include "extensions/renderer/script_context.h"
     11 #include "third_party/WebKit/public/platform/WebString.h"
     12 #include "third_party/WebKit/public/web/WebDOMError.h"
     13 #include "third_party/WebKit/public/web/WebDOMFileSystem.h"
     14 #include "third_party/WebKit/public/web/WebLocalFrame.h"
     15 #include "webkit/common/fileapi/file_system_types.h"
     16 #include "webkit/common/fileapi/file_system_util.h"
     17 
     18 namespace extensions {
     19 
     20 FileSystemNatives::FileSystemNatives(ScriptContext* context)
     21     : ObjectBackedNativeHandler(context) {
     22   RouteFunction(
     23       "GetFileEntry",
     24       base::Bind(&FileSystemNatives::GetFileEntry, base::Unretained(this)));
     25   RouteFunction("GetIsolatedFileSystem",
     26                 base::Bind(&FileSystemNatives::GetIsolatedFileSystem,
     27                            base::Unretained(this)));
     28   RouteFunction("CrackIsolatedFileSystemName",
     29                 base::Bind(&FileSystemNatives::CrackIsolatedFileSystemName,
     30                            base::Unretained(this)));
     31   RouteFunction(
     32       "GetDOMError",
     33       base::Bind(&FileSystemNatives::GetDOMError, base::Unretained(this)));
     34 }
     35 
     36 void FileSystemNatives::GetIsolatedFileSystem(
     37     const v8::FunctionCallbackInfo<v8::Value>& args) {
     38   DCHECK(args.Length() == 1 || args.Length() == 2);
     39   DCHECK(args[0]->IsString());
     40   std::string file_system_id(*v8::String::Utf8Value(args[0]));
     41   blink::WebLocalFrame* webframe =
     42       blink::WebLocalFrame::frameForContext(context()->v8_context());
     43   DCHECK(webframe);
     44 
     45   GURL context_url =
     46       extensions::ScriptContext::GetDataSourceURLForFrame(webframe);
     47   CHECK(context_url.SchemeIs(extensions::kExtensionScheme));
     48 
     49   std::string name(fileapi::GetIsolatedFileSystemName(context_url.GetOrigin(),
     50                                                       file_system_id));
     51 
     52   // The optional second argument is the subfolder within the isolated file
     53   // system at which to root the DOMFileSystem we're returning to the caller.
     54   std::string optional_root_name;
     55   if (args.Length() == 2) {
     56     DCHECK(args[1]->IsString());
     57     optional_root_name = *v8::String::Utf8Value(args[1]);
     58   }
     59 
     60   GURL root_url(fileapi::GetIsolatedFileSystemRootURIString(
     61       context_url.GetOrigin(), file_system_id, optional_root_name));
     62 
     63   args.GetReturnValue().Set(
     64       blink::WebDOMFileSystem::create(webframe,
     65                                       blink::WebFileSystemTypeIsolated,
     66                                       blink::WebString::fromUTF8(name),
     67                                       root_url)
     68           .toV8Value(args.Holder(), args.GetIsolate()));
     69 }
     70 
     71 void FileSystemNatives::GetFileEntry(
     72     const v8::FunctionCallbackInfo<v8::Value>& args) {
     73   DCHECK(args.Length() == 5);
     74   DCHECK(args[0]->IsString());
     75   std::string type_string = *v8::String::Utf8Value(args[0]->ToString());
     76   blink::WebFileSystemType type;
     77   bool is_valid_type = fileapi::GetFileSystemPublicType(type_string, &type);
     78   DCHECK(is_valid_type);
     79   if (is_valid_type == false) {
     80     return;
     81   }
     82 
     83   DCHECK(args[1]->IsString());
     84   DCHECK(args[2]->IsString());
     85   DCHECK(args[3]->IsString());
     86   std::string file_system_name(*v8::String::Utf8Value(args[1]->ToString()));
     87   GURL file_system_root_url(*v8::String::Utf8Value(args[2]->ToString()));
     88   std::string file_path_string(*v8::String::Utf8Value(args[3]->ToString()));
     89   base::FilePath file_path = base::FilePath::FromUTF8Unsafe(file_path_string);
     90   DCHECK(fileapi::VirtualPath::IsAbsolute(file_path.value()));
     91 
     92   DCHECK(args[4]->IsBoolean());
     93   blink::WebDOMFileSystem::EntryType entry_type =
     94       args[4]->BooleanValue() ? blink::WebDOMFileSystem::EntryTypeDirectory
     95                               : blink::WebDOMFileSystem::EntryTypeFile;
     96 
     97   blink::WebLocalFrame* webframe =
     98       blink::WebLocalFrame::frameForContext(context()->v8_context());
     99   DCHECK(webframe);
    100   args.GetReturnValue().Set(
    101       blink::WebDOMFileSystem::create(
    102           webframe,
    103           type,
    104           blink::WebString::fromUTF8(file_system_name),
    105           file_system_root_url)
    106           .createV8Entry(blink::WebString::fromUTF8(file_path_string),
    107                          entry_type,
    108                          args.Holder(),
    109                          args.GetIsolate()));
    110 }
    111 
    112 void FileSystemNatives::CrackIsolatedFileSystemName(
    113     const v8::FunctionCallbackInfo<v8::Value>& args) {
    114   DCHECK_EQ(args.Length(), 1);
    115   DCHECK(args[0]->IsString());
    116   std::string filesystem_name = *v8::String::Utf8Value(args[0]->ToString());
    117   std::string filesystem_id;
    118   if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id))
    119     return;
    120 
    121   args.GetReturnValue().Set(v8::String::NewFromUtf8(args.GetIsolate(),
    122                                                     filesystem_id.c_str(),
    123                                                     v8::String::kNormalString,
    124                                                     filesystem_id.size()));
    125 }
    126 
    127 void FileSystemNatives::GetDOMError(
    128     const v8::FunctionCallbackInfo<v8::Value>& args) {
    129   if (args.Length() != 2) {
    130     NOTREACHED();
    131     return;
    132   }
    133   if (!args[0]->IsString()) {
    134     NOTREACHED();
    135     return;
    136   }
    137   if (!args[1]->IsString()) {
    138     NOTREACHED();
    139     return;
    140   }
    141 
    142   std::string name(*v8::String::Utf8Value(args[0]));
    143   if (name.empty()) {
    144     NOTREACHED();
    145     return;
    146   }
    147   std::string message(*v8::String::Utf8Value(args[1]));
    148   // message is optional hence empty is fine.
    149 
    150   blink::WebDOMError dom_error = blink::WebDOMError::create(
    151       blink::WebString::fromUTF8(name), blink::WebString::fromUTF8(message));
    152   args.GetReturnValue().Set(
    153       dom_error.toV8Value(args.Holder(), args.GetIsolate()));
    154 }
    155 
    156 }  // namespace extensions
    157