// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/test/plugin/plugin_get_javascript_url_test.h" #include "base/basictypes.h" #include "base/logging.h" // url for "self". #define SELF_URL "javascript:window.location+\"\"" // The identifier for the self url stream. #define SELF_URL_STREAM_ID 1 // The maximum chunk size of stream data. #define STREAM_CHUNK 197 #if defined(OS_WIN) const int kNPNEvaluateTimerID = 100; const int kNPNEvaluateTimerElapse = 50; #endif namespace NPAPIClient { ExecuteGetJavascriptUrlTest::ExecuteGetJavascriptUrlTest( NPP id, NPNetscapeFuncs *host_functions) : PluginTest(id, host_functions), test_started_(false), #if defined(OS_WIN) window_(NULL), #endif npn_evaluate_context_(false) { } NPError ExecuteGetJavascriptUrlTest::SetWindow(NPWindow* pNPWindow) { #if !defined(OS_MACOSX) if (pNPWindow->window == NULL) return NPERR_NO_ERROR; #endif if (!test_started_) { std::string url = SELF_URL; HostFunctions()->geturlnotify(id(), url.c_str(), "_top", reinterpret_cast(SELF_URL_STREAM_ID)); test_started_ = true; #if defined(OS_WIN) HWND window_handle = reinterpret_cast(pNPWindow->window); if (!::GetProp(window_handle, L"Plugin_Instance")) { // TODO: this propery leaks. ::SetProp(window_handle, L"Plugin_Instance", this); // We attempt to retreive the NPObject for the plugin instance identified // by the NPObjectLifetimeTestInstance2 class as it may not have been // instantiated yet. SetTimer(window_handle, kNPNEvaluateTimerID, kNPNEvaluateTimerElapse, TimerProc); } window_ = window_handle; #endif } return NPERR_NO_ERROR; } #if defined(OS_WIN) void CALLBACK ExecuteGetJavascriptUrlTest::TimerProc( HWND window, UINT message, UINT_PTR timer_id, DWORD elapsed_time) { ExecuteGetJavascriptUrlTest* this_instance = reinterpret_cast (::GetProp(window, L"Plugin_Instance")); CHECK(this_instance); ::RemoveProp(window, L"Plugin_Instance"); NPObject *window_obj = NULL; this_instance->HostFunctions()->getvalue(this_instance->id(), NPNVWindowNPObject, &window_obj); if (!window_obj) { this_instance->SetError("Failed to get NPObject for plugin instance2"); this_instance->SignalTestCompleted(); return; } std::string script = "javascript:window.location"; NPString script_string; script_string.UTF8Characters = script.c_str(); script_string.UTF8Length = static_cast(script.length()); NPVariant result_var; this_instance->npn_evaluate_context_ = true; this_instance->HostFunctions()->evaluate( this_instance->id(), window_obj, &script_string, &result_var); this_instance->npn_evaluate_context_ = false; } #endif NPError ExecuteGetJavascriptUrlTest::NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype) { if (stream == NULL) { SetError("NewStream got null stream"); return NPERR_INVALID_PARAM; } if (npn_evaluate_context_) { SetError("NewStream received in context of NPN_Evaluate"); return NPERR_NO_ERROR; } static_assert(sizeof(unsigned long) <= sizeof(stream->notifyData), "cast validity check"); unsigned long stream_id = reinterpret_cast(stream->notifyData); switch (stream_id) { case SELF_URL_STREAM_ID: break; default: SetError("Unexpected NewStream callback"); break; } return NPERR_NO_ERROR; } int32 ExecuteGetJavascriptUrlTest::WriteReady(NPStream *stream) { if (npn_evaluate_context_) { SetError("WriteReady received in context of NPN_Evaluate"); return NPERR_NO_ERROR; } return STREAM_CHUNK; } int32 ExecuteGetJavascriptUrlTest::Write(NPStream *stream, int32 offset, int32 len, void *buffer) { if (stream == NULL) { SetError("Write got null stream"); return -1; } if (len < 0 || len > STREAM_CHUNK) { SetError("Write got bogus stream chunk size"); return -1; } if (npn_evaluate_context_) { SetError("Write received in context of NPN_Evaluate"); return len; } static_assert(sizeof(unsigned long) <= sizeof(stream->notifyData), "cast validity check"); unsigned long stream_id = reinterpret_cast(stream->notifyData); switch (stream_id) { case SELF_URL_STREAM_ID: self_url_.append(static_cast(buffer), len); break; default: SetError("Unexpected write callback"); break; } // Pretend that we took all the data. return len; } NPError ExecuteGetJavascriptUrlTest::DestroyStream(NPStream *stream, NPError reason) { if (stream == NULL) { SetError("NewStream got null stream"); return NPERR_INVALID_PARAM; } #if defined(OS_WIN) KillTimer(window_, kNPNEvaluateTimerID); #endif if (npn_evaluate_context_) { SetError("DestroyStream received in context of NPN_Evaluate"); return NPERR_NO_ERROR; } static_assert(sizeof(unsigned long) <= sizeof(stream->notifyData), "cast validity check"); unsigned long stream_id = reinterpret_cast(stream->notifyData); switch (stream_id) { case SELF_URL_STREAM_ID: // don't care break; default: SetError("Unexpected NewStream callback"); break; } return NPERR_NO_ERROR; } void ExecuteGetJavascriptUrlTest::URLNotify(const char* url, NPReason reason, void* data) { static_assert(sizeof(unsigned long) <= sizeof(data), "cast validity check"); if (npn_evaluate_context_) { SetError("URLNotify received in context of NPN_Evaluate"); return; } unsigned long stream_id = reinterpret_cast(data); switch (stream_id) { case SELF_URL_STREAM_ID: if (strcmp(url, SELF_URL) != 0) SetError("URLNotify reported incorrect url for SELF_URL"); if (self_url_.empty()) SetError("Failed to obtain window location."); SignalTestCompleted(); break; default: SetError("Unexpected NewStream callback"); break; } } } // namespace NPAPIClient