| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "webkit/glue/plugins/plugin_host.h" | |
| 6 | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/scoped_ptr.h" | |
| 10 #include "base/string_piece.h" | |
| 11 #include "base/string_util.h" | |
| 12 #if defined(OS_MACOSX) | |
| 13 #include "base/sys_info.h" | |
| 14 #endif | |
| 15 #include "base/sys_string_conversions.h" | |
| 16 #include "base/utf_string_conversions.h" | |
| 17 #include "net/base/net_util.h" | |
| 18 #include "third_party/npapi/bindings/npapi_extensions.h" | |
| 19 #include "third_party/npapi/bindings/npruntime.h" | |
| 20 #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" | |
| 21 #include "third_party/WebKit/WebKit/chromium/public/WebKit.h" | |
| 22 #include "webkit/glue/webkit_glue.h" | |
| 23 #include "webkit/glue/plugins/default_plugin_shared.h" | |
| 24 #include "webkit/glue/plugins/npapi_extension_thunk.h" | |
| 25 #include "webkit/glue/plugins/plugin_instance.h" | |
| 26 #include "webkit/glue/plugins/plugin_lib.h" | |
| 27 #include "webkit/glue/plugins/plugin_list.h" | |
| 28 #include "webkit/glue/plugins/plugin_stream_url.h" | |
| 29 #include "webkit/glue/plugins/webplugin_delegate.h" | |
| 30 #include "webkit/glue/plugins/webplugininfo.h" | |
| 31 | |
| 32 using WebKit::WebBindings; | |
| 33 | |
| 34 // Finds a PluginInstance from an NPP. | |
| 35 // The caller must take a reference if needed. | |
| 36 static NPAPI::PluginInstance* FindInstance(NPP id) { | |
| 37 if (id == NULL) { | |
| 38 return NULL; | |
| 39 } | |
| 40 return reinterpret_cast<NPAPI::PluginInstance*>(id->ndata); | |
| 41 } | |
| 42 | |
| 43 #if defined(OS_MACOSX) | |
| 44 // Returns true if the OS supports shared accelerated surfaces via IOSurface. | |
| 45 // This is true on Snow Leopard and higher. | |
| 46 static bool SupportsSharingAcceleratedSurfaces() { | |
| 47 int32 major, minor, bugfix; | |
| 48 base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix); | |
| 49 return major > 10 || (major == 10 && minor > 5); | |
| 50 } | |
| 51 #endif | |
| 52 | |
| 53 namespace NPAPI { | |
| 54 | |
| 55 scoped_refptr<PluginHost> PluginHost::singleton_; | |
| 56 | |
| 57 PluginHost::PluginHost() { | |
| 58 InitializeHostFuncs(); | |
| 59 } | |
| 60 | |
| 61 PluginHost::~PluginHost() { | |
| 62 } | |
| 63 | |
| 64 PluginHost *PluginHost::Singleton() { | |
| 65 if (singleton_.get() == NULL) { | |
| 66 singleton_ = new PluginHost(); | |
| 67 } | |
| 68 | |
| 69 DCHECK(singleton_.get() != NULL); | |
| 70 return singleton_; | |
| 71 } | |
| 72 | |
| 73 void PluginHost::InitializeHostFuncs() { | |
| 74 memset(&host_funcs_, 0, sizeof(host_funcs_)); | |
| 75 host_funcs_.size = sizeof(host_funcs_); | |
| 76 host_funcs_.version = (NP_VERSION_MAJOR << 8) | (NP_VERSION_MINOR); | |
| 77 | |
| 78 // The "basic" functions | |
| 79 host_funcs_.geturl = &NPN_GetURL; | |
| 80 host_funcs_.posturl = &NPN_PostURL; | |
| 81 host_funcs_.requestread = &NPN_RequestRead; | |
| 82 host_funcs_.newstream = &NPN_NewStream; | |
| 83 host_funcs_.write = &NPN_Write; | |
| 84 host_funcs_.destroystream = &NPN_DestroyStream; | |
| 85 host_funcs_.status = &NPN_Status; | |
| 86 host_funcs_.uagent = &NPN_UserAgent; | |
| 87 host_funcs_.memalloc = &NPN_MemAlloc; | |
| 88 host_funcs_.memfree = &NPN_MemFree; | |
| 89 host_funcs_.memflush = &NPN_MemFlush; | |
| 90 host_funcs_.reloadplugins = &NPN_ReloadPlugins; | |
| 91 | |
| 92 // We don't implement java yet | |
| 93 host_funcs_.getJavaEnv = &NPN_GetJavaEnv; | |
| 94 host_funcs_.getJavaPeer = &NPN_GetJavaPeer; | |
| 95 | |
| 96 // Advanced functions we implement | |
| 97 host_funcs_.geturlnotify = &NPN_GetURLNotify; | |
| 98 host_funcs_.posturlnotify = &NPN_PostURLNotify; | |
| 99 host_funcs_.getvalue = &NPN_GetValue; | |
| 100 host_funcs_.setvalue = &NPN_SetValue; | |
| 101 host_funcs_.invalidaterect = &NPN_InvalidateRect; | |
| 102 host_funcs_.invalidateregion = &NPN_InvalidateRegion; | |
| 103 host_funcs_.forceredraw = &NPN_ForceRedraw; | |
| 104 | |
| 105 // These come from the Javascript Engine | |
| 106 host_funcs_.getstringidentifier = WebBindings::getStringIdentifier; | |
| 107 host_funcs_.getstringidentifiers = WebBindings::getStringIdentifiers; | |
| 108 host_funcs_.getintidentifier = WebBindings::getIntIdentifier; | |
| 109 host_funcs_.identifierisstring = WebBindings::identifierIsString; | |
| 110 host_funcs_.utf8fromidentifier = WebBindings::utf8FromIdentifier; | |
| 111 host_funcs_.intfromidentifier = WebBindings::intFromIdentifier; | |
| 112 host_funcs_.createobject = WebBindings::createObject; | |
| 113 host_funcs_.retainobject = WebBindings::retainObject; | |
| 114 host_funcs_.releaseobject = WebBindings::releaseObject; | |
| 115 host_funcs_.invoke = WebBindings::invoke; | |
| 116 host_funcs_.invokeDefault = WebBindings::invokeDefault; | |
| 117 host_funcs_.evaluate = WebBindings::evaluate; | |
| 118 host_funcs_.getproperty = WebBindings::getProperty; | |
| 119 host_funcs_.setproperty = WebBindings::setProperty; | |
| 120 host_funcs_.removeproperty = WebBindings::removeProperty; | |
| 121 host_funcs_.hasproperty = WebBindings::hasProperty; | |
| 122 host_funcs_.hasmethod = WebBindings::hasMethod; | |
| 123 host_funcs_.releasevariantvalue = WebBindings::releaseVariantValue; | |
| 124 host_funcs_.setexception = WebBindings::setException; | |
| 125 host_funcs_.pushpopupsenabledstate = NPN_PushPopupsEnabledState; | |
| 126 host_funcs_.poppopupsenabledstate = NPN_PopPopupsEnabledState; | |
| 127 host_funcs_.enumerate = WebBindings::enumerate; | |
| 128 host_funcs_.pluginthreadasynccall = NPN_PluginThreadAsyncCall; | |
| 129 host_funcs_.construct = WebBindings::construct; | |
| 130 host_funcs_.getvalueforurl = NPN_GetValueForURL; | |
| 131 host_funcs_.setvalueforurl = NPN_SetValueForURL; | |
| 132 host_funcs_.getauthenticationinfo = NPN_GetAuthenticationInfo; | |
| 133 host_funcs_.scheduletimer = NPN_ScheduleTimer; | |
| 134 host_funcs_.unscheduletimer = NPN_UnscheduleTimer; | |
| 135 host_funcs_.popupcontextmenu = NPN_PopUpContextMenu; | |
| 136 host_funcs_.convertpoint = NPN_ConvertPoint; | |
| 137 host_funcs_.handleevent = NPN_HandleEvent; | |
| 138 host_funcs_.unfocusinstance = NPN_UnfocusInstance; | |
| 139 host_funcs_.urlredirectresponse = NPN_URLRedirectResponse; | |
| 140 } | |
| 141 | |
| 142 void PluginHost::PatchNPNetscapeFuncs(NPNetscapeFuncs* overrides) { | |
| 143 // When running in the plugin process, we need to patch the NPN functions | |
| 144 // that the plugin calls to interact with NPObjects that we give. Otherwise | |
| 145 // the plugin will call the v8 NPN functions, which won't work since we have | |
| 146 // an NPObjectProxy and not a real v8 implementation. | |
| 147 if (overrides->invoke) | |
| 148 host_funcs_.invoke = overrides->invoke; | |
| 149 | |
| 150 if (overrides->invokeDefault) | |
| 151 host_funcs_.invokeDefault = overrides->invokeDefault; | |
| 152 | |
| 153 if (overrides->evaluate) | |
| 154 host_funcs_.evaluate = overrides->evaluate; | |
| 155 | |
| 156 if (overrides->getproperty) | |
| 157 host_funcs_.getproperty = overrides->getproperty; | |
| 158 | |
| 159 if (overrides->setproperty) | |
| 160 host_funcs_.setproperty = overrides->setproperty; | |
| 161 | |
| 162 if (overrides->removeproperty) | |
| 163 host_funcs_.removeproperty = overrides->removeproperty; | |
| 164 | |
| 165 if (overrides->hasproperty) | |
| 166 host_funcs_.hasproperty = overrides->hasproperty; | |
| 167 | |
| 168 if (overrides->hasmethod) | |
| 169 host_funcs_.hasmethod = overrides->hasmethod; | |
| 170 | |
| 171 if (overrides->setexception) | |
| 172 host_funcs_.setexception = overrides->setexception; | |
| 173 | |
| 174 if (overrides->enumerate) | |
| 175 host_funcs_.enumerate = overrides->enumerate; | |
| 176 } | |
| 177 | |
| 178 bool PluginHost::SetPostData(const char* buf, | |
| 179 uint32 length, | |
| 180 std::vector<std::string>* names, | |
| 181 std::vector<std::string>* values, | |
| 182 std::vector<char>* body) { | |
| 183 // Use a state table to do the parsing. Whitespace must be | |
| 184 // trimmed after the fact if desired. In our case, we actually | |
| 185 // don't care about the whitespace, because we're just going to | |
| 186 // pass this back into another POST. This function strips out the | |
| 187 // "Content-length" header and does not append it to the request. | |
| 188 | |
| 189 // | |
| 190 // This parser takes action only on state changes. | |
| 191 // | |
| 192 // Transition table: | |
| 193 // : \n NULL Other | |
| 194 // 0 GetHeader 1 2 4 0 | |
| 195 // 1 GetValue 1 0 3 1 | |
| 196 // 2 GetData 2 2 3 2 | |
| 197 // 3 DONE | |
| 198 // 4 ERR | |
| 199 // | |
| 200 enum { INPUT_COLON=0, INPUT_NEWLINE, INPUT_NULL, INPUT_OTHER }; | |
| 201 enum { GETNAME, GETVALUE, GETDATA, DONE, ERR }; | |
| 202 int statemachine[3][4] = { { GETVALUE, GETDATA, GETDATA, GETNAME }, | |
| 203 { GETVALUE, GETNAME, DONE, GETVALUE }, | |
| 204 { GETDATA, GETDATA, DONE, GETDATA } }; | |
| 205 std::string name, value; | |
| 206 const char* ptr = static_cast<const char*>(buf); | |
| 207 const char* start = ptr; | |
| 208 int state = GETNAME; // initial state | |
| 209 bool done = false; | |
| 210 bool err = false; | |
| 211 do { | |
| 212 int input; | |
| 213 | |
| 214 // Translate the current character into an input | |
| 215 // for the state table. | |
| 216 switch (*ptr) { | |
| 217 case ':' : | |
| 218 input = INPUT_COLON; | |
| 219 break; | |
| 220 case '\n': | |
| 221 input = INPUT_NEWLINE; | |
| 222 break; | |
| 223 case 0 : | |
| 224 input = INPUT_NULL; | |
| 225 break; | |
| 226 default : | |
| 227 input = INPUT_OTHER; | |
| 228 break; | |
| 229 } | |
| 230 | |
| 231 int newstate = statemachine[state][input]; | |
| 232 | |
| 233 // Take action based on the new state. | |
| 234 if (state != newstate) { | |
| 235 switch (newstate) { | |
| 236 case GETNAME: | |
| 237 // Got a value. | |
| 238 value = std::string(start, ptr - start); | |
| 239 TrimWhitespace(value, TRIM_ALL, &value); | |
| 240 // If the name field is empty, we'll skip this header | |
| 241 // but we won't error out. | |
| 242 if (!name.empty() && name != "content-length") { | |
| 243 names->push_back(name); | |
| 244 values->push_back(value); | |
| 245 } | |
| 246 start = ptr + 1; | |
| 247 break; | |
| 248 case GETVALUE: | |
| 249 // Got a header. | |
| 250 name = StringToLowerASCII(std::string(start, ptr - start)); | |
| 251 TrimWhitespace(name, TRIM_ALL, &name); | |
| 252 start = ptr + 1; | |
| 253 break; | |
| 254 case GETDATA: { | |
| 255 // Finished headers, now get body | |
| 256 if (*ptr) | |
| 257 start = ptr + 1; | |
| 258 size_t previous_size = body->size(); | |
| 259 size_t new_body_size = length - static_cast<int>(start - buf); | |
| 260 body->resize(previous_size + new_body_size); | |
| 261 if (!body->empty()) | |
| 262 memcpy(&body->front() + previous_size, start, new_body_size); | |
| 263 done = true; | |
| 264 break; | |
| 265 } | |
| 266 case ERR: | |
| 267 // error | |
| 268 err = true; | |
| 269 done = true; | |
| 270 break; | |
| 271 } | |
| 272 } | |
| 273 state = newstate; | |
| 274 ptr++; | |
| 275 } while (!done); | |
| 276 | |
| 277 return !err; | |
| 278 } | |
| 279 | |
| 280 } // namespace NPAPI | |
| 281 | |
| 282 extern "C" { | |
| 283 | |
| 284 // Allocates memory from the host's memory space. | |
| 285 void* NPN_MemAlloc(uint32_t size) { | |
| 286 scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); | |
| 287 if (host != NULL) { | |
| 288 // Note: We must use the same allocator/deallocator | |
| 289 // that is used by the javascript library, as some of the | |
| 290 // JS APIs will pass memory to the plugin which the plugin | |
| 291 // will attempt to free. | |
| 292 return malloc(size); | |
| 293 } | |
| 294 return NULL; | |
| 295 } | |
| 296 | |
| 297 // Deallocates memory from the host's memory space | |
| 298 void NPN_MemFree(void* ptr) { | |
| 299 scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); | |
| 300 if (host != NULL) { | |
| 301 if (ptr != NULL && ptr != reinterpret_cast<void*>(-1)) | |
| 302 free(ptr); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 // Requests that the host free a specified amount of memory. | |
| 307 uint32_t NPN_MemFlush(uint32_t size) { | |
| 308 // This is not relevant on Windows; MAC specific | |
| 309 return size; | |
| 310 } | |
| 311 | |
| 312 // This is for dynamic discovery of new plugins. | |
| 313 // Should force a re-scan of the plugins directory to load new ones. | |
| 314 void NPN_ReloadPlugins(NPBool reload_pages) { | |
| 315 WebKit::resetPluginCache(reload_pages ? true : false); | |
| 316 } | |
| 317 | |
| 318 // Requests a range of bytes for a seekable stream. | |
| 319 NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { | |
| 320 if (!stream || !range_list) | |
| 321 return NPERR_GENERIC_ERROR; | |
| 322 | |
| 323 scoped_refptr<NPAPI::PluginInstance> plugin( | |
| 324 reinterpret_cast<NPAPI::PluginInstance*>(stream->ndata)); | |
| 325 if (!plugin.get()) | |
| 326 return NPERR_GENERIC_ERROR; | |
| 327 | |
| 328 plugin->RequestRead(stream, range_list); | |
| 329 return NPERR_NO_ERROR; | |
| 330 } | |
| 331 | |
| 332 // Generic form of GetURL for common code between GetURL and GetURLNotify. | |
| 333 static NPError GetURLNotify(NPP id, | |
| 334 const char* url, | |
| 335 const char* target, | |
| 336 bool notify, | |
| 337 void* notify_data) { | |
| 338 if (!url) | |
| 339 return NPERR_INVALID_URL; | |
| 340 | |
| 341 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 342 if (!plugin.get()) { | |
| 343 return NPERR_GENERIC_ERROR; | |
| 344 } | |
| 345 | |
| 346 plugin->RequestURL(url, "GET", target, NULL, 0, notify, notify_data); | |
| 347 return NPERR_NO_ERROR; | |
| 348 } | |
| 349 | |
| 350 // Requests creation of a new stream with the contents of the | |
| 351 // specified URL; gets notification of the result. | |
| 352 NPError NPN_GetURLNotify(NPP id, | |
| 353 const char* url, | |
| 354 const char* target, | |
| 355 void* notify_data) { | |
| 356 // This is identical to NPN_GetURL, but after finishing, the | |
| 357 // browser will call NPP_URLNotify to inform the plugin that | |
| 358 // it has completed. | |
| 359 | |
| 360 // According to the NPAPI documentation, if target == _self | |
| 361 // or a parent to _self, the browser should return NPERR_INVALID_PARAM, | |
| 362 // because it can't notify the plugin once deleted. This is | |
| 363 // absolutely false; firefox doesn't do this, and Flash relies on | |
| 364 // being able to use this. | |
| 365 | |
| 366 // Also according to the NPAPI documentation, we should return | |
| 367 // NPERR_INVALID_URL if the url requested is not valid. However, | |
| 368 // this would require that we synchronously start fetching the | |
| 369 // URL. That just isn't practical. As such, there really is | |
| 370 // no way to return this error. From looking at the Firefox | |
| 371 // implementation, it doesn't look like Firefox does this either. | |
| 372 | |
| 373 return GetURLNotify(id, url, target, true, notify_data); | |
| 374 } | |
| 375 | |
| 376 NPError NPN_GetURL(NPP id, const char* url, const char* target) { | |
| 377 // Notes: | |
| 378 // Request from the Plugin to fetch content either for the plugin | |
| 379 // or to be placed into a browser window. | |
| 380 // | |
| 381 // If target == null, the browser fetches content and streams to plugin. | |
| 382 // otherwise, the browser loads content into an existing browser frame. | |
| 383 // If the target is the window/frame containing the plugin, the plugin | |
| 384 // may be destroyed. | |
| 385 // If the target is _blank, a mailto: or news: url open content in a new | |
| 386 // browser window | |
| 387 // If the target is _self, no other instance of the plugin is created. The | |
| 388 // plugin continues to operate in its own window | |
| 389 | |
| 390 return GetURLNotify(id, url, target, false, 0); | |
| 391 } | |
| 392 | |
| 393 // Generic form of PostURL for common code between PostURL and PostURLNotify. | |
| 394 static NPError PostURLNotify(NPP id, | |
| 395 const char* url, | |
| 396 const char* target, | |
| 397 uint32_t len, | |
| 398 const char* buf, | |
| 399 NPBool file, | |
| 400 bool notify, | |
| 401 void* notify_data) { | |
| 402 if (!url) | |
| 403 return NPERR_INVALID_URL; | |
| 404 | |
| 405 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 406 if (!plugin.get()) { | |
| 407 NOTREACHED(); | |
| 408 return NPERR_GENERIC_ERROR; | |
| 409 } | |
| 410 | |
| 411 std::string post_file_contents; | |
| 412 | |
| 413 if (file) { | |
| 414 // Post data to be uploaded from a file. This can be handled in two | |
| 415 // ways. | |
| 416 // 1. Read entire file and send the contents as if it was a post data | |
| 417 // specified in the argument | |
| 418 // 2. Send just the file details and read them in the browser at the | |
| 419 // time of sending the request. | |
| 420 // Approach 2 is more efficient but complicated. Approach 1 has a major | |
| 421 // drawback of sending potentially large data over two IPC hops. In a way | |
| 422 // 'large data over IPC' problem exists as it is in case of plugin giving | |
| 423 // the data directly instead of in a file. | |
| 424 // Currently we are going with the approach 1 to get the feature working. | |
| 425 // We can optimize this later with approach 2. | |
| 426 | |
| 427 // TODO(joshia): Design a scheme to send a file descriptor instead of | |
| 428 // entire file contents across. | |
| 429 | |
| 430 // Security alert: | |
| 431 // --------------- | |
| 432 // Here we are blindly uploading whatever file requested by a plugin. | |
| 433 // This is risky as someone could exploit a plugin to send private | |
| 434 // data in arbitrary locations. | |
| 435 // A malicious (non-sandboxed) plugin has unfeterred access to OS | |
| 436 // resources and can do this anyway without using browser's HTTP stack. | |
| 437 // FWIW, Firefox and Safari don't perform any security checks. | |
| 438 | |
| 439 if (!buf) | |
| 440 return NPERR_FILE_NOT_FOUND; | |
| 441 | |
| 442 std::string file_path_ascii(buf); | |
| 443 FilePath file_path; | |
| 444 static const char kFileUrlPrefix[] = "file:"; | |
| 445 if (StartsWithASCII(file_path_ascii, kFileUrlPrefix, false)) { | |
| 446 GURL file_url(file_path_ascii); | |
| 447 DCHECK(file_url.SchemeIsFile()); | |
| 448 net::FileURLToFilePath(file_url, &file_path); | |
| 449 } else { | |
| 450 file_path = FilePath::FromWStringHack( | |
| 451 base::SysNativeMBToWide(file_path_ascii)); | |
| 452 } | |
| 453 | |
| 454 base::PlatformFileInfo post_file_info = {0}; | |
| 455 if (!file_util::GetFileInfo(file_path, &post_file_info) || | |
| 456 post_file_info.is_directory) | |
| 457 return NPERR_FILE_NOT_FOUND; | |
| 458 | |
| 459 if (!file_util::ReadFileToString(file_path, &post_file_contents)) | |
| 460 return NPERR_FILE_NOT_FOUND; | |
| 461 | |
| 462 buf = post_file_contents.c_str(); | |
| 463 len = post_file_contents.size(); | |
| 464 } | |
| 465 | |
| 466 // The post data sent by a plugin contains both headers | |
| 467 // and post data. Example: | |
| 468 // Content-type: text/html | |
| 469 // Content-length: 200 | |
| 470 // | |
| 471 // <200 bytes of content here> | |
| 472 // | |
| 473 // Unfortunately, our stream needs these broken apart, | |
| 474 // so we need to parse the data and set headers and data | |
| 475 // separately. | |
| 476 plugin->RequestURL(url, "POST", target, buf, len, notify, notify_data); | |
| 477 return NPERR_NO_ERROR; | |
| 478 } | |
| 479 | |
| 480 NPError NPN_PostURLNotify(NPP id, | |
| 481 const char* url, | |
| 482 const char* target, | |
| 483 uint32_t len, | |
| 484 const char* buf, | |
| 485 NPBool file, | |
| 486 void* notify_data) { | |
| 487 return PostURLNotify(id, url, target, len, buf, file, true, notify_data); | |
| 488 } | |
| 489 | |
| 490 NPError NPN_PostURL(NPP id, | |
| 491 const char* url, | |
| 492 const char* target, | |
| 493 uint32_t len, | |
| 494 const char* buf, | |
| 495 NPBool file) { | |
| 496 // POSTs data to an URL, either from a temp file or a buffer. | |
| 497 // If file is true, buf contains a temp file (which host will delete after | |
| 498 // completing), and len contains the length of the filename. | |
| 499 // If file is false, buf contains the data to send, and len contains the | |
| 500 // length of the buffer | |
| 501 // | |
| 502 // If target is null, | |
| 503 // server response is returned to the plugin | |
| 504 // If target is _current, _self, or _top, | |
| 505 // server response is written to the plugin window and plugin is unloaded. | |
| 506 // If target is _new or _blank, | |
| 507 // server response is written to a new browser window | |
| 508 // If target is an existing frame, | |
| 509 // server response goes to that frame. | |
| 510 // | |
| 511 // For protocols other than FTP | |
| 512 // file uploads must be line-end converted from \r\n to \n | |
| 513 // | |
| 514 // Note: you cannot specify headers (even a blank line) in a memory buffer, | |
| 515 // use NPN_PostURLNotify | |
| 516 | |
| 517 return PostURLNotify(id, url, target, len, buf, file, false, 0); | |
| 518 } | |
| 519 | |
| 520 NPError NPN_NewStream(NPP id, | |
| 521 NPMIMEType type, | |
| 522 const char* target, | |
| 523 NPStream** stream) { | |
| 524 // Requests creation of a new data stream produced by the plugin, | |
| 525 // consumed by the browser. | |
| 526 // | |
| 527 // Browser should put this stream into a window target. | |
| 528 // | |
| 529 // TODO: implement me | |
| 530 DVLOG(1) << "NPN_NewStream is not implemented yet."; | |
| 531 return NPERR_GENERIC_ERROR; | |
| 532 } | |
| 533 | |
| 534 int32_t NPN_Write(NPP id, NPStream* stream, int32_t len, void* buffer) { | |
| 535 // Writes data to an existing Plugin-created stream. | |
| 536 | |
| 537 // TODO: implement me | |
| 538 DVLOG(1) << "NPN_Write is not implemented yet."; | |
| 539 return NPERR_GENERIC_ERROR; | |
| 540 } | |
| 541 | |
| 542 NPError NPN_DestroyStream(NPP id, NPStream* stream, NPReason reason) { | |
| 543 // Destroys a stream (could be created by plugin or browser). | |
| 544 // | |
| 545 // Reasons: | |
| 546 // NPRES_DONE - normal completion | |
| 547 // NPRES_USER_BREAK - user terminated | |
| 548 // NPRES_NETWORK_ERROR - network error (all errors fit here?) | |
| 549 // | |
| 550 // | |
| 551 | |
| 552 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 553 if (plugin.get() == NULL) { | |
| 554 NOTREACHED(); | |
| 555 return NPERR_GENERIC_ERROR; | |
| 556 } | |
| 557 | |
| 558 return plugin->NPP_DestroyStream(stream, reason); | |
| 559 } | |
| 560 | |
| 561 const char* NPN_UserAgent(NPP id) { | |
| 562 #if defined(OS_WIN) | |
| 563 // Flash passes in a null id during the NP_initialize call. We need to | |
| 564 // default to the Mozilla user agent if we don't have an NPP instance or | |
| 565 // else Flash won't request windowless mode. | |
| 566 bool use_mozilla_user_agent = true; | |
| 567 if (id) { | |
| 568 scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); | |
| 569 if (plugin.get() && !plugin->use_mozilla_user_agent()) | |
| 570 use_mozilla_user_agent = false; | |
| 571 } | |
| 572 | |
| 573 if (use_mozilla_user_agent) | |
| 574 return "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a1) " | |
| 575 "Gecko/20061103 Firefox/2.0a1"; | |
| 576 #elif defined(OS_MACOSX) | |
| 577 // Silverlight 4 doesn't handle events correctly unless we claim to be Safari. | |
| 578 scoped_refptr<NPAPI::PluginInstance> plugin; | |
| 579 if (id) | |
| 580 plugin = FindInstance(id); | |
| 581 if (plugin.get()) { | |
| 582 WebPluginInfo plugin_info = plugin->plugin_lib()->plugin_info(); | |
| 583 if (plugin_info.name == ASCIIToUTF16("Silverlight Plug-In") && | |
| 584 StartsWith(plugin_info.version, ASCIIToUTF16("4."), false)) { | |
| 585 return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) " | |
| 586 "AppleWebKit/534.1+ (KHTML, like Gecko) Version/5.0 Safari/533.16"; | |
| 587 } | |
| 588 } | |
| 589 #endif | |
| 590 | |
| 591 return webkit_glue::GetUserAgent(GURL()).c_str(); | |
| 592 } | |
| 593 | |
| 594 void NPN_Status(NPP id, const char* message) { | |
| 595 // Displays a message on the status line of the browser window. | |
| 596 | |
| 597 // TODO: implement me | |
| 598 DVLOG(1) << "NPN_Status is not implemented yet."; | |
| 599 } | |
| 600 | |
| 601 void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { | |
| 602 // Invalidates specified drawing area prior to repainting or refreshing a | |
| 603 // windowless plugin | |
| 604 | |
| 605 // Before a windowless plugin can refresh part of its drawing area, it must | |
| 606 // first invalidate it. This function causes the NPP_HandleEvent method to | |
| 607 // pass an update event or a paint message to the plug-in. After calling | |
| 608 // this method, the plug-in recieves a paint message asynchronously. | |
| 609 | |
| 610 // The browser redraws invalid areas of the document and any windowless | |
| 611 // plug-ins at regularly timed intervals. To force a paint message, the | |
| 612 // plug-in can call NPN_ForceRedraw after calling this method. | |
| 613 | |
| 614 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 615 if (plugin.get() && plugin->webplugin()) { | |
| 616 if (invalidRect) { | |
| 617 #if defined(OS_WIN) | |
| 618 if (!plugin->windowless()) { | |
| 619 RECT rect = {0}; | |
| 620 rect.left = invalidRect->left; | |
| 621 rect.right = invalidRect->right; | |
| 622 rect.top = invalidRect->top; | |
| 623 rect.bottom = invalidRect->bottom; | |
| 624 ::InvalidateRect(plugin->window_handle(), &rect, false); | |
| 625 return; | |
| 626 } | |
| 627 #endif | |
| 628 gfx::Rect rect(invalidRect->left, | |
| 629 invalidRect->top, | |
| 630 invalidRect->right - invalidRect->left, | |
| 631 invalidRect->bottom - invalidRect->top); | |
| 632 plugin->webplugin()->InvalidateRect(rect); | |
| 633 } else { | |
| 634 plugin->webplugin()->Invalidate(); | |
| 635 } | |
| 636 } | |
| 637 } | |
| 638 | |
| 639 void NPN_InvalidateRegion(NPP id, NPRegion invalidRegion) { | |
| 640 // Invalidates a specified drawing region prior to repainting | |
| 641 // or refreshing a window-less plugin. | |
| 642 // | |
| 643 // Similar to NPN_InvalidateRect. | |
| 644 | |
| 645 // TODO: this is overkill--add platform-specific region handling (at the | |
| 646 // very least, fetch the region's bounding box and pass it to InvalidateRect). | |
| 647 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 648 DCHECK(plugin.get() != NULL); | |
| 649 if (plugin.get() && plugin->webplugin()) | |
| 650 plugin->webplugin()->Invalidate(); | |
| 651 } | |
| 652 | |
| 653 void NPN_ForceRedraw(NPP id) { | |
| 654 // Forces repaint for a windowless plug-in. | |
| 655 // | |
| 656 // We deliberately do not implement this; we don't want plugins forcing | |
| 657 // synchronous paints. | |
| 658 } | |
| 659 | |
| 660 NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { | |
| 661 // Allows the plugin to query the browser for information | |
| 662 // | |
| 663 // Variables: | |
| 664 // NPNVxDisplay (unix only) | |
| 665 // NPNVxtAppContext (unix only) | |
| 666 // NPNVnetscapeWindow (win only) - Gets the native window on which the | |
| 667 // plug-in drawing occurs, returns HWND | |
| 668 // NPNVjavascriptEnabledBool: tells whether Javascript is enabled | |
| 669 // NPNVasdEnabledBool: tells whether SmartUpdate is enabled | |
| 670 // NPNVOfflineBool: tells whether offline-mode is enabled | |
| 671 | |
| 672 NPError rv = NPERR_GENERIC_ERROR; | |
| 673 | |
| 674 switch (static_cast<int>(variable)) { | |
| 675 case NPNVWindowNPObject: { | |
| 676 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 677 NPObject *np_object = plugin->webplugin()->GetWindowScriptNPObject(); | |
| 678 // Return value is expected to be retained, as | |
| 679 // described here: | |
| 680 // <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess> | |
| 681 if (np_object) { | |
| 682 WebBindings::retainObject(np_object); | |
| 683 void **v = (void **)value; | |
| 684 *v = np_object; | |
| 685 rv = NPERR_NO_ERROR; | |
| 686 } else { | |
| 687 NOTREACHED(); | |
| 688 } | |
| 689 break; | |
| 690 } | |
| 691 case NPNVPluginElementNPObject: { | |
| 692 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 693 NPObject *np_object = plugin->webplugin()->GetPluginElement(); | |
| 694 // Return value is expected to be retained, as | |
| 695 // described here: | |
| 696 // <http://www.mozilla.org/projects/plugins/npruntime.html#browseraccess> | |
| 697 if (np_object) { | |
| 698 WebBindings::retainObject(np_object); | |
| 699 void** v = static_cast<void**>(value); | |
| 700 *v = np_object; | |
| 701 rv = NPERR_NO_ERROR; | |
| 702 } else { | |
| 703 NOTREACHED(); | |
| 704 } | |
| 705 break; | |
| 706 } | |
| 707 #if !defined(OS_MACOSX) // OS X doesn't have windowed plugins. | |
| 708 case NPNVnetscapeWindow: { | |
| 709 scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); | |
| 710 if (!plugin.get()) { | |
| 711 NOTREACHED(); | |
| 712 return NPERR_GENERIC_ERROR; | |
| 713 } | |
| 714 gfx::PluginWindowHandle handle = plugin->window_handle(); | |
| 715 *((void**)value) = (void*)handle; | |
| 716 rv = NPERR_NO_ERROR; | |
| 717 break; | |
| 718 } | |
| 719 #endif | |
| 720 case NPNVjavascriptEnabledBool: { | |
| 721 // yes, JS is enabled. | |
| 722 *((void**)value) = (void*)1; | |
| 723 rv = NPERR_NO_ERROR; | |
| 724 break; | |
| 725 } | |
| 726 #if defined(TOOLKIT_USES_GTK) | |
| 727 case NPNVToolkit: | |
| 728 // Tell them we are GTK2. (The alternative is GTK 1.2.) | |
| 729 *reinterpret_cast<int*>(value) = NPNVGtk2; | |
| 730 rv = NPERR_NO_ERROR; | |
| 731 break; | |
| 732 | |
| 733 case NPNVSupportsXEmbedBool: | |
| 734 *reinterpret_cast<NPBool*>(value) = true; | |
| 735 rv = NPERR_NO_ERROR; | |
| 736 break; | |
| 737 #endif | |
| 738 case NPNVSupportsWindowless: { | |
| 739 NPBool* supports_windowless = reinterpret_cast<NPBool*>(value); | |
| 740 *supports_windowless = true; | |
| 741 rv = NPERR_NO_ERROR; | |
| 742 break; | |
| 743 } | |
| 744 case NPNVprivateModeBool: { | |
| 745 NPBool* private_mode = reinterpret_cast<NPBool*>(value); | |
| 746 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 747 *private_mode = plugin->webplugin()->IsOffTheRecord(); | |
| 748 rv = NPERR_NO_ERROR; | |
| 749 break; | |
| 750 } | |
| 751 case default_plugin::kMissingPluginStatusStart + | |
| 752 default_plugin::MISSING_PLUGIN_AVAILABLE: | |
| 753 // fall through | |
| 754 case default_plugin::kMissingPluginStatusStart + | |
| 755 default_plugin::MISSING_PLUGIN_USER_STARTED_DOWNLOAD: { | |
| 756 // This is a hack for the default plugin to send notification to | |
| 757 // renderer. Even though we check if the plugin is the default plugin, | |
| 758 // we still need to worry about future standard change that may conflict | |
| 759 // with the variable definition, in order to avoid duplicate case clauses | |
| 760 // in this big switch statement. | |
| 761 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 762 if (plugin->plugin_lib()->plugin_info().path.value() == | |
| 763 kDefaultPluginLibraryName) { | |
| 764 plugin->webplugin()->OnMissingPluginStatus( | |
| 765 variable - default_plugin::kMissingPluginStatusStart); | |
| 766 } | |
| 767 break; | |
| 768 } | |
| 769 #if defined(OS_MACOSX) | |
| 770 case NPNVpluginDrawingModel: { | |
| 771 // return the drawing model that was negotiated when we initialized. | |
| 772 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 773 *reinterpret_cast<int*>(value) = plugin->drawing_model(); | |
| 774 rv = NPERR_NO_ERROR; | |
| 775 break; | |
| 776 } | |
| 777 #ifndef NP_NO_QUICKDRAW | |
| 778 case NPNVsupportsQuickDrawBool: { | |
| 779 // We do not admit to supporting the QuickDraw drawing model. The logic | |
| 780 // here is that our QuickDraw plugin support is so rudimentary that we | |
| 781 // only want to use it as a fallback to keep plugins from crashing: if a | |
| 782 // plugin knows enough to ask, we want them to use CoreGraphics. | |
| 783 NPBool* supports_qd = reinterpret_cast<NPBool*>(value); | |
| 784 *supports_qd = false; | |
| 785 rv = NPERR_NO_ERROR; | |
| 786 break; | |
| 787 } | |
| 788 #endif | |
| 789 case NPNVsupportsCoreGraphicsBool: | |
| 790 #ifndef NP_NO_CARBON | |
| 791 case NPNVsupportsCarbonBool: | |
| 792 #endif | |
| 793 case NPNVsupportsCocoaBool: { | |
| 794 // we do support these drawing and event models. | |
| 795 NPBool* supports_model = reinterpret_cast<NPBool*>(value); | |
| 796 *supports_model = true; | |
| 797 rv = NPERR_NO_ERROR; | |
| 798 break; | |
| 799 } | |
| 800 case NPNVsupportsCoreAnimationBool: { | |
| 801 // We only support the Core Animation model on 10.6 and higher | |
| 802 // TODO(stuartmorgan): Once existing CA plugins have implemented the | |
| 803 // invalidating version, remove support for this one. | |
| 804 NPBool* supports_model = reinterpret_cast<NPBool*>(value); | |
| 805 *supports_model = SupportsSharingAcceleratedSurfaces() ? true : false; | |
| 806 rv = NPERR_NO_ERROR; | |
| 807 break; | |
| 808 } | |
| 809 case NPNVsupportsInvalidatingCoreAnimationBool: { | |
| 810 NPBool* supports_model = reinterpret_cast<NPBool*>(value); | |
| 811 *supports_model = true; | |
| 812 rv = NPERR_NO_ERROR; | |
| 813 break; | |
| 814 } | |
| 815 case NPNVsupportsOpenGLBool: { | |
| 816 // This drawing model was never widely supported, and we don't plan to | |
| 817 // support it. | |
| 818 NPBool* supports_model = reinterpret_cast<NPBool*>(value); | |
| 819 *supports_model = false; | |
| 820 rv = NPERR_NO_ERROR; | |
| 821 break; | |
| 822 } | |
| 823 #endif // OS_MACOSX | |
| 824 case NPNVPepperExtensions: | |
| 825 // Available for any plugin that attempts to get it. | |
| 826 // If the plugin is not started in a Pepper implementation, it | |
| 827 // will likely fail when it tries to use any of the functions | |
| 828 // attached to the extension vector. | |
| 829 rv = NPAPI::GetPepperExtensionsFunctions(value); | |
| 830 break; | |
| 831 default: | |
| 832 DVLOG(1) << "NPN_GetValue(" << variable << ") is not implemented yet."; | |
| 833 break; | |
| 834 } | |
| 835 return rv; | |
| 836 } | |
| 837 | |
| 838 NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { | |
| 839 // Allows the plugin to set various modes | |
| 840 | |
| 841 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 842 switch(variable) { | |
| 843 case NPPVpluginWindowBool: { | |
| 844 // Sets windowless mode for display of the plugin | |
| 845 // Note: the documentation at | |
| 846 // http://developer.mozilla.org/en/docs/NPN_SetValue is wrong. When | |
| 847 // value is NULL, the mode is set to true. This is the same way Mozilla | |
| 848 // works. | |
| 849 plugin->set_windowless(value == 0); | |
| 850 return NPERR_NO_ERROR; | |
| 851 } | |
| 852 case NPPVpluginTransparentBool: { | |
| 853 // Sets transparent mode for display of the plugin | |
| 854 // | |
| 855 // Transparent plugins require the browser to paint the background | |
| 856 // before having the plugin paint. By default, windowless plugins | |
| 857 // are transparent. Making a windowless plugin opaque means that | |
| 858 // the plugin does not require the browser to paint the background. | |
| 859 bool mode = (value != 0); | |
| 860 plugin->set_transparent(mode); | |
| 861 return NPERR_NO_ERROR; | |
| 862 } | |
| 863 case NPPVjavascriptPushCallerBool: | |
| 864 // Specifies whether you are pushing or popping the JSContext off. | |
| 865 // the stack | |
| 866 // TODO: implement me | |
| 867 DVLOG(1) << "NPN_SetValue(NPPVJavascriptPushCallerBool) is not " | |
| 868 "implemented."; | |
| 869 return NPERR_GENERIC_ERROR; | |
| 870 case NPPVpluginKeepLibraryInMemory: | |
| 871 // Tells browser that plugin library should live longer than usual. | |
| 872 // TODO: implement me | |
| 873 DVLOG(1) << "NPN_SetValue(NPPVpluginKeepLibraryInMemory) is not " | |
| 874 "implemented."; | |
| 875 return NPERR_GENERIC_ERROR; | |
| 876 #if defined(OS_MACOSX) | |
| 877 case NPPVpluginDrawingModel: { | |
| 878 int model = reinterpret_cast<int>(value); | |
| 879 if (model == NPDrawingModelCoreGraphics || | |
| 880 model == NPDrawingModelInvalidatingCoreAnimation || | |
| 881 (model == NPDrawingModelCoreAnimation && | |
| 882 SupportsSharingAcceleratedSurfaces())) { | |
| 883 plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); | |
| 884 return NPERR_NO_ERROR; | |
| 885 } | |
| 886 return NPERR_GENERIC_ERROR; | |
| 887 } | |
| 888 case NPPVpluginEventModel: { | |
| 889 // we support Carbon and Cocoa event models | |
| 890 int model = reinterpret_cast<int>(value); | |
| 891 switch (model) { | |
| 892 #ifndef NP_NO_CARBON | |
| 893 case NPEventModelCarbon: | |
| 894 #endif | |
| 895 case NPEventModelCocoa: | |
| 896 plugin->set_event_model(static_cast<NPEventModel>(model)); | |
| 897 return NPERR_NO_ERROR; | |
| 898 break; | |
| 899 } | |
| 900 return NPERR_GENERIC_ERROR; | |
| 901 } | |
| 902 #endif | |
| 903 default: | |
| 904 // TODO: implement me | |
| 905 DVLOG(1) << "NPN_SetValue(" << variable << ") is not implemented."; | |
| 906 break; | |
| 907 } | |
| 908 | |
| 909 NOTREACHED(); | |
| 910 return NPERR_GENERIC_ERROR; | |
| 911 } | |
| 912 | |
| 913 void* NPN_GetJavaEnv() { | |
| 914 // TODO: implement me | |
| 915 DVLOG(1) << "NPN_GetJavaEnv is not implemented."; | |
| 916 return NULL; | |
| 917 } | |
| 918 | |
| 919 void* NPN_GetJavaPeer(NPP) { | |
| 920 // TODO: implement me | |
| 921 DVLOG(1) << "NPN_GetJavaPeer is not implemented."; | |
| 922 return NULL; | |
| 923 } | |
| 924 | |
| 925 void NPN_PushPopupsEnabledState(NPP id, NPBool enabled) { | |
| 926 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 927 if (plugin) | |
| 928 plugin->PushPopupsEnabledState(enabled ? true : false); | |
| 929 } | |
| 930 | |
| 931 void NPN_PopPopupsEnabledState(NPP id) { | |
| 932 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 933 if (plugin) | |
| 934 plugin->PopPopupsEnabledState(); | |
| 935 } | |
| 936 | |
| 937 void NPN_PluginThreadAsyncCall(NPP id, | |
| 938 void (*func)(void*), | |
| 939 void* user_data) { | |
| 940 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 941 if (plugin) | |
| 942 plugin->PluginThreadAsyncCall(func, user_data); | |
| 943 } | |
| 944 | |
| 945 NPError NPN_GetValueForURL(NPP id, | |
| 946 NPNURLVariable variable, | |
| 947 const char* url, | |
| 948 char** value, | |
| 949 uint32_t* len) { | |
| 950 if (!id) | |
| 951 return NPERR_INVALID_PARAM; | |
| 952 | |
| 953 if (!url || !*url || !len) | |
| 954 return NPERR_INVALID_URL; | |
| 955 | |
| 956 *len = 0; | |
| 957 std::string result; | |
| 958 | |
| 959 switch (variable) { | |
| 960 case NPNURLVProxy: { | |
| 961 result = "DIRECT"; | |
| 962 if (!webkit_glue::FindProxyForUrl(GURL((std::string(url))), &result)) | |
| 963 return NPERR_GENERIC_ERROR; | |
| 964 | |
| 965 break; | |
| 966 } | |
| 967 case NPNURLVCookie: { | |
| 968 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 969 if (!plugin) | |
| 970 return NPERR_GENERIC_ERROR; | |
| 971 | |
| 972 webkit_glue::WebPlugin* webplugin = plugin->webplugin(); | |
| 973 if (!webplugin) | |
| 974 return NPERR_GENERIC_ERROR; | |
| 975 | |
| 976 // Bypass third-party cookie blocking by using the url as the | |
| 977 // first_party_for_cookies. | |
| 978 GURL cookies_url((std::string(url))); | |
| 979 result = webplugin->GetCookies(cookies_url, cookies_url); | |
| 980 break; | |
| 981 } | |
| 982 default: | |
| 983 return NPERR_GENERIC_ERROR; | |
| 984 } | |
| 985 | |
| 986 // Allocate this using the NPAPI allocator. The plugin will call | |
| 987 // NPN_Free to free this. | |
| 988 *value = static_cast<char*>(NPN_MemAlloc(result.length() + 1)); | |
| 989 base::strlcpy(*value, result.c_str(), result.length() + 1); | |
| 990 *len = result.length(); | |
| 991 | |
| 992 return NPERR_NO_ERROR; | |
| 993 } | |
| 994 | |
| 995 NPError NPN_SetValueForURL(NPP id, | |
| 996 NPNURLVariable variable, | |
| 997 const char* url, | |
| 998 const char* value, | |
| 999 uint32_t len) { | |
| 1000 if (!id) | |
| 1001 return NPERR_INVALID_PARAM; | |
| 1002 | |
| 1003 if (!url || !*url) | |
| 1004 return NPERR_INVALID_URL; | |
| 1005 | |
| 1006 switch (variable) { | |
| 1007 case NPNURLVCookie: { | |
| 1008 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 1009 if (!plugin) | |
| 1010 return NPERR_GENERIC_ERROR; | |
| 1011 | |
| 1012 webkit_glue::WebPlugin* webplugin = plugin->webplugin(); | |
| 1013 if (!webplugin) | |
| 1014 return NPERR_GENERIC_ERROR; | |
| 1015 | |
| 1016 std::string cookie(value, len); | |
| 1017 GURL cookies_url((std::string(url))); | |
| 1018 webplugin->SetCookie(cookies_url, cookies_url, cookie); | |
| 1019 return NPERR_NO_ERROR; | |
| 1020 } | |
| 1021 case NPNURLVProxy: | |
| 1022 // We don't support setting proxy values, fall through... | |
| 1023 break; | |
| 1024 default: | |
| 1025 // Fall through and return an error... | |
| 1026 break; | |
| 1027 } | |
| 1028 | |
| 1029 return NPERR_GENERIC_ERROR; | |
| 1030 } | |
| 1031 | |
| 1032 NPError NPN_GetAuthenticationInfo(NPP id, | |
| 1033 const char* protocol, | |
| 1034 const char* host, | |
| 1035 int32_t port, | |
| 1036 const char* scheme, | |
| 1037 const char* realm, | |
| 1038 char** username, | |
| 1039 uint32_t* ulen, | |
| 1040 char** password, | |
| 1041 uint32_t* plen) { | |
| 1042 if (!id || !protocol || !host || !scheme || !realm || !username || | |
| 1043 !ulen || !password || !plen) | |
| 1044 return NPERR_INVALID_PARAM; | |
| 1045 | |
| 1046 // TODO: implement me (bug 23928) | |
| 1047 return NPERR_GENERIC_ERROR; | |
| 1048 } | |
| 1049 | |
| 1050 uint32_t NPN_ScheduleTimer(NPP id, | |
| 1051 uint32_t interval, | |
| 1052 NPBool repeat, | |
| 1053 void (*func)(NPP id, uint32_t timer_id)) { | |
| 1054 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 1055 if (!plugin) | |
| 1056 return 0; | |
| 1057 | |
| 1058 return plugin->ScheduleTimer(interval, repeat, func); | |
| 1059 } | |
| 1060 | |
| 1061 void NPN_UnscheduleTimer(NPP id, uint32_t timer_id) { | |
| 1062 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 1063 if (plugin) | |
| 1064 plugin->UnscheduleTimer(timer_id); | |
| 1065 } | |
| 1066 | |
| 1067 NPError NPN_PopUpContextMenu(NPP id, NPMenu* menu) { | |
| 1068 if (!menu) | |
| 1069 return NPERR_INVALID_PARAM; | |
| 1070 | |
| 1071 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 1072 if (plugin.get()) { | |
| 1073 return plugin->PopUpContextMenu(menu); | |
| 1074 } | |
| 1075 NOTREACHED(); | |
| 1076 return NPERR_GENERIC_ERROR; | |
| 1077 } | |
| 1078 | |
| 1079 NPBool NPN_ConvertPoint(NPP id, double sourceX, double sourceY, | |
| 1080 NPCoordinateSpace sourceSpace, | |
| 1081 double *destX, double *destY, | |
| 1082 NPCoordinateSpace destSpace) { | |
| 1083 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); | |
| 1084 if (plugin.get()) { | |
| 1085 return plugin->ConvertPoint(sourceX, sourceY, sourceSpace, | |
| 1086 destX, destY, destSpace); | |
| 1087 } | |
| 1088 NOTREACHED(); | |
| 1089 return false; | |
| 1090 } | |
| 1091 | |
| 1092 NPBool NPN_HandleEvent(NPP id, void *event, NPBool handled) { | |
| 1093 // TODO: Implement advanced key handling: http://crbug.com/46578 | |
| 1094 NOTIMPLEMENTED(); | |
| 1095 return false; | |
| 1096 } | |
| 1097 | |
| 1098 NPBool NPN_UnfocusInstance(NPP id, NPFocusDirection direction) { | |
| 1099 // TODO: Implement advanced key handling: http://crbug.com/46578 | |
| 1100 NOTIMPLEMENTED(); | |
| 1101 return false; | |
| 1102 } | |
| 1103 | |
| 1104 void NPN_URLRedirectResponse(NPP instance, void* notify_data, NPBool allow) { | |
| 1105 scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(instance)); | |
| 1106 if (plugin.get()) { | |
| 1107 plugin->URLRedirectResponse(!!allow, notify_data); | |
| 1108 } | |
| 1109 } | |
| 1110 | |
| 1111 } // extern "C" | |
| OLD | NEW |