Home | History | Annotate | Download | only in plugin
      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 "content/test/plugin/plugin_windowed_test.h"
      6 
      7 #include "base/logging.h"
      8 #include "content/test/plugin/plugin_client.h"
      9 
     10 namespace NPAPIClient {
     11 
     12 WindowedPluginTest::WindowedPluginTest(NPP id, NPNetscapeFuncs *host_functions)
     13     : PluginTest(id, host_functions),
     14       window_(NULL), done_(false) {
     15 }
     16 
     17 WindowedPluginTest::~WindowedPluginTest() {
     18   if (window_)
     19     DestroyWindow(window_);
     20 }
     21 
     22 NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) {
     23   if (pNPWindow->window == NULL)
     24     return NPERR_NO_ERROR;
     25 
     26   if (test_name() == "create_instance_in_paint" && test_id() == "2") {
     27     SignalTestCompleted();
     28     return NPERR_NO_ERROR;
     29   }
     30 
     31   if (window_)
     32     return NPERR_NO_ERROR;
     33 
     34   HWND parent = reinterpret_cast<HWND>(pNPWindow->window);
     35   if (!::IsWindow(parent)) {
     36     SetError("Invalid arguments passed in");
     37     return NPERR_INVALID_PARAM;
     38   }
     39 
     40   if ((test_name() == "create_instance_in_paint" && test_id() == "1") ||
     41       test_name() == "alert_in_window_message" ||
     42       test_name() == "set_title_in_paint" ||
     43       test_name() == "set_title_in_set_window_and_paint") {
     44     static ATOM window_class = 0;
     45     if (!window_class) {
     46       WNDCLASSEX wcex;
     47       wcex.cbSize         = sizeof(WNDCLASSEX);
     48       wcex.style          = CS_DBLCLKS;
     49       wcex.lpfnWndProc    = &NPAPIClient::WindowedPluginTest::WindowProc;
     50       wcex.cbClsExtra     = 0;
     51       wcex.cbWndExtra     = 0;
     52       wcex.hInstance      = GetModuleHandle(NULL);
     53       wcex.hIcon          = 0;
     54       wcex.hCursor        = 0;
     55       wcex.hbrBackground  = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
     56       wcex.lpszMenuName   = 0;
     57       wcex.lpszClassName  = L"CreateInstanceInPaintTestWindowClass";
     58       wcex.hIconSm        = 0;
     59       window_class = RegisterClassEx(&wcex);
     60     }
     61 
     62     window_ = CreateWindowEx(
     63         WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
     64         MAKEINTATOM(window_class), 0,
     65         WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE ,
     66         0, 0, 100, 100, parent, 0, GetModuleHandle(NULL), 0);
     67     DCHECK(window_);
     68     // TODO: this propery leaks.
     69     ::SetProp(window_, L"Plugin_Instance", this);
     70   }
     71 
     72   if (test_name() == "set_title_in_set_window_and_paint")
     73     CallJSFunction(this, "PluginCreated");
     74 
     75   return NPERR_NO_ERROR;
     76 }
     77 
     78 NPError WindowedPluginTest::Destroy() {
     79   if (test_name() != "ensure_scripting_works_in_destroy")
     80     return NPERR_NO_ERROR;
     81 
     82   // Bug 23706: ensure that scripting works with no asserts.
     83   NPObject *window_obj = NULL;
     84   HostFunctions()->getvalue(id(), NPNVWindowNPObject,&window_obj);
     85 
     86   if (!window_obj) {
     87     SetError("Failed to get NPObject for plugin instance");
     88   } else {
     89     std::string script = "javascript:GetMagicNumber()";
     90     NPString script_string;
     91     script_string.UTF8Characters = script.c_str();
     92     script_string.UTF8Length =
     93         static_cast<unsigned int>(script.length());
     94 
     95     NPVariant result_var;
     96     bool result = HostFunctions()->evaluate(
     97         id(), window_obj, &script_string, &result_var);
     98     if (!result ||
     99         result_var.type != NPVariantType_Double ||
    100         result_var.value.doubleValue != 42.0) {
    101       SetError("Failed to script during NPP_Destroy");
    102     }
    103   }
    104 
    105   SignalTestCompleted();
    106   return NPERR_NO_ERROR;
    107 }
    108 
    109 void WindowedPluginTest::CallJSFunction(
    110     WindowedPluginTest* this_ptr, const char* function) {
    111   NPIdentifier function_id = this_ptr->HostFunctions()->getstringidentifier(
    112       function);
    113 
    114   NPObject *window_obj = NULL;
    115   this_ptr->HostFunctions()->getvalue(
    116       this_ptr->id(), NPNVWindowNPObject, &window_obj);
    117 
    118   NPVariant rv;
    119   this_ptr->HostFunctions()->invoke(
    120       this_ptr->id(), window_obj, function_id, NULL, 0, &rv);
    121 }
    122 
    123 LRESULT CALLBACK WindowedPluginTest::WindowProc(
    124     HWND window, UINT message, WPARAM wparam, LPARAM lparam) {
    125   WindowedPluginTest* this_ptr =
    126       reinterpret_cast<WindowedPluginTest*>
    127           (::GetProp(window, L"Plugin_Instance"));
    128 
    129   if (message == WM_PAINT) {
    130     PAINTSTRUCT ps;
    131     HDC hdc = BeginPaint(window, &ps);
    132     HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
    133     HGDIOBJ orig = SelectObject(hdc, brush);
    134     RECT r;
    135     GetClientRect(window, &r);
    136     Rectangle(hdc, 0, 0, r.right, r.bottom);
    137     SelectObject(hdc, orig); // restore
    138     DeleteObject(brush);
    139     EndPaint(window, &ps);
    140   }
    141 
    142   if (this_ptr && !this_ptr->done_) {
    143     if (this_ptr->test_name() == "create_instance_in_paint" &&
    144         message == WM_PAINT) {
    145       this_ptr->done_ = true;
    146       CallJSFunction(this_ptr, "CreateNewInstance");
    147     } else if (this_ptr->test_name() == "alert_in_window_message" &&
    148                message == WM_PAINT) {
    149       this_ptr->done_ = true;
    150       // We call this function twice as we want to display two alerts
    151       // and verify that we don't hang the browser.
    152       CallJSFunction(this_ptr, "CallAlert");
    153       CallJSFunction(this_ptr, "CallAlert");
    154     } else if (this_ptr->test_name() == "set_title_in_paint" &&
    155                message == WM_PAINT) {
    156       this_ptr->done_ = true;
    157       CallJSFunction(this_ptr, "SetTitle");
    158     } else if (this_ptr->test_name() == "set_title_in_set_window_and_paint" &&
    159                message == WM_PAINT) {
    160       this_ptr->done_ = true;
    161       CallJSFunction(this_ptr, "PluginShown");
    162     }
    163 
    164     if (this_ptr->done_) {
    165       ::RemoveProp(window, L"Plugin_Instance");
    166     }
    167   }
    168 
    169   return DefWindowProc(window, message, wparam, lparam);
    170 }
    171 
    172 } // namespace NPAPIClient
    173