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