Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2012 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 "base/synchronization/waitable_event.h"
      6 #include "ipc/ipc_message_utils.h"
      7 #include "ppapi/c/pp_var.h"
      8 #include "ppapi/c/ppb_core.h"
      9 #include "ppapi/c/ppb_fullscreen.h"
     10 #include "ppapi/c/ppb_url_loader.h"
     11 #include "ppapi/c/ppp_instance.h"
     12 #include "ppapi/c/private/ppb_flash_fullscreen.h"
     13 #include "ppapi/proxy/locking_resource_releaser.h"
     14 #include "ppapi/proxy/ppapi_messages.h"
     15 #include "ppapi/proxy/ppapi_proxy_test.h"
     16 #include "ppapi/shared_impl/ppb_view_shared.h"
     17 
     18 namespace ppapi {
     19 namespace proxy {
     20 
     21 namespace {
     22 // This is a poor man's mock of PPP_Instance using global variables.  Eventually
     23 // we should generalize making PPAPI interface mocks by using IDL or macro/
     24 // template magic.
     25 PP_Instance received_instance;
     26 uint32_t received_argc;
     27 std::vector<std::string> received_argn;
     28 std::vector<std::string> received_argv;
     29 PP_Bool bool_to_return;
     30 PP_Bool DidCreate(PP_Instance instance, uint32_t argc, const char* argn[],
     31                   const char* argv[]) {
     32   received_instance = instance;
     33   received_argc = argc;
     34   received_argn.clear();
     35   received_argn.insert(received_argn.begin(), argn, argn + argc);
     36   received_argv.clear();
     37   received_argv.insert(received_argv.begin(), argv, argv + argc);
     38   return bool_to_return;
     39 }
     40 
     41 void DidDestroy(PP_Instance instance) {
     42   received_instance = instance;
     43 }
     44 
     45 PP_Rect received_position;
     46 PP_Rect received_clip;
     47 // DidChangeView is asynchronous. We wait until the call has completed before
     48 // proceeding on to the next test.
     49 base::WaitableEvent did_change_view_called(false, false);
     50 void DidChangeView(PP_Instance instance, const PP_Rect* position,
     51                    const PP_Rect* clip) {
     52   received_instance = instance;
     53   received_position = *position;
     54   received_clip = *clip;
     55   did_change_view_called.Signal();
     56 }
     57 
     58 PP_Bool received_has_focus;
     59 base::WaitableEvent did_change_focus_called(false, false);
     60 void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
     61   received_instance = instance;
     62   received_has_focus = has_focus;
     63   did_change_focus_called.Signal();
     64 }
     65 
     66 PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) {
     67   // This one requires use of the PPB_URLLoader proxy and PPB_Core, plus a
     68   // resource tracker for the url_loader resource.
     69   // TODO(dmichael): Mock those out and test this function.
     70   NOTREACHED();
     71   return PP_FALSE;
     72 }
     73 
     74 // Clear all the 'received' values for our mock.  Call this before you expect
     75 // one of the functions to be invoked.  TODO(dmichael): It would be better to
     76 // have a flag also for each function, so we know the right one got called.
     77 void ResetReceived() {
     78   received_instance = 0;
     79   received_argc = 0;
     80   received_argn.clear();
     81   received_argv.clear();
     82   memset(&received_position, 0, sizeof(received_position));
     83   memset(&received_clip, 0, sizeof(received_clip));
     84   received_has_focus = PP_FALSE;
     85 }
     86 
     87 PPP_Instance_1_0 ppp_instance_1_0 = {
     88   &DidCreate,
     89   &DidDestroy,
     90   &DidChangeView,
     91   &DidChangeFocus,
     92   &HandleDocumentLoad
     93 };
     94 
     95 // PPP_Instance_Proxy::DidChangeView relies on PPB_(Flash)Fullscreen being
     96 // available with a valid implementation of IsFullScreen, so we mock it.
     97 PP_Bool IsFullscreen(PP_Instance instance) {
     98   return PP_FALSE;
     99 }
    100 PPB_Fullscreen ppb_fullscreen = { &IsFullscreen };
    101 PPB_FlashFullscreen ppb_flash_fullscreen = { &IsFullscreen };
    102 
    103 }  // namespace
    104 
    105 class PPP_Instance_ProxyTest : public TwoWayTest {
    106  public:
    107    PPP_Instance_ProxyTest()
    108        : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
    109    }
    110 };
    111 
    112 TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
    113   plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0, &ppp_instance_1_0);
    114   host().RegisterTestInterface(PPB_FLASHFULLSCREEN_INTERFACE,
    115                                &ppb_flash_fullscreen);
    116   host().RegisterTestInterface(PPB_FULLSCREEN_INTERFACE,
    117                                &ppb_fullscreen);
    118 
    119   // Grab the host-side proxy for the interface. The browser only speaks 1.1,
    120   // while the proxy ensures support for the 1.0 version on the plugin side.
    121   const PPP_Instance_1_1* ppp_instance = static_cast<const PPP_Instance_1_1*>(
    122       host().host_dispatcher()->GetProxiedInterface(
    123           PPP_INSTANCE_INTERFACE_1_1));
    124 
    125   // Call each function in turn, make sure we get the expected values and
    126   // returns.
    127   //
    128   // We don't test DidDestroy, because it has the side-effect of removing the
    129   // PP_Instance from the PluginDispatcher, which will cause a failure later
    130   // when the test is torn down.
    131   PP_Instance expected_instance = pp_instance();
    132   std::vector<std::string> expected_argn, expected_argv;
    133   expected_argn.push_back("Hello");
    134   expected_argn.push_back("world.");
    135   expected_argv.push_back("elloHay");
    136   expected_argv.push_back("orldway.");
    137   std::vector<const char*> argn_to_pass, argv_to_pass;
    138   CHECK(expected_argn.size() == expected_argv.size());
    139   for (size_t i = 0; i < expected_argn.size(); ++i) {
    140     argn_to_pass.push_back(expected_argn[i].c_str());
    141     argv_to_pass.push_back(expected_argv[i].c_str());
    142   }
    143   uint32_t expected_argc = expected_argn.size();
    144   bool_to_return = PP_TRUE;
    145   ResetReceived();
    146   // Tell the host resource tracker about the instance.
    147   host().resource_tracker().DidCreateInstance(expected_instance);
    148   EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance,
    149                                                     expected_argc,
    150                                                     &argn_to_pass[0],
    151                                                     &argv_to_pass[0]));
    152   EXPECT_EQ(received_instance, expected_instance);
    153   EXPECT_EQ(received_argc, expected_argc);
    154   EXPECT_EQ(received_argn, expected_argn);
    155   EXPECT_EQ(received_argv, expected_argv);
    156 
    157   PP_Rect expected_position = { {1, 2}, {3, 4} };
    158   PP_Rect expected_clip = { {5, 6}, {7, 8} };
    159   ViewData data;
    160   data.rect = expected_position;
    161   data.is_fullscreen = false;
    162   data.is_page_visible = true;
    163   data.clip_rect = expected_clip;
    164   data.device_scale = 1.0f;
    165   ResetReceived();
    166   LockingResourceReleaser view_resource(
    167       (new PPB_View_Shared(OBJECT_IS_IMPL,
    168                            expected_instance, data))->GetReference());
    169   ppp_instance->DidChangeView(expected_instance, view_resource.get());
    170   did_change_view_called.Wait();
    171   EXPECT_EQ(received_instance, expected_instance);
    172   EXPECT_EQ(received_position.point.x, expected_position.point.x);
    173   EXPECT_EQ(received_position.point.y, expected_position.point.y);
    174   EXPECT_EQ(received_position.size.width, expected_position.size.width);
    175   EXPECT_EQ(received_position.size.height, expected_position.size.height);
    176   EXPECT_EQ(received_clip.point.x, expected_clip.point.x);
    177   EXPECT_EQ(received_clip.point.y, expected_clip.point.y);
    178   EXPECT_EQ(received_clip.size.width, expected_clip.size.width);
    179   EXPECT_EQ(received_clip.size.height, expected_clip.size.height);
    180 
    181   PP_Bool expected_has_focus = PP_TRUE;
    182   ResetReceived();
    183   ppp_instance->DidChangeFocus(expected_instance, expected_has_focus);
    184   did_change_focus_called.Wait();
    185   EXPECT_EQ(received_instance, expected_instance);
    186   EXPECT_EQ(received_has_focus, expected_has_focus);
    187 
    188   //  TODO(dmichael): Need to mock out a resource Tracker to be able to test
    189   //                  HandleResourceLoad. It also requires
    190   //                  PPB_Core.AddRefResource and for PPB_URLLoader to be
    191   //                  registered.
    192 
    193   host().resource_tracker().DidDeleteInstance(expected_instance);
    194 }
    195 
    196 }  // namespace proxy
    197 }  // namespace ppapi
    198