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.
6 #include "base/message_loop.h"
7 #include "base/test/test_timeouts.h"
9 #include "ppapi/c/dev/ppb_var_deprecated.h"
10 #include "ppapi/c/dev/ppp_class_deprecated.h"
11 #include "ppapi/c/pp_var.h"
12 #include "ppapi/c/ppb_var.h"
13 #include "ppapi/c/ppp_instance.h"
14 #include "ppapi/c/private/ppp_instance_private.h"
15 #include "ppapi/proxy/host_dispatcher.h"
16 #include "ppapi/proxy/interface_list.h"
17 #include "ppapi/proxy/ppapi_proxy_test.h"
18 #include "ppapi/shared_impl/ppapi_permissions.h"
19 #include "ppapi/shared_impl/ppb_var_shared.h"
20 #include "ppapi/shared_impl/var.h"
24 // A fake version of NPObjectVar for testing.
25 class NPObjectVar
: public ppapi::Var
{
28 virtual ~NPObjectVar() {}
31 virtual NPObjectVar
* AsNPObjectVar() OVERRIDE
{ return this; }
32 virtual PP_VarType
GetType() const OVERRIDE
{ return PP_VARTYPE_OBJECT
; }
38 const PP_Instance kInstance
= 0xdeadbeef;
40 PP_Var
GetPPVarNoAddRef(Var
* var
) {
41 PP_Var var_to_return
= var
->GetPPVar();
42 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var_to_return
);
46 PluginDispatcher
* plugin_dispatcher
= NULL
;
47 // Return the plugin-side proxy for PPB_Var_Deprecated.
48 const PPB_Var_Deprecated
* plugin_var_deprecated_if() {
49 // The test code must set the plugin dispatcher.
50 CHECK(plugin_dispatcher
);
51 // Grab the plugin-side proxy for PPB_Var_Deprecated (for CreateObject).
52 return static_cast<const PPB_Var_Deprecated
*>(
53 plugin_dispatcher
->GetBrowserInterface(
54 PPB_VAR_DEPRECATED_INTERFACE
));
57 // Mock PPP_Instance_Private.
59 PP_Var
GetInstanceObject(PP_Instance
/*instance*/) {
60 // The 1 ref we got from CreateObject will be passed to the host. We want to
61 // have a ref of our own.
62 printf("GetInstanceObject called\n");
63 plugin_var_deprecated_if()->AddRef(instance_obj
);
67 PPP_Instance_Private ppp_instance_private_mock
= {
71 // We need to pass in a |PPP_Class_Deprecated| to
72 // |PPB_Var_Deprecated->CreateObject| for a mock |Deallocate| method.
73 void Deallocate(void* object
) {
76 const PPP_Class_Deprecated ppp_class_deprecated_mock
= {
80 NULL
, // GetAllPropertyNames
82 NULL
, // RemoveProperty
89 // We need to mock PPP_Instance, so that we can create and destroy the pretend
90 // instance that PPP_Instance_Private uses.
91 PP_Bool
DidCreate(PP_Instance
/*instance*/, uint32_t /*argc*/,
92 const char* /*argn*/[], const char* /*argv*/[]) {
93 // Create an object var. This should exercise the typical path for creating
96 plugin_var_deprecated_if()->CreateObject(kInstance
,
97 &ppp_class_deprecated_mock
,
102 void DidDestroy(PP_Instance
/*instance*/) {
103 // Decrement the reference count for our instance object. It should be
105 plugin_var_deprecated_if()->Release(instance_obj
);
108 PPP_Instance_1_0 ppp_instance_mock
= { &DidCreate
, &DidDestroy
};
110 // Mock PPB_Var_Deprecated, so that we can emulate creating an Object Var.
111 PP_Var
CreateObject(PP_Instance
/*instance*/,
112 const PPP_Class_Deprecated
* /*ppp_class*/,
113 void* /*ppp_class_data*/) {
114 NPObjectVar
* obj_var
= new NPObjectVar
;
115 return obj_var
->GetPPVar();
118 const PPB_Var_Deprecated ppb_var_deprecated_mock
= {
119 PPB_Var_Shared::GetVarInterface1_0()->AddRef
,
120 PPB_Var_Shared::GetVarInterface1_0()->Release
,
121 PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8
,
122 PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8
,
126 NULL
, // EnumerateProperties
128 NULL
, // RemoveProperty
131 NULL
, // IsInstanceOf
135 class PPP_Instance_Private_ProxyTest
: public TwoWayTest
{
137 PPP_Instance_Private_ProxyTest()
138 : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE
) {
139 plugin().RegisterTestInterface(PPP_INSTANCE_PRIVATE_INTERFACE
,
140 &ppp_instance_private_mock
);
141 plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0
,
143 host().RegisterTestInterface(PPB_VAR_DEPRECATED_INTERFACE
,
144 &ppb_var_deprecated_mock
);
150 // TODO(raymes): This #ifdef is only here because we check the state of the
151 // plugin globals on the main thread, rather than the plugin thread which causes
152 // the thread checker to fail. Once ENABLE_PEPPER_THREADING is the default,
153 // this will be safe to do anyway, so we can remove this.
154 #ifdef ENABLE_PEPPER_THREADING
155 TEST_F(PPP_Instance_Private_ProxyTest
, PPPInstancePrivate
) {
157 TEST_F(PPP_Instance_Private_ProxyTest
, DISABLED_PPPInstancePrivate
) {
159 // This test controls its own instance; we can't use the one that
160 // PluginProxyTestHarness provides.
161 ASSERT_NE(kInstance
, pp_instance());
162 HostDispatcher::SetForInstance(kInstance
, host().host_dispatcher());
164 // Requires dev interfaces.
165 InterfaceList::SetProcessGlobalPermissions(
166 PpapiPermissions::AllPermissions());
168 // This file-local global is used by the PPP_Instance mock above in order to
169 // access PPB_Var_Deprecated.
170 plugin_dispatcher
= plugin().plugin_dispatcher();
172 // Grab the host-side proxy for PPP_Instance and PPP_Instance_Private.
173 const PPP_Instance_Private
* ppp_instance_private
=
174 static_cast<const PPP_Instance_Private
*>(
175 host().host_dispatcher()->GetProxiedInterface(
176 PPP_INSTANCE_PRIVATE_INTERFACE
));
177 const PPP_Instance_1_1
* ppp_instance
= static_cast<const PPP_Instance_1_1
*>(
178 host().host_dispatcher()->GetProxiedInterface(
179 PPP_INSTANCE_INTERFACE_1_1
));
181 // Initialize an Instance, so that the plugin-side machinery will work
183 EXPECT_EQ(PP_TRUE
, ppp_instance
->DidCreate(kInstance
, 0, NULL
, NULL
));
185 // Check the plugin-side reference count.
186 EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj
));
187 // Check the host-side var exists with the expected id and has 1 refcount (the
188 // refcount on behalf of the plugin).
189 int32 expected_host_id
=
190 plugin().var_tracker().GetHostObject(instance_obj
).value
.as_id
;
191 Var
* host_var
= host().var_tracker().GetVar(expected_host_id
);
192 ASSERT_TRUE(host_var
);
195 host().var_tracker().GetRefCountForObject(GetPPVarNoAddRef(host_var
)));
197 // Call from the browser side to get the instance object.
198 PP_Var host_pp_var
= ppp_instance_private
->GetInstanceObject(kInstance
);
199 EXPECT_EQ(instance_obj
.type
, host_pp_var
.type
);
200 EXPECT_EQ(host_pp_var
.value
.as_id
, expected_host_id
);
201 EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj
));
202 // A reference is passed to the browser, which we consume here.
203 host().var_tracker().ReleaseVar(host_pp_var
);
204 EXPECT_EQ(1, host().var_tracker().GetRefCountForObject(host_pp_var
));
206 // The plugin is going away; generally, so will all references to its instance
208 host().var_tracker().ReleaseVar(host_pp_var
);
209 // Destroy the instance. DidDestroy above decrements the reference count for
210 // instance_obj, so it should also be destroyed.
211 ppp_instance
->DidDestroy(kInstance
);
212 EXPECT_EQ(-1, plugin().var_tracker().GetRefCountForObject(instance_obj
));
213 EXPECT_EQ(-1, host().var_tracker().GetRefCountForObject(host_pp_var
));