15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/test/plugin/plugin_test.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/test/plugin/npapi_constants.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace NPAPIClient { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginTest::PluginTest(NPP id, NPNetscapeFuncs *host_functions) { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_ = id; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_->pdata = this; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_functions_ = host_functions; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_completed_ = false; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PluginTest::~PluginTest() {} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PluginTest::IsWindowless() const { return false; } 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginTest::New(uint16 mode, int16 argc, const char* argn[], 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* argv[], NPSavedData* saved) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_name_ = this->GetArgValue("name", argc, argn, argv); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* id = this->GetArgValue("id", argc, argn, argv); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id) // NULL for NP_FULL 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_id_ = id; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginTest::Destroy() { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginTest::SetWindow(NPWindow* pNPWindow) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It's a shame I have to implement URLEncode. But, using webkit's 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or using chrome's means a ball of string of dlls and dependencies that 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is very very long. After spending far too much time on it, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// I'll just encode it myself. Too bad Microsoft doesn't implement 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this in a reusable way either. Both webkit and chrome will 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// end up using libicu, which is a string of dependencies we don't 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// want. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline unsigned char toHex(const unsigned char x) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x > 9 ? (x + 'A' - 10) : (x + '0'); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string URLEncode(const std::string &sIn) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string sOut; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t length = sIn.length(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t idx = 0; idx < length;) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char ch = sIn.at(idx); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isalnum(ch)) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sOut.append(1, ch); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (isspace(ch) && ((ch != '\n') && (ch != '\r'))) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sOut.append(1, '+'); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sOut.append(1, '%'); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sOut.append(1, toHex(ch>>4)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sOut.append(1, toHex(ch%16)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx++; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sOut; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::SignalTestCompleted() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPObject *window_obj = NULL; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_functions_->getvalue(id_, NPNVWindowNPObject, &window_obj); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window_obj) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_completed_ = true; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To signal test completion, we expect a couple of 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // javascript functions to be defined in the webpage 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which hosts this plugin: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // onSuccess(test_name, test_id) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // onFailure(test_name, test_id, error_message) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string script("javascript:"); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Succeeded()) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("onSuccess(\""); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append(test_name_); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("\",\""); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append(test_id_); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("\");"); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("onFailure(\""); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append(test_name_); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("\",\""); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append(test_id_); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("\",\""); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append(test_status_); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script.append("\");"); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPString script_string; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_string.UTF8Characters = script.c_str(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_string.UTF8Length = static_cast<unsigned int>(script.length()); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPVariant result_var; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_functions_->evaluate(id_, window_obj, &script_string, &result_var); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *PluginTest::GetArgValue(const char *name, const int16 argc, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *argn[], const char *argv[]) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int idx = 0; idx < argc; idx++) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::strcasecmp(argn[idx], name) == 0) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return argv[idx]; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::SetError(const std::string &msg) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_status_.append(msg); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::ExpectStringLowerCaseEqual(const std::string &val1, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string &val2) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LowerCaseEqualsASCII(val1, val2.c_str())) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string err; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = "Expected Equal for '"; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(val1); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("' and '"); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(val2); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("'"); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(err); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::ExpectAsciiStringNotEqual(const char *val1, const char *val2) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (val1 == val2) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string err; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = "Expected Not Equal for '"; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(val1); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("' and '"); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(val2); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("'"); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(err); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::ExpectIntegerEqual(int val1, int val2) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (val1 != val2) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string err; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err = "Expected Equal for '"; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(base::IntToString(val1)); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("' and '"); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append(base::IntToString(val2)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) err.append("'"); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetError(err); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginTest::NewStream(NPMIMEType type, NPStream* stream, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPBool seekable, uint16* stype) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action here. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 PluginTest::WriteReady(NPStream *stream) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Take data in small chunks 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4096; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 PluginTest::Write(NPStream *stream, int32 offset, int32 len, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *buffer) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pretend that we took all the data. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NPError PluginTest::DestroyStream(NPStream *stream, NPError reason) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NPERR_NO_ERROR; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::StreamAsFile(NPStream* stream, const char* fname) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::URLNotify(const char* url, NPReason reason, void* data) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int16 PluginTest::HandleEvent(void* event) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PluginTest::URLRedirectNotify(const char* url, int32_t status, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* notify_data) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no default action 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace NPAPIClient 200