OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "native_client/src/trusted/plugin/pnacl_resources.h" | 5 #include "native_client/src/trusted/plugin/pnacl_resources.h" |
6 | 6 |
7 #include "native_client/src/include/portability_io.h" | 7 #include "native_client/src/include/portability_io.h" |
8 #include "native_client/src/shared/platform/nacl_check.h" | 8 #include "native_client/src/shared/platform/nacl_check.h" |
9 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 9 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 10 #include "native_client/src/trusted/plugin/file_utils.h" |
10 #include "native_client/src/trusted/plugin/manifest.h" | 11 #include "native_client/src/trusted/plugin/manifest.h" |
11 #include "native_client/src/trusted/plugin/plugin.h" | 12 #include "native_client/src/trusted/plugin/plugin.h" |
12 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" | 13 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" |
13 #include "native_client/src/trusted/plugin/utility.h" | 14 #include "native_client/src/trusted/plugin/utility.h" |
14 | |
15 #include "ppapi/c/pp_errors.h" | 15 #include "ppapi/c/pp_errors.h" |
| 16 #include "third_party/jsoncpp/source/include/json/reader.h" |
| 17 #include "third_party/jsoncpp/source/include/json/value.h" |
16 | 18 |
17 namespace plugin { | 19 namespace plugin { |
18 | 20 |
19 static const char kPnaclComponentScheme[] = | 21 static const char kPnaclComponentScheme[] = "pnacl-component://"; |
20 "pnacl-component://"; | 22 const char PnaclUrls::kResourceInfoUrl[] = "pnacl.json"; |
21 const char PnaclUrls::kLlcUrl[] = "llc.nexe"; | 23 |
22 const char PnaclUrls::kLdUrl[] = "ld.nexe"; | 24 const char PnaclResources::kDefaultLlcName[] = "llc.nexe"; |
| 25 const char PnaclResources::kDefaultLdName[] = "ld.nexe"; |
23 | 26 |
24 nacl::string PnaclUrls::GetBaseUrl() { | 27 nacl::string PnaclUrls::GetBaseUrl() { |
25 return nacl::string(kPnaclComponentScheme) + GetSandboxISA() + "/"; | 28 return nacl::string(kPnaclComponentScheme); |
| 29 } |
| 30 |
| 31 nacl::string PnaclUrls::PrependPlatformPrefix(const nacl::string& url) { |
| 32 return nacl::string(GetSandboxISA()) + "/" + url; |
26 } | 33 } |
27 | 34 |
28 // Determine if a URL is for a pnacl-component file, or if it is some other | 35 // Determine if a URL is for a pnacl-component file, or if it is some other |
29 // type of URL (e.g., http://, https://, chrome-extension://). | 36 // type of URL (e.g., http://, https://, chrome-extension://). |
30 // The URL could be one of the other variants for shared libraries | 37 // The URL could be one of the other variants for shared libraries |
31 // served from the web. | 38 // served from the web. |
32 bool PnaclUrls::IsPnaclComponent(const nacl::string& full_url) { | 39 bool PnaclUrls::IsPnaclComponent(const nacl::string& full_url) { |
33 return full_url.find(kPnaclComponentScheme, 0) == 0; | 40 return full_url.find(kPnaclComponentScheme, 0) == 0; |
34 } | 41 } |
35 | 42 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 #else | 92 #else |
86 return file_handle; | 93 return file_handle; |
87 #endif | 94 #endif |
88 } | 95 } |
89 | 96 |
90 nacl::DescWrapper* PnaclResources::WrapperForUrl(const nacl::string& url) { | 97 nacl::DescWrapper* PnaclResources::WrapperForUrl(const nacl::string& url) { |
91 CHECK(resource_wrappers_.find(url) != resource_wrappers_.end()); | 98 CHECK(resource_wrappers_.find(url) != resource_wrappers_.end()); |
92 return resource_wrappers_[url]; | 99 return resource_wrappers_[url]; |
93 } | 100 } |
94 | 101 |
95 void PnaclResources::StartLoad() { | 102 void PnaclResources::ReadResourceInfo( |
| 103 const nacl::string& resource_info_url, |
| 104 const pp::CompletionCallback& resource_info_read_cb) { |
| 105 PLUGIN_PRINTF(("PnaclResources::ReadResourceInfo\n")); |
| 106 |
| 107 nacl::string full_url; |
| 108 ErrorInfo error_info; |
| 109 if (!manifest_->ResolveURL(resource_info_url, &full_url, &error_info)) { |
| 110 ReadResourceInfoError(nacl::string("failed to resolve ") + |
| 111 resource_info_url + ": " + |
| 112 error_info.message() + "."); |
| 113 return; |
| 114 } |
| 115 PLUGIN_PRINTF(("Resolved resources info url: %s\n", full_url.c_str())); |
| 116 nacl::string resource_info_filename = |
| 117 PnaclUrls::PnaclComponentURLToFilename(full_url); |
| 118 |
| 119 PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n", |
| 120 resource_info_filename.c_str())); |
| 121 |
| 122 int32_t fd = GetPnaclFD(plugin_, resource_info_filename.c_str()); |
| 123 if (fd < 0) { |
| 124 ReadResourceInfoError( |
| 125 nacl::string("PnaclResources::ReadResourceInfo failed for: ") + |
| 126 resource_info_filename); |
| 127 return; |
| 128 } |
| 129 |
| 130 nacl::string json_buffer; |
| 131 file_utils::StatusCode status = file_utils::SlurpFile(fd, json_buffer); |
| 132 if (status != file_utils::PLUGIN_FILE_SUCCESS) { |
| 133 ReadResourceInfoError( |
| 134 nacl::string("PnaclResources::ReadResourceInfo reading " |
| 135 "failed for: ") + resource_info_filename); |
| 136 return; |
| 137 } |
| 138 |
| 139 // Finally, we have the resource info JSON data in json_buffer. |
| 140 PLUGIN_PRINTF(("Resource info JSON data:\n%s\n", json_buffer.c_str())); |
| 141 nacl::string error_message; |
| 142 if (!ParseResourceInfo(json_buffer, error_message)) { |
| 143 ReadResourceInfoError(nacl::string("Parsing resource info failed: ") + |
| 144 error_message + "\n"); |
| 145 return; |
| 146 } |
| 147 |
| 148 // Done. Queue the completion callback. |
| 149 pp::Core* core = pp::Module::Get()->core(); |
| 150 core->CallOnMainThread(0, resource_info_read_cb, PP_OK); |
| 151 } |
| 152 |
| 153 void PnaclResources::ReadResourceInfoError(const nacl::string& msg) { |
| 154 coordinator_->ReportNonPpapiError(ERROR_PNACL_RESOURCE_FETCH, msg); |
| 155 } |
| 156 |
| 157 bool PnaclResources::ParseResourceInfo(const nacl::string& buf, |
| 158 nacl::string& errmsg) { |
| 159 // Expect the JSON file to contain a top-level object (dictionary). |
| 160 Json::Reader json_reader; |
| 161 Json::Value json_data; |
| 162 if (!json_reader.parse(buf, json_data)) { |
| 163 errmsg = nacl::string("JSON parse error: ") + |
| 164 json_reader.getFormatedErrorMessages(); |
| 165 return false; |
| 166 } |
| 167 |
| 168 if (!json_data.isObject()) { |
| 169 errmsg = nacl::string("Malformed JSON dictionary"); |
| 170 return false; |
| 171 } |
| 172 |
| 173 if (json_data.isMember("pnacl-llc-name")) { |
| 174 Json::Value json_name = json_data["pnacl-llc-name"]; |
| 175 if (json_name.isString()) { |
| 176 llc_tool_name = json_name.asString(); |
| 177 PLUGIN_PRINTF(("Set llc_tool_name=%s\n", llc_tool_name.c_str())); |
| 178 } |
| 179 } |
| 180 |
| 181 if (json_data.isMember("pnacl-ld-name")) { |
| 182 Json::Value json_name = json_data["pnacl-ld-name"]; |
| 183 if (json_name.isString()) { |
| 184 ld_tool_name = json_name.asString(); |
| 185 PLUGIN_PRINTF(("Set ld_tool_name=%s\n", ld_tool_name.c_str())); |
| 186 } |
| 187 } |
| 188 |
| 189 return true; |
| 190 } |
| 191 |
| 192 void PnaclResources::StartLoad( |
| 193 const pp::CompletionCallback& all_loaded_callback) { |
96 PLUGIN_PRINTF(("PnaclResources::StartLoad\n")); | 194 PLUGIN_PRINTF(("PnaclResources::StartLoad\n")); |
97 | 195 |
98 CHECK(resource_urls_.size() > 0); | 196 std::vector<nacl::string> resource_urls; |
| 197 resource_urls.push_back(GetLlcUrl()); |
| 198 resource_urls.push_back(GetLdUrl()); |
| 199 |
99 PLUGIN_PRINTF(("PnaclResources::StartLoad -- local install of PNaCl.\n")); | 200 PLUGIN_PRINTF(("PnaclResources::StartLoad -- local install of PNaCl.\n")); |
100 // Do a blocking load of each of the resources. | 201 // Do a blocking load of each of the resources. |
101 int32_t result = PP_OK; | 202 int32_t result = PP_OK; |
102 for (size_t i = 0; i < resource_urls_.size(); ++i) { | 203 for (size_t i = 0; i < resource_urls.size(); ++i) { |
103 const nacl::string& url = resource_urls_[i]; | 204 const nacl::string& url_with_platform_prefix = |
| 205 PnaclUrls::PrependPlatformPrefix(resource_urls[i]); |
104 nacl::string full_url; | 206 nacl::string full_url; |
105 ErrorInfo error_info; | 207 ErrorInfo error_info; |
106 if (!manifest_->ResolveURL(resource_urls_[i], &full_url, &error_info)) { | 208 if (!manifest_->ResolveURL(url_with_platform_prefix, &full_url, |
| 209 &error_info)) { |
107 coordinator_->ReportNonPpapiError( | 210 coordinator_->ReportNonPpapiError( |
108 ERROR_PNACL_RESOURCE_FETCH, | 211 ERROR_PNACL_RESOURCE_FETCH, |
109 nacl::string("failed to resolve ") + | 212 nacl::string("failed to resolve ") + |
110 url + ": " + | 213 url_with_platform_prefix + ": " + |
111 error_info.message() + "."); | 214 error_info.message() + "."); |
112 break; | 215 break; |
113 } | 216 } |
114 nacl::string filename = PnaclUrls::PnaclComponentURLToFilename(full_url); | 217 nacl::string filename = PnaclUrls::PnaclComponentURLToFilename(full_url); |
115 | 218 |
116 int32_t fd = PnaclResources::GetPnaclFD(plugin_, filename.c_str()); | 219 int32_t fd = PnaclResources::GetPnaclFD(plugin_, filename.c_str()); |
117 if (fd < 0) { | 220 if (fd < 0) { |
118 coordinator_->ReportNonPpapiError( | 221 coordinator_->ReportNonPpapiError( |
119 ERROR_PNACL_RESOURCE_FETCH, | 222 ERROR_PNACL_RESOURCE_FETCH, |
120 nacl::string("PnaclLocalResources::StartLoad failed for: ") + | 223 nacl::string("PnaclResources::StartLoad failed for: ") + |
121 filename + " (PNaCl not installed? Check chrome://nacl)"); | 224 filename + " (PNaCl not installed? Check chrome://nacl)"); |
122 result = PP_ERROR_FILENOTFOUND; | 225 result = PP_ERROR_FILENOTFOUND; |
123 break; | 226 break; |
124 } else { | 227 } else { |
125 resource_wrappers_[url] = | 228 resource_wrappers_[resource_urls[i]] = |
126 plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY); | 229 plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY); |
127 } | 230 } |
128 } | 231 } |
129 // We're done! Queue the callback. | 232 // We're done! Queue the callback. |
130 pp::Core* core = pp::Module::Get()->core(); | 233 pp::Core* core = pp::Module::Get()->core(); |
131 core->CallOnMainThread(0, all_loaded_callback_, result); | 234 core->CallOnMainThread(0, all_loaded_callback, result); |
132 } | 235 } |
133 | 236 |
134 } // namespace plugin | 237 } // namespace plugin |
OLD | NEW |