blob: 13ccdcd155536fd857f9a15228ee0406d4e248d2 [file] [log] [blame]
// 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<void*>(SELF_URL_STREAM_ID));
test_started_ = true;
#if defined(OS_WIN)
HWND window_handle = reinterpret_cast<HWND>(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<ExecuteGetJavascriptUrlTest*>
(::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<unsigned int>(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<unsigned long>(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<unsigned long>(stream->notifyData);
switch (stream_id) {
case SELF_URL_STREAM_ID:
self_url_.append(static_cast<char*>(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<unsigned long>(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<unsigned long>(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